为什么合并不会引起冲突

时间:2016-03-13 10:44:10

标签: git version-control merge

此问题遵循this topic。我正在努力了解merge做了什么来避免意外错误。

我有两个分支:masterb。我看到了做git merge的奇怪结果。您可以在合并之前看到git log 的输出,这里:

* 148c970 (HEAD, master) rename 1 in master to 1_master
| * ad18d9b (b) rename 1 in b to 1_b
|/  
* 15cd89b add 1 in master

所以我在1master中有一个名为b的文件。然后将其重命名为master1_master以及1_b中的b。然后我做了git merge

git merge b

我猜它会导致冲突,因为合并基数必须是15cd89b,并且两个分支都会在1上引入更改,但它们不匹配。

但合并并没有导致任何conflict,合并后我在工作目录中看到了1_b1_master

注意:

我认为相关答案中的torektwalberg预测了上述情况中的冲突。

2 个答案:

答案 0 :(得分:2)

如果我尝试重现您的问题,我会收到重命名/重命名冲突,正如我所料。首先,我创建了一个存储库和一些文件(具有独特的内容):

$ mkdir rename-exp
$ cd rename-exp/
$ git init
Initialized empty Git repository in /home/torek/tmp/rename-exp/.git/
$ cat > 1
This is file "1" in its initial state.
The file is being used
for a test of what happens with
a rename vs rename conflict
in Git.
The file needs some contents
so that git can detect the
rename when we actually
do the rename.
$ cat > 2
This is file "2".         
We give it some contents
so that it has a unique SHA-1.
$ git add .
$ git commit -m initial
[master (root-commit) a4b6f52] initial
 2 files changed, 12 insertions(+)
 create mode 100644 1
 create mode 100644 2

接下来,我创建分支b并重命名。请注意,使用git mvmv后跟git rm --cachedgit add进行重命名无关紧要(但git mv更容易,所以我使用它)。然而,重要的是git能够检测到重命名。这要求文件完全匹配100%(简单案例)或匹配"至少50%" (此阈值可以调整,但默认值为50%)当差异时,{1)旧名称(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
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
  • 的值
  • 来自git config --get diff.renameLimit的值,如果没有merge.renameLimit的设置。

答案 1 :(得分:1)

我认为这是因为Git并不真正了解重命名文件的概念。请参阅Git FAQ 对于Git,只有add 1_master后跟remove 1。你做的是

on branch master:

  • 添加文件1_master
  • 删除文件1

并在分支b上:

  • 添加文件1_b
  • 删除文件1

总而言之(即 merge ),这给出了:

  • 添加文件1_master
  • 添加文件1_b
  • 删除文件1

没有冲突。两个分支都对文件1应用相同的操作:删除它。

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