Git cherry-pick后GitHub PR重复显示已合并提交的问题咨询
问题背景
我们不需要在GitHub上发起PR,而是通过git cherry-pick将cherry-pick-test分支的代码合并到main分支来保持代码更新,操作步骤如下:
git clone repo-url git checkout -b cherry-pick-test echo "commit-1" > cherry_test.txt git add ./cherry_test.txt git commit -m "commit-1" git push origin cherry-pick-test git log --graph --oneline --all # 用于获取commit hash git checkout main git cherry-pick aab828a894dd13c05bc16ed799a7842c6a8c4d6b git push origin main
执行完上述命令后,main分支已更新,cherry_test.txt也已合并到main分支。但偶尔需要从cherry-pick-test分支向main分支发起PR时,已通过cherry-pick合并的commit-1(哈希值aab828a894dd13c05bc16ed799a7842c6a8c4d6b)仍会出现在PR的待合并内容中。我们希望发起PR时不显示这些已通过cherry-pick合并的文件,想知道这个需求能否实现,还是GitHub系统本身如此设计。
(附GitHub PR截图:截图显示PR待合并内容中包含已通过cherry-pick合并的cherry_test.txt文件)
原因说明
Git的cherry-pick操作会基于原commit的内容生成一个全新的commit,这个新commit的哈希值和原分支上的commit完全不同。GitHub在对比PR的源分支与目标分支时,是通过commit哈希来判断内容是否已合并,因此会认为原分支的commit-1尚未合并到main,从而在PR中显示对应的文件。
可行解决方案
方案1:将原分支rebase到main分支
如果cherry-pick-test分支仅由你个人使用,可执行以下操作:
# 切换到cherry-pick-test分支 git checkout cherry-pick-test # 拉取远程main分支的最新代码 git fetch origin main # 将cherry-pick-test分支基于远程main分支做rebase,自动跳过已合并的内容 git rebase origin/main # 强制推送到远程分支(注意:多人协作的分支禁止强制推送) git push origin cherry-pick-test --force
rebase完成后,原分支上的commit-1会被自动移除,后续发起PR时就不会再显示已合并的内容。
方案2:基于main新建分支迁移未合并内容
如果不想修改原分支的提交历史,可直接基于最新的main分支新建分支,将cherry-pick-test上未合并的新内容cherry-pick到新分支,再用新分支发起PR。示例命令:
# 切换到main分支并拉取最新代码 git checkout main git pull origin main # 新建分支 git checkout -b new-cherry-pick-test # cherry-pick原分支上未合并的新commit(替换为实际commit哈希) git cherry-pick [未合并的commit哈希] # 推送新分支并发起PR git push origin new-cherry-pick-test
方案3:PR中手动筛选合并内容
发起PR后,在GitHub的PR页面可以选择仅合并分支上的新commit,或者使用Squash and Merge时手动排除已合并的内容,但这种方法依赖手动操作,容易遗漏或出错,仅适合临时场景。
结论
GitHub的PR对比逻辑确实是基于commit哈希判定是否合并,所以cherry-pick后的原分支commit会被判定为未合并状态。通过上述方案可以实现PR不显示已合并文件的需求,推荐使用方案1(rebase),前提是分支无多人协作;若分支有多人协作,优先选择方案2。
内容的提问来源于stack exchange,提问作者GoneCase123

