2013-03-15 14 views
7

Chciałbym, aby wyniki git diff były filtrowane według nazwy pliku.git diff filtrowane według nazwy pliku

W szczególności chcę diff dla wszystkich plików o nazwie "AssemblyInfo.cs", ale znajduje się w dowolnym miejscu w repozytorium git.

Używam git na Cygwin, jeśli to robi różnicę.

Odpowiedz

9

argumenty plik do git diff muszą być ograniczone przez -- - spróbuj tego:

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

xargs sprawia pewien, że spacje, tabulatory, znaki nowej linii, itp są prawidłowo obsługiwane.

Można debugować go argumentem --name-status na git diff. Można też spróbować:

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

[edytuj] Spróbuj:

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

Wydaje się to robić tak samo jak 'git diff', ale pozostawia ostatni plik. – Zantier

+0

Być może ostatni plik się nie zmienił. Proszę debugować z moimi sugestiami powyżej. Jeśli nadal nie jest jasne, opublikuj wyniki moich sugestii debugowania w oryginalnym pytaniu. – GoZoner

+0

'git diff - only-only | grep AssemblyInfo.cs' rzeczywiście podaje poprawne nazwy plików, jak przypuszczam, ale potrzebuję pełnego wyjścia diff. Zarówno 'find. -name AssemblyInfo.cs | xargs git diff - 'and' find. -name AssemblyInfo.cs | xargs git diff --name-status - 'daje pliki, które nie są" AssemblyInfo.cs "(takie jak pliki .sql). – Zantier

0

Można użyć pipeline

find . -name AssemblyInfo.cs | git diff 

Korzystając find filtrować wszystkie pliki o nazwie „AssemblyInfo.cs”, a następnie użyć wyjścia jako parametr git diff.

+1

Wydaje się, że to nie jest filtrowanie różnic. Zrobiłem linijkę, żeby sprawdzić: '$ git diff | wc -l $ znajdź. -name AssemblyInfo.cs | git diff | wc -l 1110' – Zantier

+0

@ Zantier, co jest wynikiem działania 'find. -name AssemblyInfo.cs'? – pktangyue

+0

'znajdź. -name AssemblyInfo.cs' działa poprawnie, podając ścieżki do wszystkich plików "AssemblyInfo.cs". – Zantier

0

While the answer given by GoZoner prace dla niektórych (? sto) plików, wykonuje git diff wiele razy (w przypadku xargs) lub nie (w przypadku git diff … -- `find …`), jeśli istnieje duża liczba plików do odfiltrowania. Może to stanowić problem, w zależności od przypadku użycia.

Możliwe rozwiązanie to utworzenie zatwierdzenia zawierającego tylko zmiany interesujących plików i porównanie zatwierdzeń. Na podstawie an answer on unstaging files matching some pattern wymyśliłem tego rozwiązania:

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

Teraz git status --porcelain | grep <pattern> pokazuje wszystkie pliki, które powinny być porównywane. Wszystkie inne pliki można wyświetlić, przekazując -v do grep, tj. git status --porcelain | grep -v <pattern>. Te pliki muszą być przywrócone do stanu <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 -- 

(. Należy pamiętać, że stosując xargs nie jest problemem w tym przypadku, jak dzwoni git rm i git checkout wielokrotnie jest ok)

teraz indeksu (i kopia robocza) zawiera tylko zmiany w plikach dopasowanych przez <pattern>. Następną rzeczą do zrobienia jest zatwierdzenie tych zmian:

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

To wszystko! Teraz możemy użyć git diff jak zwykle:

git diff HEAD^..HEAD 

Można użyć wszystkich opcji i argumentów, które lubisz.

Uwaga: to rozwiązanie nie jest szeroko testowane i może się nie udać, np.na plikach ze znaków specjalnych lub innych szczególnych przypadkach ... Propozycje poprawy rozwiązania są mile widziane ;-)

1

Najprostszym sposobem jest po prostu użyć symbolu wieloznacznego:

git diff -- *AssemblyInfo.cs 


Przynajmniej to działa na moim Git v1.8.4.

+0

nie można ograniczyć ścieżką w ten sposób – user1133275

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

można zastąpić AssemblyInfo\.cs swoim regex.