Git合并提交未在Git/SourceTree中显示为合并状态的修复咨询
别急,这种情况我之前在协作开发时也碰到过——合并分支后因为 stash 操作导致提交丢失了合并节点信息,变成了普通提交,所以 Git/SourceTree 没法显示合并的图形线条。不用重新合并,咱们可以通过修改提交的父节点来修复:
第一步:确认关键提交哈希
先搞清楚两个核心提交的哈希值:
- 当前 HEAD 的提交:执行
git rev-parse HEAD就能拿到,记为CURRENT_COMMIT - 被合并分支的顶端提交:就是你原本要合并的那个分支的最后一个提交,比如你合并的是
feature分支,就执行git rev-parse feature,记为MERGED_COMMIT
如果记不清被合并的分支提交,也可以用 git reflog 查看操作历史,找到合并前的状态对应的提交。
第二步:创建新的合并提交
用 git commit-tree 命令创建一个保留当前提交内容,但包含两个父节点的新合并提交:
# 生成新的合并提交,保留原提交的提交信息 git commit-tree -p HEAD^ -p MERGED_COMMIT -m "$(git log -1 --pretty=%B HEAD)" HEAD^{tree}
执行完这个命令后,终端会输出一个新的提交哈希,记为 NEW_MERGE_COMMIT。
第三步:重置HEAD到新的合并提交
把当前分支的 HEAD 指向刚生成的合并提交:
git reset --hard NEW_MERGE_COMMIT
这一步会替换当前分支的顶端提交,但是你的代码修改(包括修复的构建错误)都会完整保留,因为我们复用了原提交的树对象。
第四步:推送到远程(如果已经推送过)
如果之前已经把有问题的提交推送到了远程仓库,需要强制推送更新(重要提示:如果是多人协作的分支,一定要先和团队成员沟通,避免覆盖其他人的修改):
git push --force-with-lease
--force-with-lease 比直接 --force 更安全,它会检查远程分支是否有你本地没有的新提交,避免误覆盖。
为什么会出现这个问题?
简单来说,Git 的合并提交需要包含两个父节点(原分支的最后提交 + 被合并分支的最后提交),而你在解决冲突后执行 stash 操作,后续的提交可能变成了普通提交(只有一个父节点),所以 Git/SourceTree 没法识别这是一个合并操作,自然就不会显示合并线条。
这样操作后,你再打开 SourceTree 或者执行 git log --graph,就能看到正确的合并图形链接了,而且完全不需要重新做一遍合并和错误修复的工作~
内容的提问来源于stack exchange,提问作者packoman

