2013-08-21 9 views
16

Wie der Titel sagt, möchte ich jedes Commit finden, dessen Diff spezifische Zeichenfolge enthält.Zeige alle Commits, deren Diff spezifische Zeichenfolge enthalten

Im Moment benutze ich

git log -p 'filename' 

Welche weniger ähnliche Oberfläche jedes diff zeigt, wo ich für die Zeichenfolge zu suchen. Dann ich zurückverfolgen, um die tatsächlichen Commit-Nachrichten zu finden.

Eine einfache Alternative könnte sein, git log -p in grep zu pipen, aber ich kann die Commit-ID oder Nachricht auf diese Weise nicht finden.

+0

Haben Sie etwas dagegen, die Antworten? Ich glaube, die anderen Antworten sind besser als ein Skript (würde eigentlich eine Zeile sein) und eine liefert eine detailliertere Erklärung. –

Antwort

13

Hier ist ein Einzeiler Shell-Skript (in mehr als eine Zeile für Formatierungszwecke aufgeteilt), die die Rev-Nummern von aktuellen Zweig-erreichbaren Commits affectin extrahiert g path wobei git show -p das angegebene pattern enthält. Es ist nicht perfekt (es wird Commit-Nachrichten sowie Diffs übereinstimmen), aber es sollte einfach sein, wie Sie möchten, von hier aus zu optimieren.

git rev-list HEAD -- path | 
while read rev; do 
    if git show -p $rev | grep pattern >/dev/null; then 
     echo $rev 
    fi 
done 

Beachten Sie, dass git show mit, beispielsweise ersetzen können, git diff $rev^ $rev (beachten Sie, dass diese vergleicht nur gegen First-Eltern, wenn es sich um eine Zusammenführung ist) oder git whatchanged $rev, oder was auch immer Sie mögen. Der Haupttrick besteht darin, mit git rev-list zu beginnen, um alle Kandidaten zu extrahieren (commits, die den gegebenen Pfad beeinflussen; lassen Sie den -- path Teil weg, um alle commits zu erhalten, die von HEAD beginnen). Siehe git-rev-list(1) für viele andere Dinge, die Sie mit git rev-list tun können.

+0

Wenig zu ausführlich, für einen einzigen Liner (normales Szenario, wenn ich dies verwenden muss). Aber es ist eine saubere Lösung und es funktioniert. Ich lasse die Frage für die nächsten 24 Stunden offen, und wenn es keine bessere Lösung gibt, akzeptiere deine. Danke für die Hilfe – bbaja42

1

Wenn Sie auf Linux sind, lenkt sie durch egrep und sucht auf einem regex

git log -p 'filename' | egrep '(yourstring|commit-message)' 
+0

Ja, nette Dea, aber ich sehe den Kontext nicht (welcher Commit war derjenige, der die Änderung hatte). Thnx sowieso. – bbaja42

+0

@ bbaja42 was ist mit egrep? git log -p 'Dateiname' | egrep '(yestring | commit-Nachricht)'. Auf diese Weise werden die Commit-Nachrichten, gefolgt von den geänderten Zeilen, ausgegeben. Um mehr Kontext um Übereinstimmungen zu erhalten, kann das -C-Flag an egrep übergeben werden. – user1333371

+0

Ja, das funktioniert git log -p 'Dateiname' | egrep '(yestring | commit-Nachricht)' | grep -B 1 Yourstring. Dies sollte nur Commit-Nachrichten und 'theString' zeigen, die übereinstimmen – bbaja42

0

Haben Sie ein Rohr und grep Befehl betrachtet verwenden?

Beispiel:

git log -p | grep 'filename' 
+0

Keine schlechte Idee, aber ich brauche wirklich die Commit-Nachricht, damit ich den Kontext dieses Commits bekommen kann. Und da Commits ziemlich groß sein können, kann ich die Option -c von grep nicht wirklich verwenden. – bbaja42

0

Sie git für diese, zum Beispiel verwenden können:

git log --grep="filename" 

Oder auf einer bestimmten Datei:

git log --grep="filename" README 
+0

--grep sucht nur nach Commit-Nachrichten, nicht nach dem tatsächlichen Diff. Basiert auf Git Hilfe log – bbaja42

+0

Ok, versuchen Sie diese git grep 'Dateiname' $ (git rev-list --all) –

20
git log -S'string' 

kann verwendet werden, um nach Commits zu suchen, die eine Zeichenfolge hinzufügen oder entfernen. Es verhält sich nicht genau gleich, da es nur mit Commits übereinstimmt, die tatsächlich eine Instanz des Musters hinzufügen oder entfernen, und nicht (zum Beispiel), wo es im Diff-Kontext auftritt. Aber vielleicht ist das gut genug für dich.

+0

Ja, ich habe es versucht, aber wie du erwähnt hast, zeigt es in meinem Fall nicht alles was ich brauche. Thnx jedenfalls, guter Versuch. – bbaja42

+0

'git log -p -S'String'' – nroose

7

Ich weiß, dass diese Frage schon eine Weile beantwortet wurde, aber ich bin auch auf diese Frage gestoßen und habe eine andere Lösung gefunden, also dachte ich, ich würde sie teilen. Git-log 's -G Schalter sollte tun, was Sie wissen, wo der -S Schalter nur commits ausgeben würde, wo die Anzahl der Vorkommen der übereinstimmenden Zeichenfolge ändert.

Von git-log ‚s Manpage:

-G Blick für Unterschiede, deren Patch-Text enthält hinzugefügt/entfernt Linien übereinstimmen.

Um die Differenz zwischen -S --pickaxe-regex und -G veranschaulichen, eine Festschreibung der folgenden diff in der gleichen Datei betrachten:

+ return !regexec(regexp, two->ptr, 1, &regmatch, 0); 
... 
- hit = !regexec(regexp, mf2.ptr, 1, &regmatch, 0); 

Während git log -G "regexec (Wildcards" werden show this commit, git log -S "regexec (regexp" --pickaxe-regex wird nicht (da sich die Anzahl der Vorkommen dieser Zeichenfolge nicht geändert hat).

Weitere Informationen finden Sie in der Spitzhacke Eintrag in gitdiffcore (7)

+0

Hurra! Vielen Dank! Das funktioniert perfekt für mich. –

+0

Beachten Sie übrigens, dass der Unterschied zwischen diesem eingebauten '-G' (grep for change) und meiner langen" Einzeiler "-Antwort darin besteht, dass dieses spezielle 'regexec'-Vorkommen gefunden wird, aber * nicht * eins das ist nur in dem Kontext, der für einige 'git log-p'-Ausgaben gezeigt wird. Wenn zum Beispiel die Zeile, die geändert wurde, die Zeile * vor * dem Aufruf 'regexec' war, wird 'git log -G' diese Änderung nicht finden, aber die Ausgabe jedes 'git show -p'-Befehls wird gesucht. (Daher hängt es davon ab, was Sie herausfinden möchten, welche Befehle Sie versuchen sollten.) – torek

Verwandte Themen