Git Merge:通过在合并文件中包含相同的代码块TWICE而无怨言地合并并行相同的添加而没有冲突.为什么?

Dan*_*aum 9 git merge

我在我的Git日志中有一个有点棘手的历史,我试图完全理解.

在解释提交顺序之前,让我粘贴Git日志的图像(使用SmartGit可视化历史记录)来查询相关文件:

git_history_later

...

git_history_earlier

显示的是与我的问题相关的Git历史,不相关的中间部分被剪掉了.

两位开发人员对相关文件(Developer 1和Developer 2)进行了代码更改.

开发人员1

  • 检查图片中标有" origin/staging " 的分支(但在签出时也是' origin/development ')
  • 添加一个小代码块(见下文)
  • 提交和推送 - 此推送标记为' jon-dev-test-merge ',上面
  • 对前一次提交的代码进行简单的空格更改,并提交/推送此空白更改,标记为" jon-dev-test-merge-2 ",上面
  • 意识到他本应该在一个单独的分支上工作,所以重新开始并检查' origing/staging '(当时,' origin/development '),进入一个名为' jons_dev ' 的新分支,他推动它,并设置跟踪起源
  • 将相同的小代码块(不包括空格更改)添加到此新分支(蓝线)(在标记为' test-merge-sales ' 之前的某个时间进入提交)
  • 后来,看到开发人员2已就"改变产地/发展 "分支,合并" 产地/发展 "为他的" jons_dev "分支

与此同时...

开发人员2

  • 检查图片中标有" origin/staging " 的分支(但在签出时也是' origin/development ')
  • 将代码更改为另一个文件(与上面的Developer 1中的代码更改完全无关) - 这是他在本地开发机器上的工作副本
  • 将Developer 1的代码更改为" origin/development "分支,并将其合并到本地分支/工作副本中; 合并成功,没有冲突.请注意,我们没有看到Developer 2合并到他的本地分支中(因为他没有将该分支推送到原点),而只是从他的本地分支合并(参见下一个要点)回到' origin/development ' 那个时候的分支.
  • 从本地机器上的原点合并到跟踪的开发分支中,并将合并推回原点 - 标记为' vladimir-test-merge ',上面

到现在为止还挺好.

这是我的问题.

在理解上述事件序列的过程中,我注意到一些奇怪的事情 - 对于有问题的文件, " 起源/开发 "分支没有任何变化需要合并到标记为" origin/development " 的合并中- 其解释结果为因此,在这个文件中,这个文件的相同更改,并行进行,不包括空格,因此存在于两个文件中,因此只需要来自' jons_dev '分支的更改(这就是合并执行的方式) .

但是,我注意到了合并中的一些内容,涉及Git的合并和确定冲突的方法,我无法解释.

为了以最简单的方式为我的问题演示问题,我首先创建了屏幕截图中显示的测试分支 - ' test-merge-sales '和' jon-dev-test-merge '/' jon-dev-test-merge -2 '.然后我检查了分支' test-merge-sales '并对该分支执行了两次单独的合并(取消两次测试之间的合并).

这两个合并的相关结果如下所示.(附录:由于问题下面的评论,第二个合并方案很容易解释.但是,FIRST合并方案仍然是一个问题.)


(0)BASE文件

在显示两个合并的三维屏幕截图之前,这里是文件相关部分的屏幕截图,因为它存在于" origin/staging "分支之前,在分支分歧之前:

基础文件: 预分支文件

该图显示了文件如何在两位开发人员进行任何更改之前查找两位开发人员.

还有一些注释,它们准确地解释了每个开发人员为了达到下面的案例(1)中所示的合并前状态而做出的代码更改.

正如您在评论中看到的那样,Developer 1将一个函数 - print_customer_part_order_history后跟第二个函数- 添加print_sales_analysis_page到文件中的给定位置.与此同时,另一个分支在其中添加了一个函数 - print_customer_part_order_history在文件中完全相同的位置.代码完全相同,包括空格.

这是文件进入下面的Merge Case(1)的状态.


(1)从' jon-dev-test-merge ' 合并到' test-merge-sales '分支

注意:此合并方案是我的主要问题.由于问题下方的评论,与其他合并方案(下面的#2)相关的问题已经得到解答.

此合并不会导致冲突.打开合并文件的差异查看器,这是相关(合并)行的屏幕截图:

merge_from_jon-DEV-测试合并

(单击此链接可查看完整大小的图像)

请注意,Git通过包含两个相同的函数(并行添加)'print_customer_part_order_history()'来合并文件 - 没有合并冲突.(这是Developer 1并行添加到两个分支的代码片段.)因此,此函数在合并代码中出现两次.

注意:' test-merge-sales '分支在两个分支的突出显示的代码块中具有相同的空格 - 前导空格.

问题1:为什么Git认为没有合并冲突?在文件中的相同位置并行添加了两个代码块.尽管代码块是相同的,但我认为这应该是合并冲突.


(2)从' jon-dev-test-merge-2 ' 合并到' test-merge-sales '分支

注意:由于此问题下面的评论,已经回答了与此合并方案相关的问题.

merge_from_jon-DEV-测试合并-2.JPG

(单击此链接可查看完整大小的图像)

合并代码的唯一区别是Developer 1将前导空格更改为选项卡. 但是,在这种情况下,只有空格差异,Git声明存在合并冲突.

问题2:为什么-只有在空白的差异-将Git的决定,在一种情况下,不存在合并冲突,而在其他情况下,有一个合并冲突?


关于Git如何处理合并和合并冲突,我上面提到了两个问题.

谢谢!


ADDENDUM 我在" (0)基本文件 " 一节中添加了一个额外的屏幕截图 - 两个分支分开之前文件的相关文本- 以及描述性文本.谢谢!

Tho*_*oub 5

这很简单:在执行 a 时merge,git 分析在两个大小上都发生变化的行:

  • 如果更改相距不到 2 行(参考即将推出),这将产生冲突,因为更改很可能是同一件事;
  • 如果更改相距超过 2 行,则两侧的内容将被视为两个不同的事物,并且不会分析添加的内容,只会将其添加到生成的文件中。

由于 LHSline 79line 69git上添加了该功能,而 RHS 在git上添加了它,因此认为它是不同的内容,因为它相隔极少几行。


将来如何避免这种情况?

  • 继续到diff两个分支之间的a ,如果你仔细阅读你的差异然后在合并中编辑它,这将是可见的;
  • 在您的团队内进行更多沟通(如果可能),两个开发人员在两个不同的分支中编写完全相同的功能是否正常?

来自git merge doc(重点是我的)

冲突是如何呈现的

在合并期间,工作树文件会更新以反映合并的结果。在对共同祖先的版本所做的更改中,不重叠的更改(即,您更改了文件的一个区域,而另一侧保持该区域不变,反之亦然)将逐字合并到最终结果中。然而,当双方对同一区域进行更改时,Git 不能随机选择一侧而不是另一侧,并要求您通过将双方所做的留在该区域来解决它。

  • [“参考即将推出”](https://www.memecreator.org/static/images/memes/4812866.jpg) (2认同)