Git 为什么合并不会导致冲突

Git 为什么合并不会导致冲突,git,version-control,merge,Git,Version Control,Merge,接下来是这个问题。我正在努力理解merge在执行过程中如何避免不必要的错误 我有两个分支:master,b。我看到了执行git merge的奇怪结果。您可以在合并前看到git日志的输出,如下所示: 所以我在master和b中有一个名为1的文件。然后在master中将其重命名为1\u master并在b中将其重命名为1\u b。然后我做了git合并: git merge b $ git merge b CONFLICT (rename/rename): Rename "1"->"1_mas

接下来是这个问题。我正在努力理解
merge
在执行过程中如何避免不必要的错误

我有两个分支:
master
b
。我看到了执行
git merge
的奇怪结果。您可以在合并前看到git日志的输出,如下所示:

所以我在
master
b
中有一个名为
1
的文件。然后在
master
中将其重命名为
1\u master
并在
b
中将其重命名为
1\u b
。然后我做了git合并:

git merge b
$ git merge b
CONFLICT (rename/rename): Rename "1"->"1_master" in branch "HEAD" rename "1"->"1_b" in "b"
Automatic merge failed; fix conflicts and then commit the result.
$ 
我猜这会导致冲突,因为合并基数必须是
15cd89b
,并且两个分支都会在
1
上引入更改,但它们不匹配

但是合并没有引起任何
冲突
,合并后我在工作目录中看到了
1_b
1_master

注:


我认为,在上述情况下,链接答案和链接答案都预测了冲突。

我认为这是因为Git并不真正了解重命名文件的概念。请参阅。
对于Git,它只是
添加1_master
,然后是
删除1
。你所做的是

在分支主机上:

  • 添加文件
    1\u主文件
  • 删除文件
    1
在分支机构b:

  • 添加文件
    1\u b
  • 删除文件
    1
因此,总结(即合并)得出:

  • 添加文件
    1\u主文件
  • 添加文件
    1\u b
  • 删除文件
    1
没有冲突。两个分支对文件
1
应用相同的操作:删除它


如果您在其中一个分支上编辑文件
1
,情况就会发生变化。然后Git不知道是应用编辑还是删除。

如果我试图复制您的问题,我会遇到重命名/重命名冲突,正如我所预料的那样。首先,我创建了一个存储库和一些文件(具有唯一的内容):

接下来,我创建分支
b
并重命名。请注意,无论是使用
git mv
还是使用
mv
再加上
git rm--cached
git add
(但是
git mv
更容易重命名,所以我使用它)。然而,git能够检测到重命名是很重要的。这要求文件完全匹配100%(简单的情况)或在差异时匹配“至少50%”(此阈值可以调整,但50%是默认值),并且在
git merge
时两个树中不再存在旧名称(
1

$ git checkout -b b
Switched to a new branch 'b'
$ git mv 1 1_b
$ git commit -m 'rename 1 to 1_b in branch b'
[b cc104b1] rename 1 to 1_b in branch b
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename 1 => 1_b (100%)
然后在
master
中使用不同的名称目标执行相同的重命名:

$ git checkout master
Switched to branch 'master'
$ git mv 1 1_master
$ git commit -m 'rename 1 to 1_master in master'
[master b891757] rename 1 to 1_master in master
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename 1 => 1_master (100%)
最后,我运行
git merge

git merge b
$ git merge b
CONFLICT (rename/rename): Rename "1"->"1_master" in branch "HEAD" rename "1"->"1_b" in "b"
Automatic merge failed; fix conflicts and then commit the result.
$ 
您需要显示您的步骤(可能还有您的git版本),以便让我了解为什么您的合并认为每个更改都是删除和创建(使用非冲突创建)而不是重命名

影响这一点的其他变量:

  • 合并期间
    -X rename threshold
    的任何参数(这就是调整50%默认值的方式)
  • 来自git config的值--get merge.renameLimit
  • 如果没有为
    merge.renameLimit
    设置,则来自
    git config--get diff.renameLimit
    的值

您是如何重命名该文件的?使用git mv或只是在文件系统中重命名它,然后在git?@Pod中添加并删除文件,这不会有任何区别。这些都是很好的解释。我想问题出在文件
1
中,它是空的。所以git在试图计算更改时没有检测到它被重命名。你认为我的猜测是对的吗?很可能是的。两个空文件比较起来是相等的,但如果您有额外的空文件,git将无法确定文件
1
是否匹配
1_b
,而不是,比如说,
1_c
,等等。或者它可能不需要处理空文件,因为它们不是很有趣。