2015-04-12 41 views
2

我遇到了我無法解釋的合併行爲。以下腳本初始化存儲庫,並通過修改和重命名來創建一些分支。爲什麼git無法合併具有修改的重命名?

$ 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. 如果你嘗試「混帳結賬乙& &混帳合併A」合併將沒有任何衝突來完成。
  2. 如果您嘗試'git checkout C & & git merge'合併將完成沒有任何衝突。
  3. 如果你嘗試 '混帳結賬d & &混帳合併A',你會得到:

衝突(重命名/刪除):在f.txt刪除和重命名HEAD。 版本f.txt的HEAD留在樹中。

在案例2中的git檢測到重命名分支C和從而成功地合併從分支A.變化

萬一3,我不明白爲什麼git的不能合併來自兩個支路甚至改變成功重命名檢測後。

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

如果我記得默認是80%的文件內容匹配,但我永遠不會期望這樣的工作合理與這樣的小文件。 – U2EF1

回答

1

U2EF1’s comment實際上是正確的:

如果我記得默認是該文件內容的80%一致,但我絕不會想到這與這樣的小文件合理工作。

我只是測試相同的程序與具有100線(而不是4)文件,和Git正確識別無衝突的所有變化,所以我結束了一個文件f.txt和兩線補充。

原因是Git不跟蹤文件重命名 - 甚至是更改 - 所有。它跟蹤內容,並且git mv只是不同(儘管相似/相同)文件的git rmgit add的組合。因此,爲了識別合併策略或其他視覺輔助的文件重命名(例如在git status中),它會查看內容的相似性,然後根據兩個文件的相似性進行判斷。如果它們非常相似,並且在添加另一個文件時刪除了一個,則Git會將其識別爲重命名(複製檢測的工作方式相同)。現在,文件的內容越多,Git就越容易識別相同的內容並重新命名文件。

+0

感謝您的回覆。但爲什麼小文件存在這種限制或行爲差異?合併小型重命名文件有什麼問題嗎?我如何強制git合併小文件? – mekarthedev

+0

I.e.有沒有辦法在情況3下強制git合併文件沒有衝突? – mekarthedev

相關問題