我想知道这是否是GitHub错误,想查看是否有人发现了此问题。
我的GitHub存储库中有master
,dev
和feature
分支。
过程通常如下所示:
master : A
dev : A
feature: A - B - C
然后,我将feature
合并到dev
中并删除feature
分支,但是我不准备保留所有提交历史记录:
master : A
dev : A - B - C
当我合并为master
时,我会压缩合并使其看起来更干净:
master : A - BC
\
dev : A - B - C
我了解到,BC
在这一点上更像是一个单独的提交,但是master
的{{1}}代码和BC
的{{1}}代码是相同的。
在以上阶段比较dev
和C
时,我注意到一个奇怪的问题;当我尝试再次将master
合并到dev
中时,我看到很多冲突,反之亦然。
无论将dev
合并到master
还是dev
合并到master
中,冲突都不会改变;例如,如果master
的代码差异为dev
,当我尝试合并dev -> master
而不是-a and +b
时,我会看到相同的差异。
我们希望继续在master -> dev
分支之上构建功能并保留其历史记录,因此将其删除并基于-b and +a
创建新分支是不可能的。
我正在使用GitHub压缩和合并,因为其他成员需要批准更改才能合并到dev
中。
谁能解释我为什么看到此问题以及如何解决它?
答案 0 :(得分:1)
此图:
master : A - BC
\
dev : A - B - C
暗示C
和BC
之间存在某种联系。
没有这样的链接,但是在A
和B
之间(具体是从B
回到A
之间)有一个链接。因此,更准确的绘图是:
A--D <-- master
\
B--C <-- dev
其中D
与C
具有相同的快照,但没有关联,因此名称为D
。
这是整个问题的根源:
当我尝试再次将
dev
合并到master
时,我看到很多冲突,反之亦然。
就Git而言,dev
和master
对应的点是提交A
。因此,Git必须将从A
到C
的差异,然后再将其应用于master
,在Git看来,该差异既没有B
也没有C
我们希望继续在
dev
分支之上构建功能并保留其历史记录,因此将其删除并基于master
创建新分支是不可能的。
在那种情况下,请停止压扁,因为压扁有效地“杀死”了一个分支:对于B-C
提交,您再也不能做任何其他事情。只是做一个真正的合并。在GitHub Web UI中,选择“合并”将执行此操作;在命令行中,使用git merge --no-ff
。然后,您将获得一个合并提交(我仍称其为D
而不是一个新的完全独立的提交D
:
A------D <-- master
\ /
B--C <-- dev
在dev
上进行更多工作时,您会得到:
A------D <-- master
\ /
B--C--E--F <-- dev
,您现在可以进行另一次合并。这次不需要--no-ff
,尽管它仍然可以正常工作;在GitHub Web UI上也没有任何更改。您将获得一个新的合并提交G
:
A------D-----G <-- master
\ / /
B--C--E--F <-- dev
第二次合并的输入是将提交C
作为合并基础,将D
提交为--ours
,将F
提交为--theirs
,因此合并将顺利进行。与以前一样,C
和D
中的快照将匹配,而F
和G
中的快照将匹配。
如果您想严格地从master
的角度看发生了什么,请使用:
git log --first-parent master
这指示git log
仅查看每个合并提交的第一个父级。也就是说,Git首先显示G
指向的提交master
。然后它将从G
移到其第一个父节点D
,并显示该提交。然后它将从D
移到其第一个父节点A
并显示该提交。由于根本没有更早的提交,git log
现在停止了,其工作已完成。
(当然,如果在A
之前有提交,git log
将继续显示它们,但是此处的所有图形在A
之前都没有提交。)
答案 1 :(得分:0)
如果您已经将基本分支压缩到 main/master 中,则解决方案是对来自基本分支的所有提交进行交互变基。
假设这是当前状态
master : A - BC
\
dev : A - B - C - D
在 dev 上执行 rebase -i HEAD~3
,将 C
压缩为 B
。然后,D
的父提交将与 master 不同但相似。当您执行 git rebase master
时,您不会遇到合并冲突。
重要
这种做法重写了 git 历史。这意味着您将不得不强制推送更改。永远不要在共享分支上这样做,因为它会破坏其他用户的 git 状态。考虑在 git-scm 中咨询 Rewriting History 以获取更多详细信息。对于单个开发人员正在处理的拉取/合并请求,这种做法是安全的。