Git Flow工作流中已合并commit重复出现在新PR的原因咨询
已合并commit重复出现在新PR的原因与解决方法
现象参考
基于类Git Flow流程提交PR时,会出现部分早就在历史PR中合入integration集成分支的commit,重复出现在新开放PR提交列表的问题,当前异常PR的提交记录如下:
对应历史已合并PR的提交记录如下:
核心根因
Git唯一识别commit的依据是commit hash值,只要hash不匹配,哪怕提交内容、提交信息、作者完全一致,Git也会判定为不同提交。重复commit的问题基本都由以下三类场景导致:
- 历史PR合并时用了Squash Merge或Rebase Merge
如果团队合并PR选择Squash模式,会把PR内所有零散commit压缩成1个全新commit合入目标分支,原feature分支上的所有commit根本不会进入integration分支的提交历史;如果选择Rebase Merge模式,会把原分支的commit逐个重新应用到目标分支,生成全新的hash值。两种情况都会导致本地旧分支上的原始commit,和目标分支上实际合入的commit hash不匹配,后续开新PR时Git会把这些hash不匹配的commit判定为未合入的新提交。 - 新feature分支切分基线错误
切新分支前没有拉取远端integration分支的最新代码,直接基于本地存储的过期integration快照、甚至已经合完但未删除的旧feature分支切新分支,会把旧分支上携带的、未被目标分支识别的历史commit全部带到新分支中,PR做分支差异对比时就会把这些commit全部列出来。 - 分支历史被改写后未同步基线
如果对之前提过PR的旧分支做过amend、rebase、reset这类改写提交历史的操作,之后没有和远端已合入的最新状态对齐,直接在旧分支上开发新功能提PR,也会带出重复的历史提交。
排查步骤
- 确认历史PR的合并模式
打开之前已合并的PR详情页,查看合并记录标识,如果标注为「压缩合并」「变基合并」,即可确认是合并模式导致的commit hash不匹配。 - 本地校验commit是否真的进入目标分支
执行命令拉取最新的远端集成分支代码:
复制一个重复出现的、确认已经合过的commit短hash,执行命令在integration分支的提交历史中检索:git fetch origin integration
如果命令无输出,说明这个hash对应的commit确实没有进入integration分支,仅提交内容被合并了。git log origin/integration --oneline | grep <待校验的commit短hash> - 确认当前分支的基线位置
执行命令查找当前feature分支和最新integration分支的共同祖先节点:
拿着输出的hash查对应提交的创建时间,如果时间点早于上次PR合并的时间,说明当前分支的切分基线就是过期的。git merge-base HEAD origin/integration
修复方案
绝大多数重复commit场景,直接把当前feature分支变基到最新的integration分支即可解决:
- 切到当前提PR的feature分支:
git checkout <当前提PR的feature分支名>
- 执行变基操作,把当前分支的提交全部接到最新的integration节点之后:
git rebase origin/integration
- 变基过程中如果出现冲突,手动解决冲突文件后,执行以下命令继续变基流程:
git add <已解决冲突的文件路径> git rebase --continue
如果变基过程中提示某条提交已经存在,直接执行git rebase --skip跳过即可,对应提交的内容已经存在于integration分支中,不需要重复应用。
4. 变基完成后,执行带租约的强推命令把更新后的分支推到远端,PR列表会自动刷新:
git push --force-with-lease origin <当前提PR的feature分支名>
规避建议
- 每次切新feature分支前,必须先切到本地integration分支拉取远端最新代码,再从最新节点切新分支,不要直接在旧feature分支上开发新功能。
- 如果团队统一用Squash模式合并PR,PR合入后立刻删除对应的本地和远端feature分支,避免后续误用旧分支开发。
- 非必要不对已经提交PR的分支做改写历史的操作,如果必须修改,改完先确认和目标分支的基线对齐。
内容的提问来源于stack exchange,提问作者mindparse
相关产品推荐
相关产品推荐

