git revert 2

一、什么是合并提交(Merge Commit)

合并提交是指通过 git merge 命令把一个分支合并到当前分支时产生的特殊提交。它有两个或多个父节点,通常用于整合分支开发成果。例如:

复制代码
A---B---C---E  (master)
     \     /
      D---F    (feature)

合并 featuremaster 后,会产生一个新的合并提交 E,它有两个父节点:C(master)和F(feature)。


二、为何撤销合并提交比较特殊

普通提交只有一个父节点,git revert <commit-hash> 可以直接反向应用。但合并提交有多个父节点,Git 不知道你要保留哪条分支的内容,所以需要额外指定"主分支"(即保留哪一条父分支的内容)。


三、撤销合并提交的命令及参数

1. 基本命令

bash 复制代码
git revert -m <parent-number> <merge-commit-hash>
  • <merge-commit-hash>:你要撤销的合并提交的哈希值。
  • -m <parent-number>:指定主分支的父节点编号(通常是 1)。

2. 如何确定 parent-number?

  • 如果你在 master 分支上合并了 feature,那么合并提交的第一个父节点(parent 1)通常是 master,第二个父节点(parent 2)是 feature
  • 一般撤销合并时,-m 1 表示保留当前分支(master)的内容,撤销被合并分支(feature)的变更。

3. 实例演示

假设你在 master 分支上执行了如下合并:

bash 复制代码
git merge feature
# 产生了一个合并提交 hash 为 abcdef

后来发现合并有问题,需要撤销:

bash 复制代码
git revert -m 1 abcdef

这会生成一个新的提交,内容是把合并分支的变动"反向应用",只保留主分支的内容。


四、撤销合并提交的注意事项

  1. 冲突处理:撤销合并提交时,可能会遇到冲突。需要按照 Git 的提示解决冲突,再提交。
  2. 只撤销合并,不影响主分支历史:revert 合并提交不会删除任何历史,只是新增一个"反向合并"的提交。
  3. 慎用 reset:如果合并提交已经推送到远程仓库,建议用 revert 而不是 reset,否则会破坏团队协作。

五、常见问题与解答

Q1. 如果我不确定 parent-number 应该是多少,怎么办?

可以用如下命令查看 merge commit 的父节点:

bash 复制代码
git log -1 --pretty=raw <merge-commit-hash>

输出中会有 parent <hash> 字段,按顺序分别是 parent 1、parent 2......

Q2. 撤销合并提交后,能再次合并同一个分支吗?

如果你撤销了合并提交,Git 会认为你已经合并过该分支。此时再次合并可能会提示"Already up to date",需要用 --no-ff--allow-unrelated-histories 之类参数。

Q3. 撤销合并提交和普通提交有什么区别?

  • 普通提交只需要 git revert <commit-hash>
  • 合并提交必须指定主分支 -m <parent-number>,否则 Git 会报错。

六、总结

撤销合并提交的正确方式是:

bash 复制代码
git revert -m <parent-number> <merge-commit-hash>
  • -m <parent-number> 指定你要保留的父分支。
  • 适用于已推送远程仓库、团队协作场景。
  • 不会破坏历史,安全可靠。
相关推荐
allnlei10 分钟前
优化大仓库项目中git的使用
git
芒克芒克16 分钟前
《Git分支实战:从创建到合并的全流程》
java·git
2501_9167665443 分钟前
【Git学习】Git本地仓库基础命令
git·学习
拽着尾巴的鱼儿1 小时前
工具篇:git compare with branch 分支版本回退
git
PMP_2 小时前
git 操作 (unable to update local ref) 错误
git
黑岚樱梦2 小时前
Git学习和Linux基础
git·学习
cc蒲公英13 小时前
idea git命令初次创建项目至远程
git
高兴就好(石14 小时前
git将远程的master分支的commit都拉取到本地
git
空空kkk17 小时前
Git版本控制(一)
git
毛豆的毛豆Y18 小时前
git 如何 fork 一个仓库的所有分支
git