git合并冲突的不同场景

git合并冲突的不同场景,git,git-merge,merge-conflict-resolution,git-merge-conflict,Git,Git Merge,Merge Conflict Resolution,Git Merge Conflict,我试图了解在git合并之后,git冲突会发生在哪些情况下,以及如何避免这些情况 我创建了一个git存储库,并向其中添加了一个文本文件 我已将“1”添加到文本文件并将其提交给master 我已经从master(branch2)创建了一个新分支,并在文本文件中添加了一行内容为“2”的新行 我已经从master(branch3)创建了一个新分支,并在文本文件中添加了一行内容为“3”的新行 在此之后,我做了以下工作: 我已将第二分支合并为主分支。没有冲突,这是正确的,我也期待着 我已将master

我试图了解在git合并之后,git冲突会发生在哪些情况下,以及如何避免这些情况

我创建了一个git存储库,并向其中添加了一个文本文件

  • 我已将“1”添加到文本文件并将其提交给master
  • 我已经从master(branch2)创建了一个新分支,并在文本文件中添加了一行内容为“2”的新行
  • 我已经从master(branch3)创建了一个新分支,并在文本文件中添加了一行内容为“3”的新行
在此之后,我做了以下工作:

  • 我已将第二分支合并为主分支。没有冲突,这是正确的,我也期待着
  • 我已将master合并到branch3。我有冲突,因为文本文件的第二行有不同的内容。我已通过保留“3”而不是“2”来修复冲突
  • 我想把第三分支合并到主分支。现在我的问题是:1。当我进行合并时,是否有可能发生冲突?若有,原因为何?若否,原因为何?2.如果没有冲突,但我仍然有冲突,原因是什么

当您将
branch3
合并到
master
时,您不应该有任何冲突,如果您没有将
master
合并到
branch3
。原因很简单,因为您向
branch3
添加了一个commit,它解决了它与
master
之间的冲突。所以现在合并到
master
可以快速转发。

合并冲突发生在合并期间,而不是在合并之后

冲突部分非常简单:文件F中发生冲突时:

  • “我们的”更改了从合并基提交到我们的
    头的差异,提交更改为文件F,并且
  • “他们的”更改了从相同的合并基提交到其提示提交的差异,也更改了文件F,以及
  • 我们的变化和他们的变化重叠,但并不相同
要了解这一点,您需要:

  • 了解git diff的输出;及
  • 了解什么是合并基础
  • 实际上,
    git diff
    的输出非常简单,但它需要记住每个提交都包含所有文件的快照。这意味着我们必须提供两个快照:一个旧快照和一个新快照。这是文件在两个时间点的两张“图片”。Git接着玩了一个游戏:它告诉您,要从左侧快照转到右侧快照,必须对某组文件进行一些更改。这些更改可能涉及重命名某些文件;它们可能涉及添加新文件;它们可能涉及删除文件;它们可能涉及从某些文件中删除某些特定行,并在某些特定位置向某些文件中添加某些行

    git diff的输出不一定是任何人所做的。这只是一组更改,如果应用于左侧快照,将得到右侧快照。这里的“left side”是git diff的左参数,这里的“right side”是右参数,当您使用:

    git diff <hash1> <hash2>
    
    这里,当合并
    branch1
    branch2
    ——这意味着提交
    J
    L
    ——公共起点显然是提交
    H
    。因此,
    git merge
    将运行两个
    git diff
    命令,每个命令中的合并基将是
    H

              I--J   <-- branch1 (HEAD)
             /
    ...--G--H
             \
              K--L   <-- branch2
    
    git diff --find-renames <hash-of-H> <hash-of-J>    # what we changed on branch1
    git diff --find-renames <hash-of-H> <hash-of-L>    # what they changed on branch2
    
    这将是您的合并结果

    如果合并失败,Git在合并中间停止。您现在的工作是完成合并(自己合并更改),然后告诉Git您已经完成了合并并提交。如果这太混乱了,您可以告诉Git:完全中止合并,它将放弃所有合并尝试,并让您重新提交

    J
    ,就好像您根本就没有运行过
    Git merge

    最后一个棘手的问题是:当您通过Git自动完成合并,或者手动完成合并时,会提交两个父级记录。也就是说,如果您查看上面的merge
    M
    ,您将看到它连接回提交
    J
    L
    。在许多合并中,我们得出的结论略有不同:

                    o--o   <-- small-feature
                   /    \
    ...--o--B--o--D--o---o--o   <-- mainline
             \
              o--o--o--o--o--o   <-- big-feature
    
    这张图并不复杂,但现在很难看出合并的基础在哪里,因为从各种特性到主线以及相互之间的交叉合并


    Git将找到合并基。您可以使用
    git merge base--all
    自己查找合并基。您可以绘制图形,或者让Git使用Git log--graph
    绘制图形,并尝试通过肉眼查找合并基。找到合并基后,无论您如何操作,都可以运行
    git merge
    将运行的两个
    git diff
    命令。这将告诉您冲突将发生在哪里。但是通常情况下,没有什么意义:只需运行
    git merge
    并查找冲突。

    谢谢您的回答,但是第二个问题呢?我看不出在您描述的场景中有任何冲突的原因。您是否能够包含冲突消息?这可能有助于确定出现问题的原因。
                    o--o   <-- small-feature
                   /    \
    ...--o--B--o--D--o---o--o   <-- mainline
             \
              o--o--o--o--o--o   <-- big-feature
    
                      o--o---o   <-- offshoot-feature
                     /      / \
                    o--o---o---o--o   <-- medium-feature
                   /    \ /
    ...--o--o--o--o--o---o----o   <-- mainline