2015-03-02 66 views
1

通常情況下,當我做git blame $filename,混帳顯示我的各種信息的每一行代碼,就像在一個文件分成幾個文件之後,git可以跟蹤作者和文件重命名嗎?

^3333b include/Spec1.php (First Last)  function load($id) { 
^5555b class/Spec.php (Some One)   $id = ... 
^6666b include/Spec1.php (First Last)   $var = ... 

也就是說,

  • 其呈交它,
  • 誰最後更新的路線,
  • 有時甚至是該行所來自的文件名(當執行簡單的 單個文件重命名時)。

在我的情況下,我似乎已經打破了這個循環,並且git將我的更改註冊爲由我進行的單個全局更改。

也就是說,我有一個叫做Spec的大類,其中包含多個產品系列的代碼。我將班級中的各種代碼重構爲幾個新班級。當我提交時,git會將這些文件檢測爲「新文件」。

這意味着我的新文件將以我的名義註冊爲由我創建的所有新文件,並且其中的行是「全新的」。

從根本上,我失去了:

  • 原作者的每一行 - 儘管我剛剛搬到行從一個文件到另一個不是真的有創作它,Git把它作爲新的生產線不管。
  • 用於容納每行代碼的舊文件名 - 當我做git責備時,git現在只將該行看作是存放在創建的新文件中。它丟失了該行被安置在之前的文件名的跟蹤。

有沒有辦法在做這個複雜的提交時不會失去它們?

+0

不確定您的意思是「此時我有什麼能夠跟蹤更改並保留歷史記錄?」,但如果您擁有大型Spec類,那麼您將保留歷史記錄。你能指定你要找的更多嗎? – gravetii 2015-03-02 16:37:58

+0

請參閱更新 - 我正在尋找保留「文件重命名」作爲歷史的一部分 – Dennis 2015-03-02 17:17:59

+0

我剛纔重寫了這個問題,添加了「作者」 – Dennis 2015-03-02 17:29:53

回答

1

Git總是會動態地重命名和複製檢測,在您選擇兩個不同的提交進行比較時。

使用git blame時,您爲每個動態比較選擇的兩個提交來自父/子關係。 git log -pgit show的情況也是如此。當你運行git diff時,你自己決定要比較哪兩個提交(而不是讓git通過提交父代碼來挑選它們)。在任何情況下,提交最終都會通過git的內部diff引擎運行,要麼是顯式的git diff補丁輸出(git log -p,git show),要麼是其更改發現效果(git blame只需要查看子行中的行1234是否不同於在其父母)。

可以指定「相似度閾值」爲匹配的文件重命名,這通常是與-M選項,以及是否要啓用「找份」如果是這樣,是否啓用「完成找到更難「:這些通常通過-C(可能重複)或--find-copies-harder完成。 (git blame似乎沒有最後一個作爲標誌,-Mgit blame中也沒有查找文件重命名,而是改變了「移動的行」的分配方式。)

在這種情況下,您可能需要設置一個低(ish)-M閾值,並且可能至少指定-C兩次。 (二-C選項的意思是「尋找來自其他文件在當前的父/子對複製的代碼」而3個-C什麼惡意「尋找來自任何承諾複製的代碼」。)


你也可以配置diff.renames = true以始終啓用默認的-M值;或者也可以打開-Cdiff.renames = copies。這是特定於常規diff; git blame定義其-M-C標誌有些不同。

+0

謝謝。我不確定我跟着那個。當我做'git blame -C -C Spec1.php'時,git認爲片刻,然後仍然顯示每一行由我創作,今天,當每行實際上由其他人創作時,在過去的不同時間。爲了比較原始文件中的'git blame Spec.php',顯示了幾年前各行的各種作者。隨着我的重構,我失去了那段歷史。 – Dennis 2015-03-02 17:38:06

+0

我知道我需要在提交時做些事情嗎? – Dennis 2015-03-02 17:40:15

+0

不是「在提交時」,而是「在你運行git blame時」。您可能需要降低檢測閾值以查找移動和複製的代碼。缺省情況是檢測'-M'的20行塊和''-C'的40行。詳情請參閱文檔。 (我在這裏掩飾的一點是''M'和'-C'的確切定義對於'git blame'和'git diff'都是不同的。) – torek 2015-03-02 18:02:28