执行git reset --soft回退后如何重新应用已合并的历史PR提交?
解决方案
你执行git reset --soft仅移动了当前分支的HEAD指针,不会删除任何历史提交,所有被回退覆盖的PR合并提交都仍保存在Git本地仓库中,可按以下步骤提取并重新应用变更:
- 第一步:定位回退前的分支最新提交
执行git reflog查看引用日志,日志按操作时间倒序排列,找到标注为reset: moving to <你回退到的24小时前的提交哈希>的操作记录,该条记录的上一条就是你执行reset操作前分支指向的最新提交,将其哈希记为OLD_HEAD。 - 第二步:提取区间内所有PR合并提交
执行以下命令列出回退区间内的所有合并提交,正好对应你提到的30个已合并PR:git log --merges --oneline <当前回退到的24小时前提交哈希>..OLD_HEAD
输出内容会包含每个合并提交的短哈希、合并信息(一般带PR编号和标题),可以直接对应到具体PR。
关于你提到的
git cherry-pick无法使用的问题:本质是你误以为这些合并提交已经从仓库中消失,实际上这些提交只是脱离了当前分支的提交链路,只要拿到准确的提交哈希,配合-m 1参数指定以主分支为父提交基线,完全可以正常挑拣合并提交的变更,不存在使用障碍。
- 第三步:逐个落地PR变更
你可以按PR合并的时间顺序,对每个提取到的合并提交哈希执行:git cherry-pick -m 1 <合并提交哈希>
过程中如果遇到代码冲突,正常解决冲突后执行git add <冲突文件路径>标记冲突已处理,再执行git cherry-pick --continue即可完成单个PR的变更落地,逐个执行完所有提交就完成了全部PR的重新应用。
如果不想直接用cherry-pick,也可以先给每个合并提交生成独立补丁:执行git format-patch -1 <合并提交哈希> -m 1会在当前目录生成对应PR的补丁文件,后续通过git am <补丁文件路径>也可以把变更应用到当前分支。 - 兜底处理方案
如果因为执行过git gc清理、仓库是reset后重新克隆等原因导致reflog找不到对应记录,可以直接在代码托管平台的PR列表筛选过去24小时已合并的PR,每个PR都提供原始patch文件下载,下载后通过git am命令应用补丁即可,不需要手动复制变更代码。
内容的提问来源于stack exchange,提问作者Gajus
相关产品推荐
相关产品推荐

