考虑有一个分支A。我从分支A创建了两个分支A1,A2。再次从分支A2创建了分支A21。我更改了X文件中的第2行,并提交并推送到A21。现在,我将这些更改合并为A2。现在,我将结帐更改为A2。当我合并原点/ A时,没有冲突。我了解到,在合并期间,如果同一行中的差异或文件被删除,则会发生冲突。但是在上述情况下,合并后在A2中所做的更改保持不变,也不会发生冲突..任何人都可以解释原因。
答案 0 :(得分:2)
首先:不要查看分支名称。查看 commits 和提交图。使用图形之后,您将仅使用名称来查找提交本身。使用图形查看器,或运行git log --graph
(也许也使用--all --decorate --oneline
)。您将看到图像或带有连接提交到其 parent 提交的行的文本,形成树或图结构:
* a123456 last commit on A1
* a123457 another commit on A1
| * a2fedcb last commit on A2
|/
* a0dead0 latest shared commit reachable from both A1 and A2
.
.
.
例如,或查看下面从this answer到Viewing full version tree in git的图片。
一旦有了图形,它就会相对清楚地明白合并基础的含义。两个特定提交的合并基础是两个分支共享的提交。在上面的输出中,将提交a0dead0
。
如果我们重新水平绘制图形,则可能更清楚两个分支的分支方式:
o--...--X <-- you-are-on-this-branch (HEAD)
/
...--o--*
\
o--...--Y <-- you-ask-to-merge-this
这里,提交*
是合并的基础,提交X
(您现在已签出的提交)是HEAD
,提交Y
是另一个提交您要合并。
现在,git merge
的工作方式实质上是从合并库本身开始。 Git提取合并基础提交,然后查看分支提示提交X
和Y
。 Git 比较合并基础以提交X
,以查看您所做的事情:
git diff --find-renames <hash-of-*> <hash-of-X>
然后,Git比较合并基础以提交Y
,以查看他们做了什么:
git diff --find-renames <hash-of-*> <hash-of-Y>
Git现在只需将这两组更改组合,将它们全部应用于合并基础中的所有内容,并且,如果一切顺利,则进行新的合并提交,从而将当前分支移动为好吧:
o--...--X
/ \
...--o--* M <-- you-are-on-this-branch (HEAD)
\ /
o--...--Y <-- you-ask-to-merge-this
合并的两个父级是按此顺序合并的两个提交,即X
和Y
。
如果Git可以合并更改,则合并成功 。
如果Git无法合并更改,则合并失败。
如果您和他们将相同更改为相同文件的相同行,则Git可以将这两个更改组合在一起只需一份副本即可轻松完成。这就是Git所做的。
如果您对合并基础中的相同行进行了不同更改(提交*
),则会产生冲突。
Git可以优化整个流程,通常根本不需要物理上提取提交*
,但是原则上,这就是合并的过程。
(gitk
图片示例)
答案 1 :(得分:0)
除了@torek所说的以外,git
即使更改是相同的,即使更改是独立进行的,也将无冲突地处理合并。
在这里,我分别在branch1
和branch2
中的同一文件中进行相同的更改,然后将branch2
合并到branch1
/mnt/c/git/ConsoleApp1 (branch1)>git commit -a -m "Adding Foo in branch1"
[branch1 c03dcc2] Adding Foo in branch1
1 file changed, 4 insertions(+)
/mnt/c/git/ConsoleApp1 (branch1)>git checkout develop
error: pathspec 'develop' did not match any file(s) known to git.
/mnt/c/git/ConsoleApp1 (branch1)>git checkout master
Switched to branch 'master'
/mnt/c/git/ConsoleApp1 (master)>git checkout -b branch2
Switched to a new branch 'branch2'
/mnt/c/git/ConsoleApp1 (branch2)>git commit -a -m "Adding Foo in branch2"
[branch2 d433128] Adding Foo in branch2
1 file changed, 4 insertions(+)
/mnt/c/git/ConsoleApp1 (branch2)>git merge branch1
Merge made by the 'recursive' strategy.
结果:无冲突。
答案 2 :(得分:0)
在您的描述中,您仅谈论单个更改:
我更改了X文件中的第2行,并提交并推送到A21。
您永远不会说类似“ ...,并且在分支A上,我将X文件中的第2行更改为其他内容并提交了。”
如果这是真实的情况(即游戏中只有一个更改),那么就不会发生冲突。