2011-10-29 23 views
75

Wikipedia解釋了自動重命名檢測:git如何檢測類似的文件,因爲它的重命名檢測?

簡言之,在給定的版本N,同名在 修訂文件N-1是它的默認祖先的文件。但是,如果修訂N-1中沒有 類似名稱的文件,則Git只會在修訂版N-1中搜索僅存在 的文件,並且將非常類似的添加到新文件。

重命名檢測顯然歸結爲類似的文件檢測。該算法是否在任何地方記錄?很高興知道自動檢測到哪種轉換。

回答

75

Git跟蹤文件內容,而不是文件名。所以重命名文件而不更改其內容對於git來說很容易檢測。 (GIT不跟蹤,而是執行檢測;使用git mvgit rmgit add實際上是相同)

當一個文件被添加到存儲庫,文件名是在樹的對象。實際文件內容作爲二進制大對象(blob)添加到存儲庫中。 Git不會爲包含相同內容的其他文件添加另一個Blob。事實上,Git不能將內容存儲在文件系統中,哈希的前兩個字符是目錄名稱,其餘的是文件名稱。因此,檢測重命名是一個比較哈希值的問題。

要檢測重命名文件的小改動,Git使用特定算法和閾值限制來查看這是否是重命名。例如,請查看git diff-M標誌。還有配置值,如merge.renameLimit(在合併期間執行重命名檢測時要考慮的文件數)。

要理解git如何處理類似的文件(即,哪些文件轉換被視爲重命名),請瀏覽配置選項和可用標誌,如上所述。你不需要考慮如何。要理解git如何實際完成這些任務,請查看用於查找文本差異的算法,並閱讀git源代碼。

算法僅適用於diff,merge和log目的 - 它們不影響git如何存儲它們。文件內容的任何小的改變意味着爲它添加新的對象。在該級別沒有發生增量或差異。當然,以後,這些對象可能會打包存儲在packfiles中的三角洲,但這與重命名檢測無關。

+2

偉大的總結,謝謝。 – mahemoff

+2

+1強調**檢測**字 – akhyar

+28

_「你不需要考慮如何。」_ - 我認爲這是一個問題? – bain

4

有許多算法檢測文本之間的相似性,版本控制系統經常使用這些算法來僅存儲兩個版本之間的差異。像WinMerge這樣的工具足夠智能,可以檢測到差異,即使在行內也是如此,所以我沒有看到爲什麼這些算法不會用於重命名檢測的原因。

這是關於algorithms to detect similar texts的討論。其中一些算法可能會針對自然語言進行優化,而其他算法可能對源代碼更好,但本質上它們非常相似。