如何撤销还未推送的合并(merge)
撤销未推送的 merge:git reset --hard ORIG_HEAD(须先确认 ORIG_HEAD 尚指向本次合并前的位置);或 git log 找到合并前提交再 git reset --hard <哈希>。冲突进行中想退出用 git merge --abort。
最快:git reset --hard ORIG_HEAD——merge、reset 等部分操作会更新 ORIG_HEAD,但并非每次所谓危险操作都有此保证,在确认没有后续覆盖且对应操作已记录时,它可指向"合并前"的提交。未推送的合并这样撤销干净利索。
hard reset 前先保存当前未提交工作,并用 git show ORIG_HEAD 与 git reflog 确认目标;备份分支只能保存提交。合并前工作区已脏时,merge --abort 也不保证重建全部原状态。
两种方式
# 方式一:ORIG_HEAD 快捷引用
git reset --hard ORIG_HEAD
# 方式二:手动找合并前的提交
git log --oneline # 找到合并前的提交
git reset --hard a1b2c3d
还在合并冲突中?
未完成的合并不是撤销,是中止:
git merge --abort
验证
git log --oneline --graph -5 # 确认合并提交已消失
git status # 工作区应干净
常见问题(FAQ)
Q:ORIG_HEAD 可靠吗?
它是可被后续特定操作覆盖的单一引用,不是永久的合并记录。合并后又做了 rebase/reset,ORIG_HEAD 就变了——所以撤销要趁热,或用方式二显式找哈希。
Q:已经推送了怎么办?
不能用 reset(改写共享历史)。若存在真正的 merge commit,可核对父顺序后用 git revert -m <父序号>;快进合并没有合并提交,需评估具体提交范围。revert 保留祖先关系,后续再次 merge 不会自动重引已撤销内容。
Q:合并产生的新文件也会被清掉吗?
reset --hard 会把索引和工作区还原到目标提交,合并引入且目标提交中不存在的已跟踪文件会被移除。无关未跟踪文件通常保留,但阻碍还原目标文件的路径可能被删除;不要再盲目执行 clean。