git revert 做了什么? 为什么在 git revert 的未来,可能还需要 revert the revert?
本文通过一个小实验来回答以上的问题。
Step 1. 假定我们有一个新建的repo,其上有一个master分支,在初始状态下,一切都是空的。
Step 2. 我们给 master 分支上添加了一个 README 文件,这就是 v1 版本了。
Step 3. 我们根据 master 分支创建了一个 dev 分支,于是,dev 分支上现在也能看到 README 文件了。
Step 4. 我们回到 master 分支,在其上创建一个 v2.txt 文件, 并且commit和push,这就是 v2 commit。
接着我们又创建了 v3.txt 文件,并且commit和push,这就是 v3 commit。
现在,master分支上可以看见:
README
v2.txt
v3.txt
Step 5. 现在我们来到 dev 分支,在其上创建 v4.txt,并且commit和push,这就是 v4 commit。
接着,创建 v5.txt, 并且commit和push,这就是 v5 commit。
现在 dev 分支上可以看见:
README
v4.txt
v5.txt
Step 6. 仍然站在 dev 分支上,运行 git fetch和 git merge master
于是 dev 分支上就出现了 v6 commit。在dev上可以看到所有的文件了:
README
v2.txt
v3.txt
v4.txt
v5.txt
到目前,整个git history是这个样子:
master: v1 - v2 - v3
\ \
dev: - v4 - v5 - v6
1
2
3
本步骤中的 merge 动作会生成一个 v6 commit.
Step 7. 我们发现,dev上不想要这次的merge了,于是应该做revert动作了。运行的命令如下:
git revert -m 1 <v6-commit-id>
1
解释一下:
首先,我们最好使用 git log --graph来查看目前的分支合并情况。
然后,在revert命令中,“-m 1” 指的是当把 v6 commit 给 revert 之后保留第1条分支。对于dev分支来说,第一条分支就是它自己原来的历史了。而这些也是可以通过 git log --graph看出来的。
当执行完以上的命令后,产生了什么效果呢?
dev分支上,v2 commit 和 v3 commit 并没有从 git history 中消失
dev分支上,多了一条 v7 commit ,它代表将 v6 commit 给反操作了,即revert了
于是,此时在dev分支上,我们只可以看到:
README
v4.txt
v5.txt
此时的分支历史如下:
master: v1 - v2 - v3
\ \
dev: - v4 - v5 - v6 (merge v2,v3) - v7 (revert v6)
1
2
3
Step 8. 现在 master 上的开发又继续了,添加了一个 v8.txt, 并且commit和push了,这就是 v8 commit
Step 9. 我们现在发现 v8 是个好东西,它可以修复之前 v2,v3 上的问题,于是我们希望 merge v8
于是我们在 dev 分支上运行 git fetch和 git merge master, 从而得到了 v9 commit
历史图如下:
master: v1 - v2 - v3 - v8 -------------------------------
\ \ \
dev: - v4 - v5 - v6 (merge v2,v3) - v7 (revert v6) - v9 (merge v8)
1
2
3
猜猜我们现在能看到哪些文件了? 能看到所有的文件了吗? 我们可是 merge 了 master 分支啊。
答案是: 我们可以看到 v8.txt 了,但我们依然看不见 v2.txt 和 v3.txt
这是因为 git 在 merge master 的时候,发现 v2 和 v3 commit 都已经存在于历史中了,于是不再merge相关改动。
但在实际情况中, v2.txt 和 v3.txt 中有bug,而 v8.txt 可以修复它们。但如果仅仅只有 v8.txt , 不能发挥任何作用。这时候应该怎么让 v2.txt 和 v3.txt 再次出现呢?
对了,这时候就需要 revert the revert 了。
Step 10. 在dev分支上,运行 git revert -m 1 <v7-commit-id>
这个命令将 v7 的操作反操作了,v7是”revert v6", 则 “revert v7” 就是又做了一遍 v6 的操作。于是我们可以继续看到 v2.txt 和 v3.txt 了。
最终的历史图如下:
master: v1 - v2 - v3 - v8 -------------------------------
\ \ \
dev: - v4 - v5 - v6 (merge v2,v3) - v7 (revert v6) - v9 (merge v8) - v10 (revert v7)
1
2
3
综上所述,git revert 的操作还是要谨慎,它会使得 git log 所显示的 commit 有一定的迷惑性(即看上去存在的commit但其实已经被revert了),并且可能会引起在将来的 revert the revert.
————————————————
版权声明:本文为CSDN博主「执假以为真」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/nirendao/article/details/125668283