Git: Zeigt alle verschiedenen Änderungen an einer einzelnen Zeile in einer angegebenen Datei über den gesamten Git-Verlauf an

112

Ich habe mich umgesehen und bin mir nicht sicher, ob dies möglich ist, aber hier ist:

Ich habe eine (Javascript-) Datei (z. B. /lib/client.js), in der einer Variablen eine eindeutige Kennung zugewiesen ist: var identifier = "SOME_IDENTIFIER";

Sie können sich den Bezeichner wie eine Versionsnummer vorstellen: In regelmäßigen Abständen ändern wir diese Variable in einen neuen Bezeichner.

Ich möchte alle eindeutigen Kennungen finden, die wir jemals verwendet haben. Wie kann ich das mit git machen?

Ich kann mir vorstellen, dass es eine Möglichkeit gibt, den Git-Verlauf zu durchsuchen und den Zeilenabgleich auszudrucken "var identifier =". Ich könnte diese Liste manuell löschen.

Jedenfalls würde ich mich über jeden Einblick hier freuen. Vielen Dank.

findchris
quelle

Antworten:

106

Seit Git 1.8.4 gibt es eine direktere Möglichkeit, Ihre Frage zu beantworten.

Angenommen, diese Zeile 110ist die Zeile, die sagt var identifier = "SOME_IDENTIFIER";, dann tun Sie dies:

git log -L110,110:/lib/client.js

Dies gibt jedes Commit zurück, das diese Codezeile berührt hat.

[ Git-Dokumentation (siehe Befehlszeilenparameter "-L")]

Alexander Bird
quelle
49

Siehe die Manpage für git-logund gitdiffcore. Ich glaube, dieser Befehl würde es tun, aber es könnte nicht ganz richtig sein:

git log -G "var identifier =" file.js

BEARBEITEN: Hier ist ein grober Anfang für ein Bash-Skript, um die tatsächlichen Zeilen anzuzeigen. Dies könnte mehr sein, wonach Sie suchen.

for c in $(git log -G "something" --format=%H -- file.js); do
    git --no-pager grep -e "something" $c -- file.js
done

Es wird verwendet git log -G, um die interessanten Commits --format=%Hzu finden und eine Liste von Commit-Hashes zu erstellen. Anschließend wird jedes interessante Commit wiederholt git grep, wobei die Zeilen aus diesem Commit und der Datei angezeigt werden, die den regulären Ausdruck enthalten, dem der Commit-Hash vorangestellt ist.


BEARBEITEN: Geändert zur Verwendung -Ganstelle der -Sin den Kommentaren vorgeschlagenen.

rauben
quelle
@Rob - danke dafür - kleine Änderung an Ihrem Skript - wenn Sie nur den Dateinamen eingeben, werden nur Commits angezeigt, die nur diese Datei betreffen - wenn ein Commit auf andere Dateien verweist, wird es nicht aufgeführt
Adrian Cornish
@AdrianCornish - Ich bin froh, dass es hilfreich war. Ich denke, das OP wollte sich nur eine Datei ansehen, aber Sie haben völlig Recht, dass das Entfernen des Dateinamens wahrscheinlich ein allgemein nützlicheres Skript ist.
Rob
Ich habe eine schwierigere Situation. Die betreffende Datei wurde von paht_a / file nach path_b / file verschoben. Wenn ich es jetzt in path_b mache, werden nur Änderungen angezeigt, bis die Datei von path_a nach path_b verschoben wird. Wenn ich es in path_a mache, sagt es mir fatal: mehrdeutiges Argument 'file': unbekannte Revision oder Pfad nicht im Arbeitsbaum.
Andy Song
@AndySong - Wenn die gesuchte Zeichenfolge eindeutig genug ist, können Sie den Dateinamen einfach weglassen und trotzdem das bekommen, wonach Sie suchen.
Rob
War für mich bequemer - setzen Sie nach jedem Commit eine leere Zeile, zählen Sie die Zeilen auf:sfile=path/to/some_file; sfind='string_to_find'; for c in $(git log -G $sfind --format=%H -- $sfile); do git --no-pager grep -e $sfind -n $c -- $sfile; echo; done
John_West
14

Sie können dies auch mit gitk tun:

gitk file.js

Wählen Sie in der Dropdown-Liste "Festschreiben" die Option "Zeichenfolge hinzufügen / entfernen:" und geben Sie im Textfeld daneben "var identifier =" ein. Alle Festschreibungen, die Zeilen hinzufügen oder entfernen, die diese Zeichenfolge enthalten, werden hervorgehoben.

Ethan Brown
quelle
Dies half dabei, das Commit zu bestimmen, bei dem die Zeile mit "var identifier =" hinzugefügt wurde, zeigt jedoch keine nachfolgenden Commits an, die diese Zeile geändert haben.
Findchris
2
Hast du es versucht git blame file.jsoder git gui blame file.js?
Ethan Brown
1
Ich weiß, was Git-Schuld tut; Ich suche nach einer vollständigen Geschichte der Überarbeitungen, nicht nach einem einzigen Unterschied.
Findchris
1
git gui blame file.jswird das tun ... es zeigt Ihnen alle Revisionen einer Datei und wer sie geändert hat; Sie können einfach rückwärts durch den Verlauf klicken.
Ethan Brown
Am Ende bin ich mit gitk visuell durchgegangen. Ich stelle mir vor, dass es dafür eine elegante Git-Technik gibt, aber Gitk war gut genug. Vielen Dank.
Findchris
9

Wenn Sie die Antwort von @ rob nur ein wenig anpassen, git logwird dies im Grunde genommen für Sie erledigt, wenn Sie nur einen visuellen Vergleich benötigen:

git log -U0 -S "var identifier =" path/to/file

-U0 bedeutet Ausgabe im Patch-Modus (-p ) und zeigt keine Kontextlinien um den Patch.

Sie können dies sogar branchenübergreifend tun:

git log -U0 -S "var identifier =" branchname1 branchname2 -- path/to/file

Es gibt vielleicht eine Möglichkeit, den Diff-Header zu unterdrücken, aber ich kenne keine.

Andrew
quelle
Hat für mich gearbeitet! Vielen Dank.
Roberto Bonini
3

In magit können Sie dies mit tun

l, =L

Sie werden dann nach Datei und Start- und Endzeilen gefragt.

Slumos
quelle