Wie kann man eine Datei in eine beliebige Version in Git umwandeln?


323

Wie kann ich eine Datei beispielsweise pom.xmlvom Hauptzweig zu einer beliebigen älteren Version in Git unterscheiden?

Antworten:


346

Du kannst tun:

git diff master~20:pom.xml pom.xml

... um Ihren aktuellen Stand pom.xmlmit dem von vor master20 Revisionen durch den ersten Elternteil zu vergleichen. Sie können master~20natürlich den Objektnamen (SHA1sum) eines Commits oder eine der vielen anderen Möglichkeiten zum Festlegen einer Revision ersetzen .

Beachten Sie, dass dies tatsächlich die alte pom.xmlmit der Version in Ihrem Arbeitsbaum vergleicht, nicht mit der Version, in der festgeschrieben wurde master. Wenn Sie das möchten, können Sie stattdessen Folgendes tun:

git diff master~20:pom.xml master:pom.xml

12
Beachten Sie, dass dies nicht nur für Dateien funktioniert, sondern beispielsweise auch für (Unter-) Verzeichnisse git diff <revision>:foo/ HEAD:foo/.

2
Beachten Sie außerdem, dass Sie unter Windows Schrägstriche für Verzeichnisse verwenden müssen, wenn Sie einen Revisionsspezifizierer oder Git verwenden. Dies führt zu einer Fehlermeldung bezüglich der Datei / des Verzeichnisses, die in dieser Revision nicht vorhanden ist.
Dylan Nissley

1
@ DylanNissley oder es gibt Ihnen keinen Fehler und keinen Unterschied. Das sehe ich. Auf jeden Fall vielen Dank für den Hinweis, Schrägstriche anstelle von Schrägstrichen zu verwenden.
Gary S.

Mit Windows - Dateien habe ich es leichter zu ändern Verzeichnis und rufen Sie dann git diff Master ~ 20: ./ pom.xml ./pom.xml
lloyd

Einige Versionen von git erfordern "-" zwischen <revision> & <path>
Josh

140
git diff <revision> <path>

Zum Beispiel:

git diff b0d14a4 foobar.txt

funktioniert nicht für Version 1.7.11, wenn sich die Datei nicht im aktuellen Verzeichnis befindet. Beispiel: 'git diff f76d078 test / Config' ergibt "Fehler: Zugriff auf 'test / f76d078' nicht möglich"
simpleuser

1
@ user1663987 Übergeben Sie einfach einen vollständigen Pfad relativ zum Projektstamm : git diff <revision> root/path/file.

1
test / Config ist relativ zum Stammverzeichnis (wie im Test ein Unterverzeichnis des Stammverzeichnisses). aber dann scheint Ihr Beispiel root / path / file den root einzuschließen?
simpleuser

41

Wenn Sie den Unterschied zwischen dem letzten Festschreiben einer einzelnen Datei sehen möchten, können Sie Folgendes tun:

git log -p -1 filename

Dies gibt Ihnen den Unterschied der Datei in Git, vergleicht nicht Ihre lokale Datei.


2
Dies gibt nichts zurück
Andrei Cristian Prodan

@AndreiCristianProdan Dann hast du dort keine Änderungen. Sie können die Schritte -1schrittweise erhöhen, bis Sie die Änderungen erhalten.
Kaiser

Das ist sehr nett. Ich habe eine Bash-Funktion erstellt, die nützlich sein könnte: gitlog () { git log -${3:-p} -${2:-1} $1; } Verwendet wie: gitlog Rakefileoder gitlog Rakefile 5und gitlog Rakefile 10 s. Der erste zeigt einen Unterschied; der zweite zeigt fünf Unterschiede; der dritte zeigt zehn --no-patch.
Auxbuss

18

So sehen Sie, was beim letzten Festschreiben in einer Datei geändert wurde:

git diff HEAD~1 path/to/file.

Sie können die Zahl (~ 1) in das n-te Commit ändern, mit dem Sie sich unterscheiden möchten.


Diese Antwort ist wirklich nur ein spezifischer Fall dieser allgemeineren Antwort , wo sie ersetzt HEAD~1wird <revision>, was diese Antwort zu einem Duplikat macht.

1
das funktioniert nicht! fatal: mehrdeutiges Argument 'HEAD ~ 1': unbekannte Revision oder Pfad nicht im Arbeitsbaum. Verwenden Sie '-', um Pfade von Revisionen zu trennen
Andrei Cristian Prodan

Diese Antwort ist für mich einfach und funktional.
Douglas Frari

6

Generische Syntax:

$git diff oldCommit..newCommit -- **FileName.xml > ~/diff.txt

für alle Dateien mit dem Namen "FileName.xml" an einer beliebigen Stelle in Ihrem Repo.

Beachten Sie den Abstand zwischen "-" und "**"

Antwort auf Ihre Frage:

$git checkout master
$git diff oldCommit..HEAD -- **pom.xml 
or
$git diff oldCommit..HEAD -- relative/path/to/pom.xml 

Wie immer bei git können Sie ein Tag / sha1 / "HEAD ^" verwenden, um ein Commit zu identifizieren.

Getestet mit Git 1.9.1 unter Ubuntu.


6

Wenn weder begehen ist Ihre HEAD dann die bash Klammernerweiterung beweist wirklich nützlich, vor allem , wenn Ihre Dateinamen lang sind, das obige Beispiel:

git diff master~20:pom.xml master:pom.xml

Würde werden

git diff {master~20,master}:pom.xml

Mehr zur Klammererweiterung mit Bash.


6

Zum Vergleich mit 5 Commits mit dem aktuellen Commit, beide aktiviert master, einfach:

git diff master~5:pom.xml master:pom.xml

Sie können sich auch auf die Commit-Hash-Nummer beziehen. Wenn die Hash-Nummer beispielsweise lautet x110bd64, können Sie Folgendes tun, um den Unterschied festzustellen:

git diff x110bd64 pom.xml


2
git diff master~20 -- pom.xml

Funktioniert, wenn Sie nicht auch in der Hauptniederlassung sind.


2

Wenn Sie mit einem grafischen Werkzeug gut zurechtkommen (oder es sogar bevorzugen), können Sie:

gitk pom.xml

In gitk können Sie dann auf ein beliebiges Commit klicken (um es "auszuwählen") und mit der rechten Maustaste auf ein anderes Commit klicken, um "Diff this -> selected" oder "Diff selected -> this" im Popup-Menü auszuwählen, je nachdem, welche Reihenfolge Sie bevorzugen.



0

Wenn Sie beispielsweise eine einzelne Datei in einem Stash unterscheiden müssen, können Sie dies tun

git diff stash@{0} -- path/to/file

-1

Wenn Sie nach dem Diff für ein bestimmtes Commit suchen und die Github-Benutzeroberfläche anstelle der Befehlszeile verwenden möchten (sagen wir, Sie möchten es mit anderen Leuten verknüpfen), können Sie Folgendes tun:

https://github.com/<org>/<repo>/commit/<commit-sha>/<path-to-file>

Zum Beispiel:

https://github.com/grails/grails-core/commit/02942c5b4d832b856fbc04c186f1d02416895a7e/grails-test-suite-uber/build.gradle

Beachten Sie die Links Zurück und Weiter oben rechts, mit denen Sie durch alle Dateien im Commit navigieren können.

Dies funktioniert jedoch nur für ein bestimmtes Commit, nicht für den Vergleich zwischen zwei beliebigen Versionen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.