2012-07-23 98 views
6

我想找到重複更改的配方。 patch-id很可能是相同的,但提交屬性可能不是。git發現重複的提交(通過補丁ID)

這似乎是一種用途補丁ID:

混帳補丁ID --help

督察,你可以用這個東西來尋找可能的重複提交。

我想象串聯在一起「混帳日誌」,「混帳補丁ID」和uniq的 可能不好做的工作,但如果有人有,做的 工作做好的命令,我將不勝感激。

+0

這是一個有趣的功能。出於好奇,過去你打算看多遠?我可以看到一些有創意的集成用途(即「我的貢獻者不知道如何重新分配」),但是歷史悠久,它的效率會降低......? – Christopher 2012-07-23 02:23:51

+0

這個問題出現在一個單一分支的一個星期的歷史中,所以我的用例很溫和(git log -p就足夠了)。補丁ID評論讓我好奇,雖然...搜索所有的歷史可能是痛苦的。 – bsb 2012-07-25 00:43:24

回答

10

由於重複的變化很可能是不在同一個分支(如果有就回到它們之間除外),你可以使用git cherry

git cherry [-v] [<upstream> [<head> [<limit>]]] 

upstream將重複檢查的分支head的變化。

2

我有一個玩具回購工作的草案,但因爲它保持了 patch->提交映射在內存中可能有大的回購問題:

# print commit pairs with the same patch-id 
for c in $(git rev-list HEAD); do \ 
    git show $c | git patch-id; done \ 
| perl -anle '($p,$c)[email protected];print "$c $s{$p}" if $s{$p};$s{$p}=$c' 

輸出應該對提交的與相同的修補程序ID (3個重複的ABC出現爲「AB」,然後是「BC」)。

變化git的REV-list命令限制提交檢查:

git log --format=%H HEAD somefile 

追加 「| xargs的混帳秀」 來查看詳細的提交, 或「| xargs的混帳顯示-s --oneline 「作一個總結:

0569473 add 6-8 
5e56314 add 6-8 again 
bece3c3 comment 
e037ed6 add comment again 

原來補丁-ID並沒有在我原來的情況下, 有在其他更改後提交工作。 「git log -S」更有用。

+0

如果你想看看commit和它的父代之間的原始差異,你可以做一些像'git diff $ c〜1 $ c | git patch-id'。這會對合並提交造成不良影響。合併父母之後是一個更復雜的問題。 – Christopher 2012-07-25 09:57:23

+0

它看起來像patch-id找到相同的差異? $ git diff HEAD〜1 HEAD | git patch-id 3318362fa07e580 .. 000000000000 .. $ git show HEAD | git patch-id 3318362fa07e580 .. c397c4cdc426 .. – bsb 2012-07-26 23:02:08

+0

@bsb您確定要編寫'git show $ c | git patch-id'? 'git show'打印元數據,但'git patch-id'需要補丁作爲輸入... – 2014-04-23 16:02:42

7

要查找特定提交的重複項,這可能適用於您。

首先,確定目標的補丁ID提交:

$ THE_COMMIT_REF_OR_SHA_YOURE_SEEKING_DUPES_OF='7a3e67c' 
$ git show $THE_COMMIT_REF_OR_SHA_YOURE_SEEKING_DUPES_OF | git patch-id 
f6ea51cd6acd30cd627ce1a56e2733c1777d5b52 7a3e67ce38dbef471889d9f706b9161da7dc5cf3 

第一SHA是補丁-ID。接下來,列出了修補程序ID爲每次提交併過濾掉任何比賽:

$ for c in $(git rev-list --all); do git show $c | git patch-id; done | grep 'f6ea51cd6acd30cd627ce1a56e2733c1777d5b52' 
f6ea51cd6acd30cd627ce1a56e2733c1777d5b52 5028e2b5500bd5f4637531e337e17b73f5d0c0b1 
f6ea51cd6acd30cd627ce1a56e2733c1777d5b52 7a3e67ce38dbef471889d9f706b9161da7dc5cf3 
f6ea51cd6acd30cd627ce1a56e2733c1777d5b52 929c66b5783a0127a7689020d70d398f095b9e00 

總之,有一些額外的標誌,並在utility script形式:

test ! -z "$1" && TARGET_COMMIT_SHA="$1" || TARGET_COMMIT_SHA="HEAD" 

TARGET_COMMIT_PATCHID=$(
git show --patch-with-raw "$TARGET_COMMIT_SHA" | 
    git patch-id | 
    cut -d' ' -f1 
) 
MATCHING_COMMIT_SHAS=$(
for c in $(git rev-list --all); do 
    git show --patch-with-raw "$c" | 
     git patch-id 
done | 
    fgrep "$TARGET_COMMIT_PATCHID" | 
    cut -d' ' -f2 
) 

echo "$MATCHING_COMMIT_SHAS" 

用法:

$ git list-dupe-commits 7a3e67c 
5028e2b5500bd5f4637531e337e17b73f5d0c0b1 
7a3e67ce38dbef471889d9f706b9161da7dc5cf3 
929c66b5783a0127a7689020d70d398f095b9e00 

這是不是非常迅速,但對於大多數的回購協議是不是需要做工作(只是測量36秒與826個提交回購和158MB的.git目錄上一個2.4GHz Core 2 Duo)

+0

我可能是唯一一個感到困惑的人,但爲防萬一,「target-commit」不是文字;將其替換爲您想要獲取補丁ID的提交的SHA。 – Jimothy 2014-08-20 14:10:49

+1

@Jimothy Yep,或分支名稱或標籤名稱(任何參考,我猜)。我會看看我能否更清楚一點。 – 2014-08-20 18:43:43

2

通過bsb建議的漂亮的命令需要幾個小的調整的:

(1)相反的git show,它運行git diff-tree --cc,命令應該使用

git diff-tree -p 

否則git patch-id產生雜散空SHA1哈希。 (2)當使用管道到xargs時,xargs應該有-L 1參數。否則,三重提交不會與等效提交配對。

這裏有一個別名~/.gitconfig去:

dup = "!f() { for c in $(git rev-list HEAD); do git diff-tree -p $c | git patch-id; done | perl -anle '($p,$c)[email protected];print \"$c $s{$p}\" if $s{$p};$s{$p}=$c' | xargs -L 1 git show -s --oneline; }; f" # "git dup" lists duplicate commits 
0

要搜索提交$hash重複提交,但不包括合併提交:

git rev-list --no-merges --all | xargs -r git show | git patch-id \ 
    | grep ^$(git show $hash|git patch-id|cut -c1-40) | cut -c42-80 \ 
    | xargs -r git show -s --oneline 

搜索合併的提交$mergehash重複,替代上面的$(git show $hash|git patch-id|cut -c1-40)git diff-tree -m -p $mergehash | git patch-id給出的兩個補丁ID之一(第1列)。它們對應於兩個父母中的每一個的合併提交的差異。

要查找所有提交的副本,不包括合併提交:

git rev-list --no-merges --all | xargs -r git show | git patch-id \ 
    | sort | uniq -w40 -D | cut -c42-80 \ 
    | xargs -r git log --no-walk --pretty=format:"%h %ad %an (%cn) %s" --date-order --date=iso 

重複提交搜索可以擴展或改變參數git rev-list,它接受了大量的選項有限。例如,要將搜索限制到特定分支,請指定其名稱,而不是選項--all;或者在最近的100次提交中搜索傳遞參數HEAD ^HEAD~100

請注意,這些命令是快速的,因爲它們不使用shell循環和批處理提交。

要包含合併提交,請刪除選項--no-merges,並用xargs -r -L1 git diff-tree -m -p替換xargs -r git show。這要慢得多,因爲每提交一次就會執行一次git diff-tree

說明:

  • 第一行產生圖補丁ID的與提交一個散列(2列數據的各40個字符)。

  • 第二行只保留與重複的修補程序ID(第1列)相對應的提交哈希(第2列)。

  • 最後一行輸出有關重複提交的自定義信息。