git与多个父母损失父母合并

时间:2018-04-10 07:18:31

标签: git

我的树看起来像这样

* b
|\
| * a
|/
* master,m

现在我想将 a和b 合并到主

git checkout m
git merge --no-ff a b

但它给出了

* m
|\
| * b
| |\
| | * a
| |/
| /
|/
* master

表示m在合并后没有父a

这是预期的行为吗? 我能做我想做的事(m有父母masterba)吗?最好只使用单个(合并)命令。

此脚本重现了这种情况

git init
git commit --allow-empty -m "init"
git branch m
git branch a
git branch b
git checkout a
git commit --allow-empty -m "a"
git checkout b
git merge --no-ff a
git checkout m
git merge --no-ff a b

git --version: 2.16.2.windows.1

2 个答案:

答案 0 :(得分:2)

是正常行为。

合并有两个部分:

  1. 为快照派生正确的源树。
  2. 生成正确的更新提交图。
  3. 我们在此假设第1步已被神奇地照顾过。 :-)也就是说,我们只关注最终的提交图。

    在Git中合并(无论是否章鱼)涉及确保所选择的最终提交将所有输入提交作为祖先。如果您当前的提交是所有建议的合并提交的祖先,则合并可以作为快进操作完成,默认情况下, 将以快速方式完成 - 前进操作。

    这里的缺点是,有时我们希望通过--first-parent来区分代表分支的单一提交行。如果Git要进行快进操作,那么这条线将(至少可能)通过混合其他合并提交的其他第一父母来销毁。例如,在您的情况下,b指向合并提交,其中父项标记为a(一方),然后masterm(另一方面)。所以Git提供--no-ff来强制进行真正的合并,通过进行新的提交,其第一个父级是当前提交。

    但是,即使对于多头"章鱼"合并,如果你的参数提交名称或哈希ID是彼此的祖先,Git将删除祖先的那个:因为ab的祖先,Git不必使用a生成 正确的图正确的源代码快照 - 所以它不会。

    没有根本原因Git无法将 b a作为父母 - 第二和第三,包括按顺序 - 新合并提交。所有常用的算法都将继续有效。它只是不必要的

答案 1 :(得分:1)

我使用git write-treecommit-tree完成了此操作。但我正在寻找更简单(高级)的解决方案。

... after merge into m

> git checkout m
> git write-tree
4b825dc642cb6eb9a060e54bf8d69288fbee4904
> git commit-tree 4b82 -p master -p a -p b -m "message"
4663c5272f635e688c93fd3061aeb6317dd9c86f
> git update-ref refs/heads/m 4663