2013-03-15 16 views
7

Ich möchte die Ergebnisse von git diff durch den Dateinamen gefiltert werden.git diff gefiltert nach Dateiname

Insbesondere möchte ich eine diff für alle Dateien mit dem Namen "AssemblyInfo.cs", aber irgendwo innerhalb der Git-Repository.

Ich benutze git auf Cygwin, wenn das einen Unterschied macht.

Antwort

9

Datei Argumente git diff müssen durch -- begrenzt werden - versuchen Sie dies:

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

xargs stellt sicher, Leerzeichen, Tabulatoren, Zeilenumbrüche usw. korrekt behandelt werden.

Sie könnten es mit dem --name-status Argument zu git diff debuggen. Sie könnten auch versuchen:

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

[Bearbeiten] Versuchen:

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

Dies scheint das gleiche zu tun wie 'git diff', lässt aber die letzte Datei aus. – Zantier

+0

Vielleicht hat sich die letzte Datei nicht geändert. Bitte debugge mit meinen obigen Vorschlägen. Wenn es noch unklar ist, posten Sie die Ausgabe meiner Debug-Vorschläge in Ihrer ursprünglichen Frage. – GoZoner

+0

'git diff - Nur-Name | grep AssemblyInfo.cs' gibt tatsächlich die korrekten Dateinamen, wie ich es erwarte, aber ich brauche volle diff-Ausgabe. Beide finden. -name AssemblyInfo.cs | xargs git diff - 'und' finden. -name AssemblyInfo.cs | xargs git diff --name-status - "gibt Dateien, die nicht" AssemblyInfo.cs "sind (wie .sql-Dateien). – Zantier

0

können Sie pipeline

find . -name AssemblyInfo.cs | git diff 

Verwenden find alle Dateien "AssemblyInfo.cs" genannt filtern verwenden, dann die Ausgabe als Parameter von git diff verwenden.

+1

Dies scheint das Diff nicht zu filtern. Ich habe Zeilen gezählt, nur um zu überprüfen: '$ git diff | wc -l $ finden. -name AssemblyInfo.cs | git diff | wc -l 1110' – Zantier

+0

@Zantier was ist die Ausgabe von 'finden. -name AssemblyInfo.cs'? – pktangyue

+0

'finden. -name AssemblyInfo.cs' funktioniert ordnungsgemäß und gibt die Pfade zu allen "AssemblyInfo.cs" -Dateien an. – Zantier

0

Während the answer given by GoZoner Werke für einige (? Hundert) Dateien, führt er git diff mehrere Male (im Falle von xargs) oder nicht (im Falle von git diff … -- `find …`) wenn es eine große Anzahl von Dateien zu Diff gibt. Dies kann ein Problem sein oder nicht, abhängig von Ihrem Anwendungsfall.

Eine mögliche Lösung besteht darin, ein Commit zu erstellen, das nur Änderungen an interessanten Dateien enthält und die Commits unterscheidet. Basierend auf an answer on unstaging files matching some pattern kam ich mit dieser Lösung:

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

Jetzt git status --porcelain | grep <pattern> alle Dateien angezeigt, die verglichen werden sollen. Alle anderen Dateien können aufgelistet werden, indem -v an grep übergeben wird, d. H. git status --porcelain | grep -v <pattern>. Diese Dateien müssen auf den Zustand der <old_branch> zurückgesetzt werden:

# 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 -- 

(. Beachten Sie, dass xargs verwendet, ist kein Problem in diesem Fall, wie der Aufruf von git rm und git checkout mehrere Male ist ok)

nun der Index (und Arbeitskopie) enthält nur Änderungen an den Dateien, die von <pattern> übereinstimmen. Als nächstes müssen Sie diese Änderungen übernehmen:

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

Das war's! Jetzt können wir git diff wie gewohnt verwenden:

git diff HEAD^..HEAD 

Sie alle Optionen verwenden können, oder Argumente, die Sie mögen.

Hinweis: Diese Lösung wird nicht umfassend getestet und kann z.auf Dateien mit Sonderzeichen oder anderen Sonderfällen ... Vorschläge, die Lösung zu verbessern, sind willkommen ;-)

1

Die einfachste Methode ist einfach einen Platzhalter verwenden:

git diff -- *AssemblyInfo.cs 


Zumindest auf meinem Git arbeitet v1.8.4.

+0

können Sie nicht durch Pfad so begrenzen – user1133275

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

Sie können die AssemblyInfo\.cs durch Ihre Regex ersetzen.

Verwandte Themen