2010-08-19 139 views
17

我很瞭解Git如何支持文件移動:因爲它使用文件哈希,所以「添加」文件很容易被檢測爲與「移除」文件相同。Git在重構過程中如何跟蹤歷史記錄?

我的問題是關於重構:考慮到Java中,包聲明變化,使文件內容將不會是相同的。在這種情況下,Git如何確定「已添加」文件與「已刪除」文件共享歷史記錄?假設我只做了很小的修改或類似的非確定性解決方案,它是否檢查「最相似的內容」?

+0

等一下......這 「阿帕奇Maven的」 書只是在我面前有一個作者的名字怪異的熟悉... – VonC 2010-08-19 08:49:21

+0

吧,我是這個傢伙:D – 2010-08-19 10:25:19

+0

我知道了!我仍然試圖從「C'est pas sorcier」中談論一個瘋狂的弗雷德在最近的JUG談到maven3遷移的情景......好時光;)歡迎來到SO。 – VonC 2010-08-19 10:31:51

回答

20

Git FAQ提到的,它會檢測基於啓發式類似的內容。

Git必須與很多不同的工作流程進行互操作,例如一些更改可能來自補丁,其中重命名信息可能不可用。依靠明確的重命名跟蹤,無法合併兩棵完全相同的樹,除了一個做了補丁(創建/刪除),還有一個樹使用了其他啓發式。

第二個說明中,跟蹤重命名實際上只是跟蹤樹中內容移動方式的特殊情況。在某些情況下,您可能有興趣查詢函數何時添加或移動到不同的文件。通過僅依賴於在需要時重新創建此信息的能力,Git旨在提供一種更靈活的方式來跟蹤樹的變化。

但是,這並不意味着Git有對重命名的支持。
在GIT中的DIFF機械具有用於自動地檢測重命名的支持,這是由「-M」開關導通以對git-diff-*家庭命令。
git-log(1)和git-whatchanged(1)使用重命名檢測機制,因此例如'git log -M'將給出具有重命名信息的提交歷史記錄。
Git還支持跨重命名的有限合併形式。
兩個工具用於分配怪,git-blame(1)git-annotate(1)都使用自動重命名檢測碼來跟蹤重命名。


git log爲您提供有關啓發式一些細節:

-B[<n>][/<m>] 

歇完全重寫轉變爲對刪除和創建。這有兩個目的:

  • 它影響的方式,相當於一個文件的完全重寫不是與發生在文本上匹配的背景下,極少數線路混在一起了一系列的缺失和插入的變化,但是作爲舊的一切刪除操作,隨後插入一切新內容,並且數字m控制-B選項的這一方面(默認爲60%)。
    -B/70%指定爲與原始小於30%應保持在結果爲GIT中認爲這是一個總重寫(即否則所得到的貼劑將與上下文行混合在一起的一系列缺失和插入的)。

  • 與-M一起使用時,完全重寫的文件也被認爲是重命名的來源(通常-M只考慮消失的文件作爲重命名的來源),而數字n控制着這個方面-B選項(默認爲50%)
    -B20%指定添加和刪除相對於文件大小的20%或更多的更改有資格作爲重命名到另一個文件的可能來源。

-M[<n>] 

如果生成的diff,檢測並報告重命名爲每個提交。對於在遍歷歷史記錄時跨越重命名的文件,請參閱--follow
如果指定了n,則它是相似度索引(即與文件大小相比的添加/刪除量)的閾值。
例如,-M90%表示如果超過90%的文件沒有變化,git應該考慮刪除/添加對是重命名


其他參考:

+0

好的,但是用簡單的語言對原始情況有一個簡單的答案嗎?如果我通過將Java類移動到不同的包目錄來重構Java類,以便(例如)100行中的單行已被修改,表示Java包,則_default_日誌和責備是否會識別移動/重命名?我還會在GitHub/BitBucket上看到正確的指責嗎?換句話說,如果我執行這個(非常非常非常常見的)活動,那麼這些事情是否會與所有事情的默認設置「一起工作」? – 2015-09-05 23:07:44

+0

@GarretWilson是的,它會在本地(你可以調用'git log --follow'(如http://stackoverflow.com/q/2314652/6309)或'git blame -C'。儘管(GitHub:http://stackoverflow.com/a/5647721/6309)(或BitBucket:https://bitbucket.org/site/master/issues/589/file- history-should-follow-copies-and) – VonC 2015-09-05 23:13:29

+0

感謝您對鏈接的快速澄清!我將扣留我對Git的評論,這似乎我沒有選擇,只能使用... :) – 2015-09-05 23:35:00

相關問題