Git撤销已Push的Merge
2024-10-23 18:07:51 15
复现场景
- 现有一个分支
master - 基于
master创建分支merge master正常commit & pushCmerge正常commit & pushD和E- 将
merge合并到master, commit为M
A -- B -- C -- M (master)
\ /
D -- E (merge)masterpush
现在因为某些原因要撤销这次合并
操作方法
git log找到合并的那次commit hash (名称一般为 Merge branch xxx)git revert -m 1 hash保留创建分支后master的提交C, 抛弃merge的提交D和E-m 1表示保留master分支的更改 (保留第一个父提交 即合并前的主分支)-m 2表示保留merge分支的更改 (保留第二个父提交 即被合并的分支)- git revert会再创建一个commit, 可以看到内容是撤销了
D和E - 将commit push, 这次撤销合并就完成了
- 假如第2步选择
-m 2, 那么就可以看到master上的C被撤销,D和E被保留
生产操作, 一般都是选择-m 1, 即保留master后续的commit.
因为master主干代码都是最稳定的
其他情况 一
- 假如
merge的D和E后, 将master的C合并到merge merge再做了一次提交Fmaster又做了一次提交G- 最终将
merge合并到master
这种是比较常见的场景.
需求开始时, 从master拉个新分支.
新分支写完后准备合并.
发现冲突了, 然后把master的代码合到新分支, 涉及冲突的, (可以)重新作为新分支的一个commit.
最终将新分支的代码合并到master上线
其他情况 二
- 假如
merge的D和E后, 将master的C合并到merge merge再做了一次提交F- 最终将
merge合并到master
从git log看, master最新的commit是merge的F
属于master的有ABC, merge的DEF
方法一
这种可以先找到C的hash
然后
git reset --hard <commit_hash_of_C>
然后强制推送到remote
git push origin master --force
缺点就是master不会有DEF的相关记录了 (merge仍然有), 且会影响到其他人的合并
如果合并后刚push, 可以用reset再push (仓库允许强制push)
方法二
基于master的C创建新分支, 再替换master
方法三
git rebase -i HEAD~7
交互性的选择保留或丢弃最近7个提交
方法四
一个一个revert




