2010-12-10 13 views
353

git blame eignet sich hervorragend für modifizierte und hinzugefügte Zeilen, aber wie kann ich feststellen, wenn eine Zeile, die in einem bestimmten früheren Commit vorhanden war, schließlich gelöscht wurde. Ich denke bisect, aber ich hoffte auf etwas handlicheres.Wie kann ich eine gelöschte Zeile "schuldigen"?

[bevor Sie fragen: in dem Fall, ich habe gerade eine git log -p und suchten nach der Codezeile durch und (a) hatte irgendein Idiot nur die Lebenslinie im vorherigen gelöscht begehen und (b) Ich war, dass Idiot]

+3

Es gibt ein [followup] (http: // stackoverflow.com/q/12591247/923794) mit einer Antwort klarstellen, dass 'git log -S /Pfad/zu/Datei' will ein '-c' oder' -cc' auch Umzüge während der Zusammenführung anzeigen (Konflikte) – cfi

+2

Es sollte sei '-c' und' -cc'. @Steen: Richtig, danke fürs Hinzeigen! Dumme Aufsicht. Ich wünschte, ich könnte den Kommentar bearbeiten. Hinzufügen eines neuen, dann löschen meine, dann löschen Sie Ihre ist alles zu umständlich, denke ich :) – cfi

+3

Ich möchte 'git Schuld 'würde eine Option haben, um gelöschte Zeilen (mit vielleicht [durchgestrichen] (http://stackoverflow.com) zeigen/q/8357203/60075) oder rot) mit der Revision, in der sie gelöscht wurden. –

Antwort

436

Wenn Sie den Inhalt der Linie wissen, ist dies ein idealer Anwendungsfall für:

git log -S <string> path/to/file 

, die zeigt Ihnen zusagt, einführen oder eine Instanz dieser Zeichenfolge entfernen. Es gibt auch die -G<regex>, die das Gleiche mit regulären Ausdrücken macht! Siehe man git-log und suchen Sie nach den Optionen -G und -S, oder Spitzhacke (der Anzeigename für diese Funktionen) für weitere Informationen.

Die -S Option wird tatsächlich in der Kopfzeile der git-blame Manpage auch im Abschnitt Beschreibung erwähnt, wo es ein Beispiel mit git log -S... gibt.

+0

Brilliant ... genau das, was ich in diesem Portierungsjob brauchte Ich arbeite an +1 – jkp

+19

Nachdem ich Git für 1+ Jahre benutzt habe, erstaunt es mich immer wieder zu sehen, dass Git * immer * einen Befehl/eine Option irgendwo hat, um fast alle anzusprechen Nutzungsszenario habe ich. Danke für das Teilen, es ist genau das, was ich jetzt brauche! –

+16

Diese Methode hat für mich schon früher funktioniert, aber gerade jetzt habe ich einen Fall gesehen, in dem das Commit, bei dem die Zeile gelöscht wurde, nicht gefunden wurde. Es stellte sich heraus, dass die betreffende Zeile in einem Merge-Commit gelöscht wurde - würde das den Fehler erklären? (Die 'git blame --reverse' Methode hat es allerdings gefunden.) – antinome

100

Ich denke, was Sie wirklich wollen,

git blame --reverse START..END filename 

Von the manpage ist:

Weg Geschichte vorwärts statt rückwärts. Anstatt die Revision anzuzeigen, in der eine Zeile angezeigt wurde, wird die letzte Revision angezeigt, in der eine Zeile existiert hat. Dies erfordert eine Reihe von Überarbeitungen wie START..END, wo der Pfad, den man beschuldigen soll, in START existiert.

Mit git blame reverse, können Sie die letzte finden die Linie verpflichten erschien in. Sie müssen noch die commit zu bekommen, dass nach kommt.

Sie können den folgenden Befehl verwenden, um ein umgekehrtes Git-Protokoll anzuzeigen. Das erste Commit, das angezeigt wird, ist das letzte Mal, dass diese Zeile angezeigt wird, und das nächste Commit wird sein, wenn es geändert oder entfernt wird.

git log --reverse --ancestry-path COMMIT^..master 
+9

Wenn es mehrere Zusammenführungen von der Verzweigung gibt, wo die Zeile in den Zweig eingefügt wurde, wo die Zeile fehlt (oder irgendeinen anderen Fall, wo es mehrere Pfade in der Zeile von START bis ENDE gibt), wird 'git tarn --reverse' angezeigt die Revision vor der Zusammenführung, die chronologisch zuletzt war, nicht die Revision vor der ursprünglichen Zusammenführung, bei der die Entscheidung getroffen wurde, die Zeile nicht zu übernehmen. Gibt es eine Möglichkeit, die früheste Revision zu finden, bei der die Linie nicht existierte, sondern die bestehende? – rakslice

+1

@rakslice, dafür können Sie Schuld --reverse --first-parent verwenden, es ist etwas besser. – max630

5

git Schuld --reverse können Sie schließen erhalten, wo die Linie gelöscht. Aber es tatsächlich nicht Punkt auf die Revision, wo die Zeile gelöscht wird. Es zeigt auf die letzte Revision, wo die Linie war vorhanden. Dann, wenn die folgende Revision eine Plain-Commit ist, haben Sie Glück und Sie haben die Lösch-Revision. OTOH, wenn die folgende Revision ist ein merge Commit, dann können die Dinge ein wenig wild werden. Als Teil der Bemühungen, difflame zu erstellen, habe ich dieses Problem angegangen, wenn Sie bereits Python auf Ihrer Box installiert haben und Sie bereit sind, es zu versuchen, dann warten Sie nicht länger und lassen Sie mich wissen, wie es geht.

https://github.com/eantoranz/difflame

Verwandte Themen