DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

Git rebase 提示 skipped previously applied,提交哈希明明不同

rebase可以按补丁等价跳过哈希不同的提交。对比实际变更,区分reapply-cherry-picks、empty与keep-empty,保留改写前引用和未提交文件。

功能分支的某个提交已经 cherry-pick 到主分支。随后把功能分支 rebase 到主分支,Git 提示 skipped previously applied commit,那个提交不再单独出现在结果中。原提交与 cherry-pick 后的哈希不同,并不阻止 Git 判断它们已经包含相同的补丁。

提交 ID 还包含父提交和提交元数据;rebase 的这项判断关注变更本身。不同 ID 不等于变更必须重复应用,也不能据此认定 Git 丢了文件。

先对比补丁,而不是只数提交

在 rebase 前,用实际上游和功能分支检查:

git cherry -v origin/main topic

origin/main 与 topic 都是示例引用,应换成准备执行 rebase 的那一对。确认上游引用已按原流程更新,并记录当前提交号,避免用旧引用分析新操作。

输出以 - 开头的提交,在指定上游有补丁等价的变更;以 + 开头的提交没有。git cherry 的比较基于 diff,并忽略空白和行号等差异,所以它能识别经过 cherry-pick、am 或 rebase 复制的提交。

这是一项帮助定位的判断,不是业务等价证明。继续查看原提交、上游对应改动和最终文件差异,尤其是冲突解决后的代码。两个提交有等价补丁,不要求它们的整个 tree ID 一定相同;周围其他文件可以已经改变。

正常去重时,无需强行留下第二次修改

默认 rebase 会在前期排除上游已经包含的 clean cherry-pick。原分支上的 D 和上游的 D' 虽然 ID 不同,若补丁等价,就可能只保留上游那一份效果。

如果最终文件包含所需改动,功能分支没有额外修改丢失,这通常正是预期结果。把建议信息关闭只会隐藏提示,不会改变选择提交的规则;也不要为了恢复提交数量直接硬重置或强推共享分支。

要审查这次重写,先在操作前保留原分支引用,并在仓库外保存未提交、未跟踪及需要保留的文件。备份引用只能保住已有提交,不能替你保存工作区里的内容。检查完成后的实际差异和项目功能,再决定是否接受新历史。

确实要重新应用时,区分两次判断

如果经过审查,仍明确需要把这些补丁纳入重放,--reapply-cherry-picks 可以改变前期自动跳过的行为。例如,在已保存工作、确认引用及本地历史边界后:

git rebase --reapply-cherry-picks origin/main

这条命令重写当前分支,不能当作只读排查命令。已经共享的历史须先按团队流程协调,不能在排错过程中顺手覆盖他人的分支。

进入重放后,提交又可能变成空提交,因为同样的改动已经在新的基础里。此时由 --empty 控制如何处理。Git 2.56.0 支持 drop、keep 和 stop;需要逐项判断时,可以在兼容版本中明确选择 --empty=stop,而不是假定 --reapply-cherry-picks 保证每个提交都留下。

--keep-empty 则针对一开始就为空的提交,不是用来阻止前期补丁等价检测的。把这三个选项混用,很容易得到“已经加了 keep-empty,为什么还被跳过”的误解。老版本的可用参数应以本机帮助为准,不要照新文档强塞未知选项。

冲突或空提交需要按当前状态处理

重放停下时先查看 git status 和当前差异,再决定继续、修改或按原计划放弃。git rebase --abort 用于仍在进行中的 rebase;操作完成后,它不能撤销已经完成的历史重写。需要恢复时依据先前保存的引用和文件处理,不要拿硬重置代替审查。

最终应核对要保留的功能改动,而不是要求新提交 ID 与旧 ID 相同。rebase 本来就会生成新的提交;这里要确认的是哪些补丁被认为已存在、哪些被重新应用,以及冲突和空结果的取舍是否符合项目意图。