我遇到这个奇怪的问题,Git合并我无法解释或分类。这是一个缺失的提交。合并出错了吗?它的数据是否已损坏?以下是存储库历史记录的内容:
master----\----commit A----cherry-picked changesets from topic---commit B--\----commit C----merge---
\ \ /
topic-----------------------------------------------------------merge---------/
现在,我的问题是当master
合并到topic
分支(为了使其与提交A和B一起更新)时,提交B引入的变更集只是不在那里!如果提交B正在修改文件foo
& bar
,即使很多也没有显示那些通过合并更改的文件。文件foo
和bar
现在,当我将topic
合并回master
时,提交B是有效的反转,没有任何记录或反转的痕迹!
可能出了什么问题?
答案 0 :(得分:11)
master----\----commit A----cherry-picked changesets from topic---commit B--\----commit C----merge---
\ \ /
topic-----------------------------------------------------------merge---------/
~~~~~
^
+ here you merged B in topic
主题中已经有一个合并,它将提交B作为父级。所以B在主题中完全合并,不再在任何地方合并。
由于您没有主题中的更改,因此您显然已在主题上还原它们,无论是在合并本身还是在后续提交中。这种反转是合并算法的常规提交,并且它不会合并到master中。因此,当您将主题合并到主服务器时,此提交的更改将被合并,还原提交B。
要从B返回更改,您必须:
git cherry-pick B
)主题。如果没有意识到这些变化可能会如何逆转?如果你正在合并并且发生冲突,你可以使用“本地”思维来解决它们,你还不需要这些改变。但是从Git(或任何其他版本控制系统的所有内容; 3-way merge在所有这些中的工作方式相同)的观点来看,你已经看到了这些变化并拒绝了它们,所以你永远不会再得到它们了,除非你手动重新应用它们。
冲突可能很容易是由早期的挑选引起的。虽然算法不会声明冲突,如果双方看起来相同,因此如果你挑选和合并,如果你在一边修改樱桃选择的代码,它将宣布冲突。说你有:
----\-- A -------- B' -- B2 --\
\ \
D -- B -- E -----------merge
其中B'
选择B
和B2
修改B
所做的相同代码。在这种情况下,合并将看到一方做B
而另一方做B2
,因为樱桃选择被B2
隐藏,因此将宣布{{1}之间的冲突}和B
。如果你不仔细看历史,你可能很容易解决这个错误。如果在选择提交时,您可以将目标分支合并到源代码中,可以避免此问题:
B2
其中----\-- A --------\- B' -\- B2 --\
\ \ \ \
D -- B -- E --m1-----m2----merge
是正常合并,没有涉及樱桃选择,m1
使用本地版本解析,因为它只在远程选择了樱桃。这将确保进一步合并将正常工作。
实际上应该可以为git编写合并策略来自动执行此操作。
答案 1 :(得分:2)
不确定为什么B
不存在,但我建议在topic
之上重新定位master
,而不是将master
合并到topic
。< / p>
您挑选的提交内容会重复到master
,但在将master
合并到已存在相同提交的分支(topic
)时效果不佳。 />
当您在topic
之上重新master
时,这会有所不同:任何重复的提交都不会重播。
当然,rebase的问题是更改topic
SHA1,如果您已将topic
推送到上游回购(其他人已经提取topic
,则会出现问题)。
一般来说,如“What is the right git workflow with shared feature branches?”所示,您可能希望避免“反向合并”(master
到topic
)并主要仅以一种方式使用合并({ {1}}到topic
)。