我遇到了无法解释的合并行为。以下脚本初始化存储库并使一些分支具有修改和重命名。
$ 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)"
拥有:
CONFLICT(重命名/删除):在A中删除f.txt并在HEAD中重命名。 f.txt的版本HEAD留在树中。
如果2 git在分支C中检测到重命名,从而成功合并分支A中的更改。
在案例3中,我无法理解为什么即使在成功重命名检测之后git也无法合并来自两个分支的更改。
$ git --version
git version 1.9.3 (Apple Git-50)
答案 0 :(得分:1)
U2EF1’s comment实际上是对的:
如果我记得默认情况下80%的文件内容是匹配的,但我绝对不会期望这对这些小文件合理地工作。
我刚用一个包含100行(而不是4行)的文件测试了相同的过程,Git正确识别了所有更改而没有冲突,因此我最终得到了一个文件f.txt
和两行添加。
原因是Git不跟踪文件重命名 - 甚至更改 -at all。它跟踪内容,而git mv
只是不同(尽管相似/相同)文件的git rm
和git add
的组合。因此,为了识别用于合并策略或其他视觉辅助的文件重命名(例如在git status
中),它查看内容的相似性,然后通过两个文件的相似性来判断。如果它们非常相似并且在添加另一个文件时删除了一个,那么Git会将其识别为重命名(复制检测以相同的方式工作)。现在,文件的内容越多,您就越容易让Git识别相同的内容并重命名文件。