2013-03-15 91 views
7

我希望git diff的結果可以按文件名過濾。通過文件名篩選的git diff

特別是,我想爲所有名爲「AssemblyInfo.cs」的文件比較diff,但它位於git存儲庫中的任何位置。

我在Cygwin上使用git,如果這有所作爲。

回答

9

文件參數git diff需要由--分隔 - 試試這個:

find . -name <pattern> | xargs git diff -- 

xargs的確保空格,製表符,換行符等正確處理。

您可以使用--name-status參數調試git diff。您也可以嘗試:

git diff --name-only | grep <pattern> 

[編輯]嘗試:

git diff --name-status -- `find . -name '<pattern>'` 
[email protected](98)$ git diff --name-status -- `find . -name '*.scm'` 
M  scheme/base/boolean.scm 
M  surf/compiler/common.scm 
M  surf/compiler/compile.scm 
M  surf/compiler/expand.scm 
+0

這似乎與'git diff'相同,但是遺漏了最後一個文件。 – Zantier 2013-03-15 18:25:37

+0

也許最後一個文件沒有改變。請根據我的建議進行調試。如果還不清楚,請在原始問題中發佈我的調試建議的輸出。 – GoZoner 2013-03-15 18:31:33

+0

'git diff --name-only | grep AssemblyInfo.cs'確實提供了正確的文件名,正如我所料,但我需要全差分輸出。兩個'找到。名稱AssemblyInfo.cs | xargs git diff --'和'find。名稱AssemblyInfo.cs | xargs git diff --name-status --'給出的文件不是「AssemblyInfo.cs」(如.sql文件)。 – Zantier 2013-03-19 09:36:50

0

您可以使用pipeline

find . -name AssemblyInfo.cs | git diff 

使用find過濾所有名爲「的AssemblyInfo.cs」的文件,然後使用輸出爲git diff參數。

+1

這似乎並沒有過濾差異。我做了線計數只是爲了檢查: '$ git diff | wc -l $ find。名稱AssemblyInfo.cs | git diff | wc -l 1110' – Zantier 2013-03-15 18:03:42

+0

@Zantier find的輸出是什麼。名稱AssemblyInfo.cs'? – pktangyue 2013-03-15 18:05:02

+0

'發現。名稱AssemblyInfo.cs工作正常,給所有「AssemblyInfo.cs」文件提供路徑。 – Zantier 2013-03-15 18:06:02

0

雖然the answer given by GoZoner作品一些(?百)文件,它執行git diff多次(在xargs的情況下)或失敗(在git diff … -- `find …`的情況下)如果有大量文件需要比較。根據您的使用情況,這可能是個問題或不是問題。

一個可能的解決方案是創建一個只包含對感興趣文件的更改並區分提交的提交。基於an answer on unstaging files matching some pattern我想出了這個解決方案:

git co <new_branch> --detach 
git reset --soft <old_branch> 

現在git status --porcelain | grep <pattern>表明,應該比較的所有文件。所有其他文件可以通過傳遞-vgrep,即git status --porcelain | grep -v <pattern>來列出。該文件需要重置爲<old_branch>狀態:

# Remove the destination of renamed and copied files not matching <pattern> 
git status --porcelain | grep -v <pattern> | grep '^R \|^C ' | sed 's/.* -> //' | xargs git rm -f -- 
# Remove added files not matching <pattern> 
git status --porcelain | grep -v <pattern> | grep '^A ' | cut -c 4- | xargs git rm -f -- 
# Restore deleted files not matching <pattern> 
git status --porcelain | grep -v <pattern> | grep '^M \|^D ' | cut -c 4- | xargs git checkout HEAD -- 

(請注意,使用xargs是不是在這種情況下一個問題,因爲調用git rmgit checkout多次是確定)

現在指數(和工作副本)僅包含對<pattern>匹配的文件的更改。接下來要做的是做出這樣的改變:

git commit -m "Changes between <old_branch> and <new_branch> in files matching <pattern>" 

就是這樣!現在我們可以像往常一樣使用git diff

git diff HEAD^..HEAD 

您可以使用您喜歡的所有選項或參數。

注意:此解決方案未經過廣泛測試,可能會失敗,例如,對有特殊字符或其他特殊情況下的文件...建議改進解決方案,歡迎;-)

1

最簡單的方法是簡單地使用通配符:

git diff -- *AssemblyInfo.cs 


至少這個工作對我的Git v1.8.4。

+0

你不能通過這樣的路徑來限制 – user1133275 2015-11-05 21:02:13

0
find . -iregex AssemblyInfo\.cs -exec git diff {} + 

你可以用你的正則表達式替換AssemblyInfo\.cs