Git Diff-Datei gegen die letzte Änderung

236

Ist es möglich, git dazu zu bringen, einen Unterschied zwischen einer bestimmten Datei zu erzeugen, wie sie jetzt existiert, und wie sie vor dem letzten Commit existierte, der sie geändert hat?

Das heißt, wenn wir wissen:

$ git log --oneline myfile
123abc Fix some stuff
456def Frobble the foos
789dba Initial commit

Dann git diff 456def myfilegibt die letzte Änderung zu myfile. Es ist möglich, dasselbe ohne das Wissen zu tun, das von der git log; Was hat sich in 123abc geändert?

Chowlett
quelle
8
Ich bevorzugegit diff HEAD^ <file_path>
asgs
4
@asgs - Tut nicht das, was ich gefragt habe (aus zwei Gründen - HEAD^ist 123abc, HEAD^^ist 456def; und wenn es andere Commits gab, die diese Datei nicht beeinflussten, dann HEAD^verweist auf sie)
Chowlett
Sie haben Recht, haben den Teil "Das letzte Commit, das es geändert hat" verpasst
wie

Antworten:

215

Dies existiert zwar, aber es ist tatsächlich eine Funktion von git log:

git log -p [--follow] [-1] <path>

Beachten Sie, dass -pdies auch verwendet werden kann, um den Inline-Unterschied von einem einzelnen Commit anzuzeigen:

git log -p -1 <commit>

Verwendete Optionen:

  • -p(auch -uoder --patch) ist deeeeeeeep in der git-logManpage versteckt und ist eigentlich eine Anzeigeoption für git-diff. Bei Verwendung mit logwird der Patch angezeigt, der für jedes Commit generiert wird , zusammen mit den Commit-Informationen. Außerdem werden Commits ausgeblendet, die die angegebenen nicht berühren <path>. (Dieses Verhalten wird im folgenden Abschnitt beschrieben --full-diff, wodurch der volle Unterschied jedes Commits angezeigt wird.)
  • -1zeigt nur die letzte Änderung an der angegebenen Datei an ( -n 1kann anstelle von verwendet werden -1); Andernfalls werden alle Unterschiede ungleich Null dieser Datei angezeigt.
  • --follow ist erforderlich, um Änderungen anzuzeigen, die vor einer Umbenennung aufgetreten sind.

Soweit ich das beurteilen kann, ist dies die einzige Möglichkeit, die letzten Änderungen an einer Datei sofort anzuzeigen, ohne git log(oder ähnliches) zu verwenden, um entweder die Anzahl der dazwischen liegenden Revisionen zu zählen oder den Hash des Commits zu bestimmen.

Um Änderungen an älteren Revisionen anzuzeigen, scrollen Sie einfach durch das Protokoll oder geben Sie ein Commit oder Tag an, von dem aus das Protokoll gestartet werden soll. (Wenn Sie ein Commit oder Tag angeben, kehren Sie natürlich zum ursprünglichen Problem zurück, herauszufinden, welches Commit oder Tag das richtige ist.)

Kredit, bei dem Kredit fällig ist:

  • Ich habe log -pdank dieser Antwort entdeckt .
  • Dank an FranciscoPuga und diese Antwort, um mir die --followOption zu zeigen.
  • Dank an ChrisBetti für die Erwähnung der -n 1Option und atatko für die Erwähnung der -1Variante.
  • Dank an sweaver2112, der mich dazu gebracht hat, die Dokumentation tatsächlich zu lesen und herauszufinden, was -psemantisch "bedeutet".
Kyle Strand
quelle
6
Dies war eine großartige Lösung für mich. Zeigte jedes Commit und seine Unterschiede zur aktuellen Datei, als ich liefgit log -p filename
Ian Jamieson
4
Perfekt. Um nur die letzte Änderung zu sehen, müssen Sie lediglich den -n 1Parameter hinzufügen . git log -p -n 1 filename
Chris Betti
@ ChrisBetti Danke; Ich habe das in meine Antwort aufgenommen!
Kyle Strand
1
-n 1kann auch ersetzt werden durch -1, es ändert nichts am Ergebnis Ich bevorzuge nur die Syntax:git log -p -1 filename
Atatko
1
Es gibt eine nützliche Option "--skip = [n]". Sie können eingeben git log -p -1 --skip=1 <path>, um das zweite Commit anzuzeigen.
Maciek Łoziński
220

Eine der Möglichkeiten, Git Diff zu verwenden, ist:

git diff <commit> <path>

Ein üblicher Weg, um ein Commit des letzten Commits zu referenzieren, ist ein relativer Pfad zum tatsächlichen HEAD. Sie können frühere Commits als HEAD ^ (in Ihrem Beispiel ist dies 123abc) oder HEAD ^^ (in Ihrem Beispiel 456def) usw. referenzieren.

Die Antwort auf Ihre Frage lautet also:

git diff HEAD^^ myfile
Francisco Puga
quelle
6
Oh natürlich. Ich habe es versucht HEAD^, aber das hat natürlich nichts gebracht. Ich dachte nicht, es zu versuchen HEAD^^.
Chowlett
17
Vielleicht einfachere Syntax für vor langer Zeit HEAD~2
festgeschriebene
19
Es ist nicht wahr (zumindest für Git 1.9.0), dass HEAD^^ myfilees sich tatsächlich auf das vorletzte Commit bezieht, das sich geändert hat myfile. Es bezieht sich auf das vorletzte Commit insgesamt. Gibt es eine Möglichkeit, "Ich möchte die letzte an dieser Datei vorgenommene Änderung sehen" anzugeben, ohne den Commit-Hash (einen Teil davon) anzugeben oder die Anzahl der Commits zwischen der letzten an dieser Datei vorgenommenen Änderung und der aktuellen Revision zu zählen?
Kyle Strand
3
Hm, sieht so aus, als wäre git log -pes ziemlich nah.
Kyle Strand
30
Downvote-Grund: Die Frage lautet "zwischen einer bestimmten Datei, wie sie jetzt existiert, und wie sie vor dem letzten Commit existiert hat, der sie geändert hat ". Wenn die Datei jedoch beim letzten Gesamt-Commit nicht geändert wurde, funktioniert diese Antwort nicht.
Chris Betti
8

Wenn Sie mit einem grafischen Werkzeug gut zurechtkommen, funktioniert dies sehr gut:

gitk <file>

gitk zeigt jetzt alle Commits an, bei denen die Datei aktualisiert wurde. Wenn Sie ein Commit markieren, wird der Unterschied zum vorherigen Commit in der Liste angezeigt. Dies funktioniert auch für Verzeichnisse, aber Sie können dann auch die Datei auswählen, die für das ausgewählte Commit unterschieden werden soll. Super nützlich!

Martin G.
quelle
1
Auch sehr nützlich: git difftool HEAD^ fileodergit difftool -d HEAD^ path
ForeverLearning