使用分支上的第一个提交压缩合并提交

时间:2021-04-02 04:34:38

标签: git github git-branch git-squash

我有一个提交和一个合并提交。我想用同一分支上的第一个提交来压缩合并提交。有人可以解释一下如何做到这一点吗?

Screenshot of git rebase -i -r

1 个答案:

答案 0 :(得分:1)

不能压缩合并提交。 “压缩”提交的定义从单独的提交 AB 开始,它们具有父/子关系,A 是父级,B 是子级:

...--o--A--B--C--...

(旧提交向左绘制,新提交向右绘制)。

然后我们用单个组合提交 A-B 替换 AB 对:

       A--B--C--...
      /
...--o--AB--C'--...

其中AB的父节点与A的父节点相同,但AB的快照与B的快照相同。因为 AB 的哈希 ID 与 AB 不同,所以我们被迫用新的提交 {{1} 替换所有“下游”提交,例如 C }} 等等。原始提交流 C' 继续存在,但我们停止使用它以支持新的和改进的流。

使提交成为 merge commit 的原因是它不仅有一个,而是有两个或多个父级。也就是说,我们可能有:

...-A-B-C

Git 目前无法将 ...--o--A--B <-- branch1 (HEAD) / C <-- branch2 替换为 (1) 具有相同父sB 和 {{1} }) 与 AB o 相同,但 (2) 与 C 的快照相同。我们想在这里得到的是:

A

人类可以做到这一点,但目前 Git 没有内置命令来做到这一点。

要手动执行此操作:

  1. 在提交 B 时进入 分离 HEAD 状态,使用 B...--o--AB <-- branch1 (HEAD) / C <-- branch2
  2. o 中的新提交 git checkout 准备合并提交消息;
  3. 运行 git switch --detach 将提交 AB 作为合并提交并快进到它;
  4. 运行 /tmp/msgfilegit merge --ff-only $(git commit-tree -p HEAD -p branch2 -F /tmp/msgfile branch1^{tree}) 使名称 AB 指向提交 git checkout -B branch1

请注意,此特定方案假定在 git switch -C branch1 上没有超出 branch1 的提交。如果有,配方就会变得更复杂。

最后一点:这样做的结果很可能就是人们所说的evil merge。请确保您了解这一点,以及对您的特定项目、同事等这样做是否合理。重新执行合并,就像 AB 稍后会做的那样,很可能产生不同的结果:完全删除提交 B