相对于常规的 commit,当使用 git merge 合并两个分支的时候,你会得到一个新的 merge commit。
当我们 git show 的时候会出现类似信息:
1commit 6dd0e2b9398ca8cd12bfd1faa1531d86dc41021a
Merge: d24d3b4 11a7112 这行表明了两个分支在合并时,所处的 parent 的版本线索。
比如在上述项目中我们开出了一个 dev 分支并做了一些操作,现在分支的样子变成了这样:
1init -> v1 -> v2 -> v3 (master)
当我们在 dev 开发的差不多了:
1
这个时候形成了一个 Merge Commit faulty merge:
1init -> v1 -> v2 -> v3 -- faulty merge (master)
此时 faulty merge 有两个 parent 分别是 v3 和 d2。
回滚错误的合并这个 merge 之后还继续在 dev 开发,另一波人也在从别的分支往 master 合并代码。变成这样:
1init -> v1 -> v2 -> v3 -- faulty merge -> v4 -> vc3 (master)
这个时候你发现, 妹的,上次那个 merge 好像给共享分支 master 引入了一个 bug。这个 bug 导致团队其他同学跑不通测试,或者这是一个线上的 bug,如果不及时修复老板要骂街了。
这个时候第一想到的肯定是回滚代码,但怎么回滚呢。用 reset?不现实,因为太流氓不说,还会把别人的代码也干掉,所以只能用 revert。而 revert 它最初被设计出来就是干这个活的。
怎么操作呢?首先想到的是上面所说的 git revert ,但是貌似不太行。
1git revert faulty merge
这是因为试图撤销两个分支的合并的时候 Git 不知道要保留哪一个分支上的修改。所以我们需要告诉 git 我们保留那个分支 m 或者 mainline。
1git revert -m 1 faulty merge
-m 后面带的参数值可以是 1 或者 2,对应着 parent 的顺序。
上面列子:1 代表 v3,2 代表 d2。
所以该操作会保留 master 分支的修改,而撤销 dev 分支合并过来的修改。提交历史变为:
1init -> v1 -> v2 -> v3 -- faulty merge -> v4 -> vc3 -> rev3 (master)
此处 rev3 是一个常规 commit,其内容包含了之前在 faulty merge 撤销掉的 dev 合并过来的 commit 的(反操作)的合集。
到这个时候还没完,我们要记住,因为我们抛弃过之前 dev 合并过来的 commit,下次 dev 再往 master 合并,之前抛弃过的其实是不包含在里面的。那怎么办呢?
恢复之前的回滚很简单,我们把之前 master 那个带有反操作的 commit 给撤销掉不就好了?
1git checkout master
此时提交历史变成了:
1init -> v1 -> v2 -> v3 -- faulty merge -> v4 -> vc3 -> rev3 -> rev3` -> final merge (master)
你学会这个骚操作了吗?评论区见!
▼往期精彩回顾▼卧槽!Java 长整数的这个坑你踩过吗?唉,因为 Java 的装逼简化炫技写法背锅了!
点击左下角阅读原文查看历史经典技术问题汇总,看完顺手走一波PYQ呀~