Ich habe also die Frage gefunden, wie der Änderungsverlauf einer Datei angezeigt werden soll, aber der Änderungsverlauf dieser bestimmten Datei ist riesig und ich bin wirklich nur an den Änderungen einer bestimmten Methode interessiert. Wäre es also möglich, den Änderungsverlauf nur für diese bestimmte Methode anzuzeigen?
Ich weiß, dass dies Git erfordern würde, um den Code zu analysieren, und dass die Analyse für verschiedene Sprachen unterschiedlich wäre, aber Methoden- / Funktionsdeklarationen sehen in den meisten Sprachen sehr ähnlich aus, daher dachte ich, dass möglicherweise jemand diese Funktion implementiert hat.
Die Sprache, mit der ich derzeit arbeite, ist Objective-C, und das SCM, das ich derzeit verwende, ist git. Es würde mich jedoch interessieren, ob diese Funktion für SCM / Sprache vorhanden ist.
Antworten:
Neuere Versionen haben
git log
eine spezielle Form des-L
Parameters gelernt :Mit anderen Worten: Wenn Sie Git darum bitten
git log -L :myfunction:path/to/myfile.c
, wird der Änderungsverlauf dieser Funktion nun gerne gedruckt.quelle
Die Verwendung
git gui blame
ist in Skripten schwer zu verwenden, und obwohlgit log -G
undgit log --pickaxe
kann Ihnen jeweils zeigen, wann die Methodendefinition angezeigt oder verschwunden ist, habe ich keine Möglichkeit gefunden, sie dazu zu bringen, alle Änderungen aufzulisten, die am Hauptteil Ihrer Methode vorgenommen wurden.Sie können jedoch
gitattributes
und dietextconv
Eigenschaft verwenden, um eine Lösung zusammenzusetzen, die genau das tut. Obwohl diese Funktionen ursprünglich dazu gedacht waren, Ihnen bei der Arbeit mit Binärdateien zu helfen, funktionieren sie hier genauso gut.Der Schlüssel ist, dass Git alle Zeilen außer denen, an denen Sie interessiert sind, aus der Datei entfernt, bevor Sie Diff-Operationen ausführen. Dann
git log
wirdgit diff
usw. nur der Bereich angezeigt, an dem Sie interessiert sind.Hier ist der Überblick darüber, was ich in einer anderen Sprache mache. Sie können es für Ihre eigenen Bedürfnisse optimieren.
Schreiben Sie ein kurzes Shell-Skript (oder ein anderes Programm), das ein Argument verwendet - den Namen einer Quelldatei - und nur den interessanten Teil dieser Datei ausgibt (oder nichts, wenn nichts davon interessant ist). Sie können
sed
beispielsweise Folgendes verwenden:Definieren Sie einen Git-
textconv
Filter für Ihr neues Skript. (gitattributes
Weitere Informationen finden Sie in der Manpage.) Der Name des Filters und die Position des Befehls können beliebig sein.Weisen Sie Git an, diesen Filter zu verwenden, bevor Sie Differenzen für die betreffende Datei berechnen.
Nun, wenn Sie verwenden
-G.
( man beachte die.
) alle Commits aufzulisten , die sichtbaren Veränderungen erzeugen , wenn der Filter angewendet wird, haben Sie genau die Commits , dass Sie daran interessiert sind. Jede andere Optionen , die Git Diff - Routinen zu verwenden, wie zum Beispiel--patch
, wird erhalten Sie auch diese eingeschränkte Ansicht.Voilà!
Eine nützliche Verbesserung, die Sie möglicherweise vornehmen möchten, besteht darin, dass Ihr Filterskript einen Methodennamen als erstes Argument (und die Datei als zweites) verwendet. Auf diese Weise können Sie eine neue Methode von Interesse angeben, indem Sie einfach aufrufen
git config
, anstatt Ihr Skript bearbeiten zu müssen. Zum Beispiel könnten Sie sagen:Natürlich kann das Filterskript alles tun, was Sie wollen, mehr Argumente annehmen oder was auch immer: Es gibt viel Flexibilität, die über das hinausgeht, was ich hier gezeigt habe.
quelle
Git Log hat die Option '-G', um alle Unterschiede zu finden.
Geben Sie ihm einfach eine korrekte Regex des Funktionsnamens, den Sie interessieren. Beispielsweise,
quelle
--oneline
mit-p
Das Nächste, was Sie tun können, ist, die Position Ihrer Funktion in der Datei zu bestimmen (z. B. sagen wir, Ihre Funktion
i_am_buggy
befindet sich in den Zeilen 241 bis 263 vonfoo/bar.c
), und dann Folgendes auszuführen:Dadurch wird weniger geöffnet (oder ein gleichwertiger Pager). Jetzt können Sie
/i_am_buggy
(oder Ihr Pager-Äquivalent) eingeben und die Änderungen schrittweise durchführen.Dies kann je nach Codestil sogar funktionieren:
Dies begrenzt die Suche vom ersten Treffer dieser Regex (idealerweise Ihrer Funktionsdeklaration) auf dreißig Zeilen danach. Das Endargument kann auch ein regulärer Ausdruck sein, obwohl es eine zweifelhaftere Aussage ist , dies mit regulären Ausdrücken zu erkennen.
quelle
-L ":int myfunc:foo/bar.c"
und sich auf die Funktion mit diesem Namen beschränken. Das ist fantastisch - danke für den Zeiger! Wenn nur die Funktionserkennung etwas zuverlässiger wäre ...Der richtige Weg ist,
git log -L :function:path/to/file
wie in eckes Antwort erklärt zu verwenden .Wenn Ihre Funktion jedoch sehr lang ist, möchten Sie möglicherweise nur die Änderungen sehen, die verschiedene Commits eingeführt haben, nicht die gesamten Funktionszeilen, die unverändert enthalten sind, für jedes Commit, das möglicherweise nur eine dieser Zeilen berührt. Wie ein normaler
diff
tut.Normalerweise
git log
können Unterschiede mit angezeigt werden-p
, dies funktioniert jedoch nicht-L
. Sie müssen alsogrep
git log -L
nur die beteiligten Zeilen und den Header für Commits / Dateien anzeigen, um sie zu kontextualisieren. Der Trick hier besteht darin, nur terminale farbige Linien, die einen--color
Schalter hinzufügen , mit einem regulären Ausdruck abzugleichen. Schließlich:Beachten Sie, dass
^[
dies tatsächlich wörtlich sein sollte^[
. Sie können sie eingeben, indem Sie ^ B ^ [in Bash drücken, dh Ctrl+ V, Ctrl+ [. Referenz hier .Mit dem letzten
-3
Schalter können vor und nach jeder übereinstimmenden Zeile 3 Zeilen des Ausgabekontexts gedruckt werden. Möglicherweise möchten Sie es an Ihre Bedürfnisse anpassen.quelle
Git Schuld zeigt Ihnen, wer zuletzt jede Zeile der Datei geändert hat; Sie können die zu untersuchenden Zeilen angeben, um zu vermeiden, dass der Verlauf von Zeilen außerhalb Ihrer Funktion angezeigt wird.
quelle
git gui blame
Sie ältere Revisionen navigieren.Funktionsverlauf anzeigen
git log -L :<funcname>:<file>
wie in eckes 'Antwort und Git-Dokument gezeigtWenn nichts angezeigt wird, lesen Sie Definieren eines benutzerdefinierten Hunk-Headers , um
*.java diff=java
der.gitattributes
Datei etwas hinzuzufügen , das Ihre Sprache unterstützt.Funktionsverlauf zwischen Commits mit anzeigen
git log commit1..commit2 -L :functionName:filePath
Zeigen Sie den überladenen Funktionsverlauf an (es kann viele Funktionen mit demselben Namen, aber unterschiedlichen Parametern geben) mit
git log -L :sum\(double:filepath
quelle