git blame
eignet sich hervorragend für geänderte und hinzugefügte Zeilen. Wie kann ich jedoch feststellen, wann eine Zeile, die in einem bestimmten vorherigen Commit vorhanden war, gelöscht wurde? Ich denke nach bisect
, aber ich hoffte auf etwas Handlicheres.
(Bevor Sie fragen: In diesem Fall habe ich gerade a ausgeführt git log -p
und nach der Codezeile gesucht und (a) ein Idiot hat gerade die wichtige Zeile im vorherigen Commit gelöscht und (b) ich war dieser Idiot.)
git log -S<string> /path/to/file
dass ein-c
oder-cc
auch Entfernungen während der Zusammenführung (Konflikte)-c
und sein--cc
. @Steen: Richtig, danke für den Hinweis! Dummes Versehen. Ich wünschte, ich könnte den Kommentar bearbeiten. Das Hinzufügen eines neuen, dann das Löschengit blame
hätte die Möglichkeit, gelöschte Zeilen (mit möglicherweise durchgestrichenem oder rotem Text) mit der Revision anzuzeigen, in der sie gelöscht wurden.Antworten:
Wenn Sie den Inhalt der Zeile kennen, ist dies ein idealer Anwendungsfall für:
Dies zeigt Ihnen Commits, die eine Instanz dieser Zeichenfolge einführen oder entfernen. Es gibt auch das,
-G<regex>
was dasselbe mit regulären Ausdrücken macht! Sieheman git-log
und die Suche nach den-G
und-S
Optionen oder pickaxe (der Name für diese Funktionen) für weitere Informationen.Die
-S
Option wird auch in der Kopfzeile dergit-blame
Manpage im Beschreibungsabschnitt erwähnt, wo ein Beispiel mit verwendet wirdgit log -S...
.quelle
git blame --reverse
Methode fand es jedoch.)-c
Option zusätzlich, um die Commits aus dem Zusammenführen anzuzeigen .Ich denke, was du wirklich willst, ist
Aus der Manpage :
Mit
git blame reverse
können Sie das letzte Commit finden, in dem die Zeile angezeigt wurde. Sie müssen noch das Commit abrufen, das danach kommt.Mit dem folgenden Befehl können Sie ein umgekehrtes Git-Protokoll anzeigen. Das erste angezeigte Commit ist das letzte Mal, dass diese Zeile angezeigt wird, und das nächste Commit ist, wenn es geändert oder entfernt wird.
quelle
git blame --reverse
wird die Revision vor dem Zusammenführen angezeigt, die chronologisch war Zuletzt nicht die Überarbeitung vor der ersten Zusammenführung, bei der die Entscheidung getroffen wurde, die Linie nicht zu übernehmen. Gibt es eine Möglichkeit, die früheste Revision zu finden, bei der die Leitung nicht mehr existiert, anstatt die letzte?Nur um Cascabels Antwort zu vervollständigen :
Ich hatte das gleiche Problem wie hier erwähnt, aber es stellte sich heraus, dass die Zeile fehlte, da ein Zusammenführungs-Commit von einem Zweig zurückgesetzt und dann wieder zusammengeführt wurde, wodurch die betreffende Zeile effektiv entfernt wurde. Das
--full-history
Flag verhindert das Überspringen dieser Commits.quelle
git Schuld --reverse können Sie erhalten nah an , wo die Linie gelöscht. Es zeigt jedoch nicht auf die Revision, in der die Zeile gelöscht wird. Es zeigt auf die letzte Revision, in der die Linie vorhanden war . Wenn es sich bei der folgenden Revision um ein einfaches Commit handelt, haben Sie Glück und haben die Löschrevision erhalten. OTOH, wenn die folgende Revision ein Merge-Commit ist , können die Dinge ein wenig wild werden.
Als Teil der Bemühungen, Difflame zu erstellen, habe ich genau dieses Problem gelöst. Wenn Sie also Python bereits auf Ihrer Box installiert haben und bereit sind, es auszuprobieren, warten Sie nicht länger und lassen Sie mich wissen, wie es geht.
https://github.com/eantoranz/difflame
quelle
Für Änderungen, die in Merge-Commits versteckt sind
Beim Zusammenführen von Commits werden die Änderungen automatisch in der Git-Protokollausgabe ausgeblendet. Sowohl die Spitzhacke als auch die umgekehrte Schuld fanden die Änderung nicht. Die gewünschte Zeile wurde also hinzugefügt und später entfernt, und ich wollte die Zusammenführung finden, die sie entfernt hat. Der Dateiverlauf
git log -p -- path/file
zeigte nur, dass er hinzugefügt wurde. Hier ist der beste Weg, den ich gefunden habe, um es zu finden:git log -p -U9999 -- path/file
Suchen Sie nach der Änderung und suchen Sie dann rückwärts nach "^ commit" - das erste "^ commit" ist das Commit, bei dem die Datei zuletzt diese Zeile hatte. Das zweite "^ commit" erfolgt nach dem Verschwinden. Das zweite Commit ist möglicherweise dasjenige, das es entfernt hat. Das
-U9999
soll den gesamten Dateiinhalt anzeigen (nach jedem Ändern der Datei), vorausgesetzt, Ihre Dateien bestehen aus maximal 9999 Zeilen.Findet alle zugehörigen Zusammenführungen über Brute Force (differenziert jedes mögliche Zusammenführungs-Commit mit seinem ersten Elternteil, läuft gegen Tonnen von Commits)
git log --merges --pretty=format:"git diff %h^...%h | grep target_text" HEAD ^$(git merge-base A B) | sh -v 2>&1 | less
(Ich habe versucht, den Revisionsfilter stärker einzuschränken, bin jedoch auf Probleme gestoßen und empfehle dies nicht. Die von mir gesuchten Änderungen zum Hinzufügen / Entfernen betrafen verschiedene Zweige, die zu unterschiedlichen Zeiten zusammengeführt wurden und A ... B nicht enthalten waren wann die Änderungen tatsächlich in die Hauptzeile übernommen wurden.)
Zeigen Sie einen Git-Baum mit diesen beiden Commits (und entfernen Sie einen Großteil des komplexen Git-Verlaufs):
git log --graph --oneline A B ^$(git merge-base A B)
(A ist das erste Commit oben, B ist das zweite Commit oben)Zeige die Geschichte von A und die Geschichte von B minus die Geschichte von A und B.
Alternative Version (scheint den Pfad eher linear als den regulären Git-Verlaufsbaum anzuzeigen - ich bevorzuge jedoch den regulären Git-Verlaufsbaum):
Drei, nicht zwei Punkte - drei Punkte bedeuten "r1 r2 - nicht $ (Git-Merge-Basis - alle r1 r2). Dies ist die Menge von Commits, die entweder von r1 (linke Seite) oder r2 (rechts) erreichbar sind Seite), aber nicht von beiden. " - Quelle: "man gitrevisions"
quelle