我的树看起来像这样
* b
|\
| * a
|/
* master,m
现在我想将 a和b 合并到主
中git checkout m
git merge --no-ff a b
但它给出了
* m
|\
| * b
| |\
| | * a
| |/
| /
|/
* master
表示m在合并后没有父a
。
这是预期的行为吗?
我能做我想做的事(m
有父母master
,b
和a
)吗?最好只使用单个(合并)命令。
此脚本重现了这种情况
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
答案 0 :(得分:2)
此 是正常行为。
合并有两个部分:
我们在此假设第1步已被神奇地照顾过。 :-)也就是说,我们只关注最终的提交图。
在Git中合并(无论是否章鱼)涉及确保所选择的最终提交将所有输入提交作为祖先。如果您当前的提交是所有建议的合并提交的祖先,则合并可以作为快进操作完成,默认情况下, 将以快速方式完成 - 前进操作。
这里的缺点是,有时我们希望通过--first-parent
来区分代表分支的单一提交行。如果Git要进行快进操作,那么这条线将(至少可能)通过混合其他合并提交的其他第一父母来销毁。例如,在您的情况下,b
指向合并提交,其中父项标记为a
(一方),然后master
和m
(另一方面)。所以Git提供--no-ff
来强制进行真正的合并,通过进行新的提交,其第一个父级是当前提交。
但是,即使对于多头"章鱼"合并,如果你的参数提交名称或哈希ID是彼此的祖先,Git将删除祖先的那个:因为a
是b
的祖先,Git不必使用a
生成 正确的图或正确的源代码快照 - 所以它不会。
没有根本原因Git无法将 b
和 a
作为父母 - 第二和第三,包括按顺序 - 新合并提交。所有常用的算法都将继续有效。它只是不必要的。
答案 1 :(得分:1)
我使用git write-tree
和commit-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