乐趣区

git回滚错误合并的分支

场景
线上分支:master
你开发的分支:dev1
同时开发的分支:dev2
dev1 分支开发的代码已经上线,并且已经 merge 到 master
同时 dev2 分支也已上线,并且已经 merge 到 master
这时发现 dev1 的巨大 bug,线上版本要把这个分支的代码全部移除。

想要达到的效果
我们要撤销所有 dev1 的合并,并且保留 dev2 的代码。
同时本地 dev1 的分支不想删除这些代码,还有在这基础上开发。
master 分支
如果使用 reset,那么线上的几个提交记录都不会保留,达不到我们想要的效果。
这里使用 git revert。
首先我们要撤销所有 dev1 的更改,找到 dev1 的两次 commit id
git revert 63db9b1228c9e38a015513f834a42fa55002fca8
git revert a407174c5df3e47e1866663e4c3fe611419eb5a8
此时 master 已经达到我们想要的效果:

开发分支
这时回到我们的 dev1 分支,修复 bug,我还要保留以前提交的代码。
但是在上线前总要先 merge master,但是 master 的两次 revert 是领先你的,一旦 merge 后你的代码就没有了。
下面是当前 dev1 的提交情况

所以我们要在 merge master 后,再使用 revert 撤销这次 merge。
但是这时你发现,在 merge 完 master 之后你又在这个分支提交了新代码,这时 revert 就会报错:
git revert ce479b597de6025da4a67ddd4a94d1b8034d8c67

error: commit ce479b597de6025da4a67ddd4a94d1b8034d8c67 is a merge but no -m option was given.
fatal: revert failed
这是因为撤销的是一次合并,git 不知道要保存这两个分支中哪个的修改。
-m 1 表示保留当前分支的更改
-m 2 表示保留 master 更改
我们目的是为了保留 dev1 的代码,所以要保留当前代码,即使用 -m 1
git revert -m 1
ce479b597de6025da4a67ddd4a94d1b8034d8c67
[dev1 bb363fa] Revert “Merge branch ‘master’ into dev1”
2 files changed, 0 insertions(+), 0 deletions(-)
rename dev2 add => b (100%)
create mode 100644 c
执行完上面的代码,我们就会发现,代码又回来了,和 master 没有回滚前的代码一样。
修完 bug,再把当前代码合并到 master,然后你就会发现,dev2 提交的代码被你的 merge 干掉了???
这是因为你的那次 rever 合并采用了你的分支代码,但是你的 dev1 分支并没有 dev2 的代码 …
所以我们应该在 master 回滚前,回到 dev1 分支,先 merge 一次最新代码,再执行后面的操作。
总结
总结起来流程很简单。
1. 保持你要开发的分支同步了 master 最新代码。
2.revert 所有该分支的提交。
3. 回到你的分支 merge master。
4.revert merge master 的那次提交。

退出移动版