为什么git不能通过修改合并重命名?

时间:2015-04-12 17:04:52

标签: git merge git-merge

我遇到了无法解释的合并行为。以下脚本初始化存储库并使一些分支具有修改和重命名。

$ git init
$ emacs file.txt
$ cat file.txt 
1
2
3
4
$ git add file.txt && git ci -m "initial"
$ git branch A && git branch B && git branch C && git branch D

$ git checkout A
$ emacs file.txt
$ cat file.txt
1
added after 1
2
3
4
$ git add file.txt && git commit -m "edited in A"

$ git checkout B
$ emacs file.txt
$ cat file.txt
1
2
3
added after 3
4
$ git add -u && git commit -m "edited in B"

$ git checkout C
$ git mv file.txt f.txt
$ git commit -m "renamed in C"

$ git checkout D
$ git mv file.txt f.txt
$ git commit -m "renamed in D"
$ emacs f.txt
$ cat f.txt
1
2
3
added after 3
4
$ git add -u && git commit -m "edited in D (after rename)"

拥有:

  1. 如果您尝试'git checkout B&& git merge A'合并将完成,没有任何冲突。
  2. 如果你试试'git checkout C&& git merge A'合并将完成,没有任何冲突。
  3. 如果您尝试'git checkout D&& git merge A'你会得到:
  4.   

    CONFLICT(重命名/删除):在A中删除f.txt并在HEAD中重命名。   f.txt的版本HEAD留在树中。

    如果2 git在分支C中检测到重命名,从而成功合并分支A中的更改。

    在案例3中,我无法理解为什么即使在成功重命名检测之后git也无法合并来自两个分支的更改。

    $ git --version
    git version 1.9.3 (Apple Git-50)
    

1 个答案:

答案 0 :(得分:1)

U2EF1’s comment实际上是对的:

  

如果我记得默认情况下80%的文件内容是匹配的,但我绝对不会期望这对这些小文件合理地工作。

我刚用一个包含100行(而不是4行)的文件测试了相同的过程,Git正确识别了所有更改而没有冲突,因此我最终得到了一个文件f.txt和两行添加。

原因是Git不跟踪文件重命名 - 甚至更改 -at all。它跟踪内容,而git mv只是不同(尽管相似/相同)文件的git rmgit add的组合。因此,为了识别用于合并策略或其他视觉辅助的文件重命名(例如在git status中),它查看内容的相似性,然后通过两个文件的相似性来判断。如果它们非常相似并且在添加另一个文件时删除了一个,那么Git会将其识别为重命名(复制检测以相同的方式工作)。现在,文件的内容越多,您就越容易让Git识别相同的内容并重命名文件。