1100 Stimmen

Wie kann eine einzelne Datei aus einer bestimmten Revision in Git abgerufen werden?

Ich habe ein Git-Repository und würde gerne sehen, wie einige Dateien vor einigen Monaten aussahen. Ich habe die Revision zu diesem Datum gefunden; sie lautet 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8 . Ich muss sehen, wie eine Datei aussieht, und sie auch als ("neue") Datei speichern.

Ich konnte die Datei mit gitk aber es gibt keine Möglichkeit, sie zu speichern. Ich habe es mit den Befehlszeilen-Tools versucht, das Naheliegendste, was ich bekam, war:

git-show 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8 my_file.txt

Dieser Befehl zeigt jedoch einen Vergleich und nicht den Inhalt der Datei an. Ich weiß, dass ich später etwas verwenden kann wie PAGER=cat und die Ausgabe in eine Datei umleiten, aber ich weiß nicht, wie ich an den eigentlichen Dateiinhalt komme.

Im Grunde suche ich etwas wie svn-Kat .

111 Stimmen

Der Schlüssel dazu: git show verwendet (wenig hilfreich) eine andere Syntax mit einem Doppelpunkt. git show 2c7cf:my_file.txt

5 Stimmen

Zur weiteren Verdeutlichung: Mit dem obigen Befehl wird git aufgefordert, zwei separate Objekte anzuzeigen, eine Revision und eine Datei. Die akzeptierte Antwort unten, die einen Doppelpunkt zwischen den beiden Objekten verwendet, fragt nach einer bestimmten Datei in einer bestimmten Revision.

2 Stimmen

Unter *nix brauchen Sie kein PAGER, sondern nur eine Umleitung der Shell-Ausgabe mit >

13voto

Alessandro Jacopson Punkte 17059

Unter Windows, mit Git Bash:

  • Ändern Sie in Ihrem Arbeitsbereich dir in den Ordner, in dem sich Ihre Datei befindet
  • git show cab485c83b53d56846eb883babaaf4dff2f2cc46:./your_file.ext > old.ext

9voto

prosoitos Punkte 5811

Zusätzlich zu den in den anderen Antworten genannten Optionen können Sie Folgendes verwenden git reset mit dem Git-Objekt (hash, branch, HEAD~x , Tag, ...) von Interesse und den Pfad Ihrer Datei:

git reset <hash> /path/to/file

In Ihrem Beispiel:

git reset 27cf8e8 my_file.txt

Das bedeutet, dass es zurückkehrt my_file.txt zu seiner Version bei der Übergabe 27cf8e8 im Index, während sie im Arbeitsverzeichnis unverändert (also in ihrer aktuellen Version) bleibt.

Von da an sind die Dinge sehr einfach:

  • können Sie die beiden Versionen Ihrer Datei mit git diff --cached my_file.txt
  • können Sie die alte Version der Datei loswerden mit git restore --staged file.txt (oder, vor Git v2.23, git reset file.txt ) wenn Sie entscheiden, dass es Ihnen nicht gefällt
  • können Sie die alte Version wiederherstellen mit git commit -m "Restore version of file.txt from 27cf8e8" y git restore file.txt (oder, vor Git v2.23, git checkout -- file.txt )
  • können Sie Aktualisierungen von der alten zur neuen Version nur für einige Hunks hinzufügen, indem Sie git add -p file.txt (dann git commit y git restore file.txt ).

Und schließlich können Sie sogar interaktiv auswählen, welche(r) Hunk(s) im ersten Schritt zurückgesetzt werden soll(en), wenn Sie laufen:

git reset -p 27cf8e8 my_file.txt

Alors git reset mit einem Pfad gibt Ihnen viel Flexibilität, um eine bestimmte Version einer Datei abzurufen, um sie mit der aktuell ausgecheckten Version zu vergleichen und, falls Sie dies wünschen, vollständig oder nur für einige Teile zu dieser Version zurückzukehren.


Editar: Mir ist gerade klar geworden, dass ich Ihre Frage nicht beantworte, denn was Sie wollten, war nicht ein Diff oder eine einfache Möglichkeit, die alte Version ganz oder teilweise wiederherzustellen, sondern einfach cat diese Version.

Natürlich können Sie das auch nach dem Zurücksetzen der Datei mit tun:

git show :file.txt

zur Ausgabe auf der Standardausgabe oder

git show :file.txt > file_at_27cf8e8.txt

Aber wenn das alles war, was du wolltest, lief git show direkt mit git show 27cf8e8:file.txt wie von anderen vorgeschlagen, ist natürlich viel direkter.

Ich werde diese Antwort aber stehen lassen, weil das Laufen git show ermöglicht es Ihnen, die alte Version sofort abzurufen, aber wenn Sie etwas damit machen wollen, ist es nicht annähernd so bequem, dies von dort aus zu tun, wie wenn Sie die Version im Index zurücksetzen.

8voto

Mr_and_Mrs_D Punkte 29254

Und um es schön in eine Datei zu packen (zumindest unter Windows) - Git Bash:

$ echo "`git show 60d8bdfc:src/services/LocationMonitor.java`" >> LM_60d8bdfc.java

El " Anführungszeichen sind erforderlich, damit die Zeilenumbrüche erhalten bleiben.

5voto

Adrian Gunawan Punkte 13141

Dies hilft Ihnen, alle gelöschten Dateien zwischen den Übertragungen zu finden, ohne den Pfad anzugeben, was nützlich ist, wenn viele Dateien gelöscht wurden.

git diff --name-only --diff-filter=D $commit~1 $commit | xargs git checkout $commit~1

2voto

josch Punkte 6178

Verwendung von git show $REV:$FILE wie bereits von anderen gesagt wurde, ist wahrscheinlich die richtige Antwort. Ich poste eine andere Antwort, denn als ich diese Methode ausprobierte, erhielt ich manchmal die folgende Fehlermeldung von Git:

fatal: path 'link/foo' exists on disk, but not in 'HEAD'

Das Problem tritt auf, wenn Teile des Pfads zur Datei ein symbolischer Link sind. In diesen Fällen wird die git show $REV:$FILE Methode wird pas arbeiten. Schritte zum Reproduzieren:

$ git init .
$ mkdir test
$ echo hello > test/foo
$ ln -s test link
$ git add .
$ git commit -m "initial commit"
$ cat link/foo
hello
$ git show HEAD:link/foo
fatal: path 'link/foo' exists on disk, but not in 'HEAD'

Das Problem ist, dass Dienstprogramme wie realpath helfen hier nicht weiter, da der Symlink in der aktuellen Übertragung möglicherweise nicht mehr existiert. Ich weiß nicht, ob es eine gute allgemeine Lösung gibt. In meinem Fall wusste ich, dass der Symlink nur in der ersten Komponente des Pfades existieren konnte, also löste ich das Problem, indem ich die git show $REV:$FILE Methode zweimal. Das funktioniert, denn wenn git show $REV:$FILE für einen Symlink verwendet wird, wird das Ziel gedruckt:

$ git show HEAD:link
test

Bei Verzeichnissen hingegen gibt der Befehl eine Kopfzeile aus, gefolgt von dem Inhalt des Verzeichnisses:

$ git show HEAD:test
tree HEAD:test

foo

In meinem Fall habe ich also die Ausgabe des ersten Aufrufs von git show $REV:$FILE und wenn es nur eine einzige Zeile war, dann habe ich die erste Komponente meines Pfades durch das Ergebnis ersetzt, um den Symlink durch Git aufzulösen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X