git log -G<regex> -p
ist ein wunderbares Werkzeug, um den Verlauf einer Codebasis nach Änderungen zu durchsuchen, die dem angegebenen Muster entsprechen. Es kann jedoch überwältigend sein, das relevante Stück in der Diff / Patch-Ausgabe in einem Meer von größtenteils irrelevanten Stücken zu lokalisieren.
Es ist natürlich möglich, die Ausgabe von git log
nach der ursprünglichen Zeichenfolge / Regex zu durchsuchen , aber dies trägt wenig dazu bei, das visuelle Rauschen und die Ablenkung vieler nicht zusammenhängender Änderungen zu verringern.
Beim Nachlesen git log
sehe ich --pickaxe-all
, dass es das genaue Gegenteil von dem gibt, was ich möchte: Es erweitert die Ausgabe (auf den gesamten Änderungssatz), während ich sie beschränken möchte (auf den bestimmten Teil).
Im Grunde bin ich auf der Suche nach einer Möglichkeit, das Diff / Patch "intelligent" in einzelne Hunks zu zerlegen und dann eine Suche für jeden Hunk durchzuführen (nur auf die geänderten Zeilen abzielen), die nicht übereinstimmenden Hunks zu verwerfen und die auszugeben das tun.
Gibt es ein Tool wie ich es beschreibe? Gibt es einen besseren Ansatz, um die passenden / betroffenen Kerle zu finden?
Erste Recherchen, die ich gemacht habe ...
Wenn es möglich wäre,
grep
die Diff- / Patch-Ausgabe zu ändern und die Kontextoptionswerte dynamisch zu gestalten, z. B. über reguläre Ausdrücke anstelle von Zeilenzahlen, könnte dies ausreichen. Istgrep
aber nicht genau so aufgebaut (und fordere diese Funktion auch nicht unbedingt an).Ich fand die Patchutils- Suite, die anfangs so klang, als würde sie meinen Bedürfnissen entsprechen. Nach dem Lesen der
man
Seiten scheinen die Tools jedoch keine passenden Hunks zu verarbeiten, die auf regulären Ausdrücken basieren. (Sie können jedoch eine Liste von Kerlen akzeptieren ...)Ich bin schließlich auf splitpatch.rb gestoßen , das das Parsen des Patches gut zu handhaben scheint, aber es müsste erheblich erweitert werden, um das Lesen von Patches über
stdin
, das Zuordnen gewünschter Hunks und das anschließende Ausgeben der Hunks zu handhaben .
Antworten:
Hier wird unter /programming//a/35434714/5305907 beschrieben, wie Sie das tun können, wonach Sie suchen. effektiv:
git diff -U1 | grepdiff 'console' --output-matching=hunk
Es werden nur die Hunks angezeigt, die mit der angegebenen Zeichenfolge "console" übereinstimmen.
quelle
grepdiff
ist im Grunde das, was ich will; Ich muss seine Hunk-Matching-Option verpasst haben! Allerdings wird die Git-Commit-Information von entfernt.grepdiff
Wenn Sie also den entsprechenden Block gefunden haben, müssen Sie das Commit-Sha vom Objekt / Blob-Sha im Diff-Header ableiten - eine ziemlich teure Operation. (siehe stackoverflow.com/a/223890/2284440 ) Es wäre so etwas wiegit find-object SHA --reverse | head -1 | cut -c 1-7 | { read sha ; git log -1 $sha; }
grepdiff
die mehr Barebones in Bezug auf akzeptierte Argumente bietet. Beachten Sie, dass, wenn das übereinstimmende Stück das letzte Stück in einem Diff ist, es fälschlicherweise den Git-Commit-Header des folgenden Commits enthält - etwas, das mich völlig verwirrte, bis ich realisierte, was los ist!Nicht genau das, wonach Sie fragen, aber eine Möglichkeit, durch Hunks zu blättern, ist der interaktive Add-Modus. Dies erfordert, dass Sie das Commit nach dem Patch, an dem Sie interessiert sind, auschecken
Gehen Sie dann im VCS noch einen Schritt zurück, jedoch nicht im Arbeitsverzeichnis
(An dieser Stelle entspricht der Unterschied zwischen dem Index und dem Arbeitsverzeichnis dem Patch, an dem Sie interessiert sind.)
Sie können jetzt ausführen
git add -p
. Dies startet eine interaktive Sitzung mit einer/
Option, mit der Sie nach Hunks suchen können, in denen einige Zeilen mit einem regulären Ausdruck übereinstimmen. Besonders nützlich, wenn Sie diese Patches tatsächlich weiterverarbeiten möchten (wie das Vorbereiten eines Teil-Cherry-Pick).Leider funktioniert der
/
Befehl imadd -p
Moment nur innerhalb einer einzelnen Datei, so dass Sie möglicherweise mehrere nicht relevante Dateien überspringen müssen.quelle
Aufbauend auf der obigen Antwort von @nagu und den anderen verknüpften Antworten konnte ich
git log -G
nur die relevanten Hunks anzeigen.Erstelle zuerst irgendwo in deinem $ PATH ein Skript mit folgendem Inhalt:
Rufen
git log -G
Sie Git auf und weisen Sie ihn an, daspickaxe-diff
Skript als externen Diff-Treiber zu verwenden:Dabei wird das Skript pickaxe-diff nur zum Generieren der Diffs verwendet, sodass der Rest der
git log
Ausgabe (Commit-Hash, Nachricht usw.) unberührt bleibt.Vorsichtsmaßnahme
Die Arbeitsweise der Git-Spitzhacke besteht darin, dass sie die Ausgabe auf die Dateien beschränkt, deren Hunks die angegebene Zeichenfolge / Regex ändern. Dies bedeutet, dass, wenn ein anderer Block in diesen Dateien auch die Suchzeichenfolge / Regex enthält, diese jedoch nicht ändert, diese weiterhin mit dem obigen Skript angezeigt wird. Dies ist eine Einschränkung von grepdiff. Es gibt eine Open Pull-Anforderung im Patchutils-Projekt, um grepdiff ein
--only-matching
Flag hinzuzufügen, das die erforderliche Funktionalität zum korrekten Herausfiltern dieser Hunks bietet.Ich habe meine Lösung in diesem Kern geschrieben .
quelle