问题场景

在新公司工作了一段时间的波仔,完成了分配给自己的任务,公司采用的是多分支模式开发,完成功能的波仔将自己的代码提交到特性分支 feature_task_bobomerge合并到了develop分支, 然后将合并结果push到了远程的develop分支, 测试部门拉取develop分支代码进行测试, 发现波仔的需求实现有偏差需要大改,且波仔的部分配置信息影响了其它功能的正常运行,项目上线在即 项目负责人决定先将波仔的合并代码取消,待需求修改完毕 bug解决掉后,在进行合并。
如何同时撤回远程和本地分支合并操作 - 图1
那么问题来了,代码目前已经完成本地merge合并 并且将merge推送到了远程仓库, 如何同时撤销本地merge 和 远程的merge操作呢?
如何同时撤回远程和本地分支合并操作 - 图2
问题演示
如何同时撤回远程和本地分支合并操作 - 图3

  1. 当前代码在develop分支
  2. 波仔 和 三毛都完成了代码 分别为 feature_task_bobo分支, feature_task_3mao分支
  3. 三毛代码先完成了合并 git merge feature_task_3mao
  4. 其次波仔完成了合并 git merge feature_task_bobo

合并后发现冲突
如何同时撤回远程和本地分支合并操作 - 图4
如果这个时候, 发现波波的代码有问题决定回滚 可以直接使用取消合并的命令即可:
git merge --abort
但是波波以为是正常的冲突 所以波波选择解决冲突 并commit提交了代码
并且,合并冲突时 波仔覆盖了3毛的配置代码
如何同时撤回远程和本地分支合并操作 - 图5
如果此时,在commit了合并后, 还未推送到远程分支的情况下 想要取消分支 可以通过reset重置到合并前的状态
git reset --hard HEAD^
但波波直接使用 git push 将 合并操作提交到了远程develop仓库中
最终测试出现问题,3毛配置被覆盖, 波仔负责模块有需求变更
需要将本次波仔的代码合并操作远程和本地分支都取消

解决思路

通过git log查看日志
如何同时撤回远程和本地分支合并操作 - 图6
当前情况如下
如何同时撤回远程和本地分支合并操作 - 图7

  1. 这里是在d3节点,合并了波仔分支代码出现的问题
  2. 可以先撤销波仔的合并操作 但不能用reset 回退版本,而是把撤销操作通过revert变为一个新的commit
  3. 在通过push将撤销操作推送到远程仓库
  4. 这样本地和远程都完成撤销合并操作
  5. 波仔把bug修复完毕后,在重新将波仔的代码合并进来

    动手实践

    基于idea工具解决

    idea中可以查看log日志

如何同时撤回远程和本地分支合并操作 - 图8

但右键该合并记录,发现revert commit操作不可点击 需要去命令行窗口操作:直接查看命令行解决方案即可

如何同时撤回远程和本地分支合并操作 - 图9

基于git命令解决

执行 git log查看日志,找到合并分支对应的版本号

如何同时撤回远程和本地分支合并操作 - 图10

develop分支 执行 git revert -m 1 1c3420d0452551040078a830a20c3a4e491b19c8 撤销合并

如何同时撤回远程和本地分支合并操作 - 图11
如何同时撤回远程和本地分支合并操作 - 图12
执行后会弹出编辑页面, 直接 :wq 保存即可
命令的作用, 撤销合并的操作, 并创建一个新的commit提交记录
如何同时撤回远程和本地分支合并操作 - 图13
执行完上面的操作,可以看到3毛的配置回来了,而波仔的代码被回退

develop分支 执行 git push 将撤销合并推送到远程develop分支

如何同时撤回远程和本地分支合并操作 - 图14
远程分支,也仅有3毛分支的代码, 这样就完成了 本地 + 远程 合并分支代码的撤销操作
波仔可以继续修改自己分支的bug问题,修改完毕后将波仔的代码重新合并到develop分支

切换到feature_task_bobo分支, 修改配置并提交

如何同时撤回远程和本地分支合并操作 - 图15

切换到develop分支, 重新合并波仔分支代码

如何同时撤回远程和本地分支合并操作 - 图16
如何同时撤回远程和本地分支合并操作 - 图17
出现冲突, 解决冲突代码,解决完毕后 再次commit and push
如何同时撤回远程和本地分支合并操作 - 图18

这样问题就全部解决啦~ 执行git log查看状态

如何同时撤回远程和本地分支合并操作 - 图19

注意

如果撤销波仔合并操作后, 再次合并波仔代码时, 发现之前参与合并过的代码无法再次合并到develop分支时
可以再一次的在 develop分支 执行 git revert 撤销合并的commit版本号 将之前撤销的波仔代码找回来即可

企业规范建议

如果正在合并代码解决冲突中

  1. git merge --abort 取消代码合并

如果合并完毕并commit提交到了本地仓库

git reset --hard HEAD^   回退到上一个版本

后面的选项有四种:
--mixed 为默认,可以不用带该参数,用于重置暂存区的文件与上一次的提交(commit)保持一致,工作区文件内容保持不变。
--hard 参数撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到上一次版本,并删除之前的所有信息提交:
--soft 仅仅修改分支中的HEAD指针的位置,不会改变工作区与暂存区中的文件的版本。

如果合并完毕,commit提交到了本地,还push到远程

git revert -m 1 HEAD  回到上一个commit的状态 (或者在git log 中找到对应的合并版本号) 即可撤回合并
git push origin master 撤回合并作为一个新的commit 推送到远程仓库