首页 > 解决方案 > 将两个合并合并为一个(或者,我可以更改提交的父级吗?)

问题描述

您能否考虑以下情况:

假设我们有以下主题分支:A、B、C、D、E、F,并且我们希望将它们合并在一起。

还假设,由于多个冲突,不可能将它们全部合并到一个章鱼合并中:

# git checkout A
# git --no-ff B C D E F
ERROR: no octopus strategy allowed

但是,可以将它们合并为轮流:

# git checkout A
# git merge --no-ff B C
OK with conflicts.
(resolve conflicts)
# git commit

# git checkout D
# git merge --no-ff E F
OK with conflicts.
(resolve conflicts)
# git commit

现在我们分别在 A 和 D 的 HEAD 上进行了两次合并提交。我们可以合并这两者。

# git checkout A
# git merge --no-ff D
OK: no conlicts

现在历史看起来有点像这样:

* A
|\
|*- D
||\\
|||* E
||* F
|*
*-
|\\
||* B
|* C
*

正如您现在可以看到 A 的 HEAD 处的提交,有两个父级,每个父级都是一个合并提交。是否可以重写最后一次提交(以及它包含的所有更改),以便它将原始六个分支的 HEAD 指向的提交作为父项?

如果没有 git 命令可以做到这一点,是否可以在 git 数据库中找到对象,更改它,计算一个新的 SHA-1 并存储它?

非常感谢您提前。

标签: git

解决方案


您不能更改任何现有提交的任何部分。

正如RomainValeri 在评论中指出的那样,可以构建您喜欢的任何提交,包括使用. 然后,您可以修改存储在您希望引用此新合并提交的任何特定分支名称中的哈希 ID,这实际上是具有冲突解决的章鱼合并:git commit-tree

          ________________
         /                \
...--o--o   <-- name1      \
         \   _______________\
          \ /                \
           X                  \
          / \                  \
 ...--o--o---M1   <-- name2     @   <-- branch
               >--M3 <--name5  /
 ...--o--o---M2   <-- name3   /
          \ /                /
           X________________/
          /                /
 ...--o--o   <-- name4    /
          \______________/

例如,@您的手工章鱼合并在哪里。根据需要更改名称(您可以随意删除和重新创建名称,或强制更新名称,或重命名分支名称),以便您发现特别有趣的一个特定名称选择 commit @,您git commit-tree使用相同的名称作为合并M3合并合并提交M1M2.

(上面的多个names 大多是可选的,但可以帮助您找到每个提交。)

我建议不要这样做,因为它不是典型的工作流程。如果你这样做了,请在不寻常的合并提交消息中添加一些内容,说明你是如何做到的以及为什么这样做。一些未来的代码考古学家——甚至可能是你自己一年后——可能正在查看历史提交,试图了解一些错误是如何产生的,并且可能会遇到这种不寻常的手工合并提交。如果没有指导,或者至少没有提醒,任何遇到这种章鱼合并的人都可以看着它并想:啊哈,章鱼合并,一定没有任何冲突,因此假设这次合并没有冲突。

如果连续有两个普通合并,遇到它们的人不能假设没有冲突,因为普通合并通常涉及冲突解决。


推荐阅读