Wie finde ich eine gelöschte Datei in einem Git-Repository und stelle sie wieder her?
Lesezeit: 10 Minuten
Avdgaag
Angenommen, ich bin in einem Git-Repository. Ich lösche eine Datei und übertrage diese Änderung. Ich arbeite weiter und mache weitere Commits. Dann entdecke ich, dass ich diese Datei nach dem Löschen wiederherstellen muss.
Ich weiß, dass ich eine Datei mit auschecken kann git checkout <commit> -- filename.txtaber ich weiß nicht, wann diese Datei gelöscht wurde.
Wie finde ich den Commit, der einen bestimmten Dateinamen gelöscht hat?
Wie stelle ich diese Datei wieder in meiner Arbeitskopie wieder her?
Beachten Sie, dass der vorherige Kommentar die Frage im Titel beantwortet, nicht im Hauptteil – das schließt das Herausfinden ein Wenn die Datei wurde gelöscht.
– durchschn
16. Dezember 2011 um 16:02 Uhr
Um den Commit zu finden, wurde eine Datei gelöscht in: git log --diff-filter=D -- path/to/file
– Titanköder
16. März 2012 um 21:28 Uhr
Verwandte: Wie verwerfen Sie nicht bereitgestellte Änderungen in Git?.
– Benutzer456814
28. April 2014 um 5:16 Uhr
Verwandte: So finden Sie eine gelöschte Datei im Commit-Verlauf
– Owen Blacker
3. November 2014 um 14:14 Uhr
@hhh git checkout deletedFile wird wiederhergestellt deletedFile wenn es gelöscht wurde, aber diese Löschung wurde noch nicht inszeniert oder begangen. Das ist nicht das, wonach die Frage hier fragt; Bei dieser Frage geht es darum, wie eine Datei wiederhergestellt wird, deren Löschung vor vielen Commits festgeschrieben wurde.
– Mark Amery
15. April 2017 um 10:33 Uhr
CB Bailey
Finden Sie den letzten Commit, der den angegebenen Pfad beeinflusst hat. Da sich die Datei nicht im HEAD-Commit befindet, muss sie bei diesem vorherigen Commit gelöscht worden sein.
git rev-list -n 1 HEAD -- <file_path>
Checken Sie dann die Version beim Commit vorher aus, indem Sie das Caretzeichen (^) Symbol:
git checkout <deleting_commit>^ -- <file_path>
Oder in einem Befehl, wenn $file ist die betreffende Datei.
Der schwierige Teil besteht darin, den Commit VORHER auszuchecken, indem Sie das ^-Suffix verwenden. Vielen Dank.
– Christian Ouard
26. April 2010 um 14:40 Uhr
Aus irgendeinem Grund funktioniert dies nicht in zsh. ± git checkout $(git rev-list -n 1 HEAD "spec/Sporkfile_example.rb")^ -- "spec/Sporkfile_example.rb" zsh: no matches found: b71c152d8f38dcd23ad7600a93f261a7252c59e9^ Ich bin auf Bash umgestiegen und es hat gut funktioniert.
– Zora
28. Februar 2012 um 3:45 Uhr
Von der Windows-Befehlszeile bekam ich einen Fehler. error: pathspec <filename> did not match any file(s) known to git.. Die Lösung war die Verwendung von git bash.
– donturner
26. Juli 2012 um 18:07 Uhr
@zoras zsh hat eine eigene Erweiterung für ‚^‘, glaube ich, aber Sie können die alternative Syntax von ‚~1‘ verwenden: git checkout <deleting-commit>~1 -- <file-path> ~X ermöglicht es Ihnen, X Commits vor dem angegebenen Commit anzugeben, also ist ~1 der Commit davor, ~2 sind zwei Commits davor usw
– Nils Luxton
10. September 2012 um 15:07 Uhr
An der Windows-Cmd-Eingabeaufforderung wird die ^ Zeichen ist das Fluchtzeichen! Daher müssen Sie bei cmd eingeben ^^ um cmd mitzuteilen, dass Sie ein einzelnes Literal ^ wollen und dass Sie danach nichts anderes mehr maskieren. Was vielen Menschen passiert ist, dass die ^ gefolgt von einem Leerzeichen. cmd denkt also, dass Sie das Leerzeichen maskieren – was einfach ein Leerzeichen ergibt. Bis Git also die cli-Argumente erhält, sieht es SHA1 und nichtSHA1^. Es ist wirklich nervig. ~ ist kein Fluchtzeichen, deshalb funktioniert das immer noch. (PS. Wenn Sie glauben, dass Googler diese Informationen möchten, stimmen Sie bitte diesem Kommentar zu.)
– Alexander Vogel
18. September 2015 um 14:48 Uhr
Robert Munteanu
Holen Sie sich alle Commits, die Dateien gelöscht haben, sowie die Dateien, die gelöscht wurden:
git log --diff-filter=D --summary
Notieren Sie sich den gewünschten Commit-Hash, z e4e6d4d5e5c59c69f3bd7be2.
Stellen Sie die gelöschte Datei von einem vorherigen Commit wieder her (~1) auf das oben festgelegte Commit (e4e6d4d5e5c59c69f3bd7be2):
@tommy – die Tilde-Spezifikation gibt Ihnen das n-te Enkelkind des benannten Commits . Sehen book.git-scm.com/4_git_treeishes.html für mehr Details .
– Robert Munteanu
23. Juli 2011 um 12:00 Uhr
Dies ist bei weitem der einfachste und intuitivste Ansatz. git log -- *PartOfMyFileName*. Danke für $commit~1
– bgs
10. April 2013 um 23:25 Uhr
das git checkout $commit~1 filename Syntax funktioniert perfekt für einzelne Dateien und funktioniert auch für ganze Verzeichnisse. dh: um alle gelöschten Bilder in ./images von sha 12345 wiederherzustellen: git checkout 12345~1 images. danke für diese antwort!
– keine Eingabe
3. Juni 2014 um 4:59 Uhr
@Alexar $commit~1 bedeutet, dass Sie den Namen des Commits hinzufügen sollten. Etwas wie 1d0c9ef6eb4e39488490543570c31c2ff594426c wo $commit ist.
– Eugen
7. April 2015 um 6:27 Uhr
Manu
So stellen Sie alle gelöschten Dateien in einem Ordner wieder her:
git ls-files -d | xargs git checkout --
Wohin werden die Dateien geleitet? Ich sehe keine Veränderung.
– Wilhelm Groß
13. September 2013 um 14:36 Uhr
Dies ist wahrscheinlich die einfachste Methode. Es ist pervers, wie schwierig git hat selbst die einfachste Aufgabe gemacht.
– jww
19. Oktober 2013 um 4:12 Uhr
Das ls-files Unterbefehl ist praktisch, scheint aber nicht für Dateien zu funktionieren, die mit entfernt wurden git rm dh inszeniert, geschweige denn begangen, was das OP gefragt hat.
– MarkHu
17. November 2017 um 8:47 Uhr
@RomainValeri – Es ist 2019. Die Tools funktionieren für mich. Ich arbeite nicht für die Tools. Wenn Lernen erforderlich ist, ist das Design gebrochen.
– jww
5. Dezember 2019 um 10:24 Uhr
@RomainValeri, @jww ihr habt beide Recht. git ist nahezu beispiellos in seiner Nützlichkeit, während es auch unglaublich kompliziert zu lernen ist. Ein nennenswerter Anteil an gits Lernkurve ist auf eine inkonsistente / nicht intuitive Benutzeroberfläche zurückzuführen. Wenn ich etwas Schwieriges lerne, gibt es mir persönlich unter anderem Sicherheit, wenn ich sehe, dass andere (kompetente) Menschen ebenfalls Schwierigkeiten haben, es zu verstehen
– Matthäus Strasiotto
17. März 2021 um 23:21 Uhr
Brett
Wenn Sie eine Datei gelöscht haben, die in der neuesten Datei vorhanden ist HEAD committen, können Sie es wiederherstellen mit:
git checkout HEAD -- path/to/file.ext
Josh Lee
Wenn Sie verrückt sind, verwenden Sie git-bisect. Folgendes ist zu tun:
git bisect start
git bisect bad
git bisect good <some commit where you know the file existed>
Jetzt ist es an der Zeit, den automatisierten Test auszuführen. Der Shell-Befehl '[ -e foo.bar ]' wird 0 zurückgeben, wenn foo.bar existiert, und 1 sonst. Der “Run”-Befehl von git-bisect verwendet eine binäre Suche, um automatisch den ersten Commit zu finden, bei dem der Test fehlschlägt. Es beginnt auf halbem Weg durch den angegebenen Bereich (von gut bis schlecht) und halbiert ihn basierend auf dem Ergebnis des angegebenen Tests.
git bisect run '[ -e foo.bar ]'
Jetzt sind Sie bei dem Commit, der es gelöscht hat. Von hier aus können Sie zurück in die Zukunft springen und verwenden git-revert um die Änderung rückgängig zu machen,
Könnten Sie das näher erläutern git bisect run '[ -e foo.bar ]'?
– durchschn
4. Juni 2009 um 22:53 Uhr
Sie können gut und schlecht auch manuell verwenden, wenn es etwas ist, das nicht automatisch überprüft werden kann. Siehe die Bisect-Manpage.
– Josh Lee
4. Juni 2009 um 23:00 Uhr
@avdgaag die git bisect run weist Git an, die Halbierung zu automatisieren, indem der Befehl nach dem Wort „run“ ausgeführt wird, wo der Befehl zurückkehren muss 0 Für ein good Fassung (vgl git help bisect für Details). Das '[ -e foo.bar ]' ist ein Standardausdruck zum Testen von if-Dateien foo.bar existiert (die Implementierung befindet sich normalerweise in einer Datei /usr/bin/[ which is usually hardlinked to /usr/bin/test) and the single quation marks are used to put that all as a single command line argument.
– Mikko Rantalainen
Mar 18, 2013 at 7:18
Great idea. I tried this approach and it identified a commit prior to deletion, but not the commit that actually deleted the file. And in another test it identified 2 commits prior to the deletion.
– Michael Osofsky
May 22, 2019 at 19:48
Insane? Maybe. But bisect is a great way to help find where a bug was introduced and so it’s a valuable skill to learn anyway. So although maybe not the ‘correct’ or most ‘correct’ way here it’s still a good idea and worth a +1 definitely!
– Pryftan
Nov 12, 2019 at 12:08
My new favorite alias, based on bonyiii’s answer (upvoted), and my own answer about “Pass an argument to a Git alias command”:
Could you elaborate on git bisect run '[ -e foo.bar ]'?
– durchschn
4. Juni 2009 um 22:53 Uhr
Sie können gut und schlecht auch manuell verwenden, wenn es etwas ist, das nicht automatisch überprüft werden kann. Siehe die Bisect-Manpage.
– Josh Lee
4. Juni 2009 um 23:00 Uhr
@avdgaag die git bisect run weist Git an, die Halbierung zu automatisieren, indem der Befehl nach dem Wort „run“ ausgeführt wird, wo der Befehl zurückkehren muss 0 Für ein good Fassung (vgl git help bisect für Details). Das '[ -e foo.bar ]' ist ein Standardausdruck zum Testen von if-Dateien foo.bar existiert (die Implementierung befindet sich normalerweise in einer Datei /usr/bin/[ which is usually hardlinked to /usr/bin/test) and the single quation marks are used to put that all as a single command line argument.
– Mikko Rantalainen
Mar 18, 2013 at 7:18
Great idea. I tried this approach and it identified a commit prior to deletion, but not the commit that actually deleted the file. And in another test it identified 2 commits prior to the deletion.
– Michael Osofsky
May 22, 2019 at 19:48
Insane? Maybe. But bisect is a great way to help find where a bug was introduced and so it’s a valuable skill to learn anyway. So although maybe not the ‘correct’ or most ‘correct’ way here it’s still a good idea and worth a +1 definitely!
– Pryftan
Nov 12, 2019 at 12:08
Mark Amery
If you know the filename, this is an easy way with basic commands:
List all the commits for that file.
git log -- path/to/file
The last commit (topmost) is the one that deleted the file. So you need to restore the second to last commit.
git checkout {second to last commit} -- path/to/file
This is the first solution I’ve seen that’s simple enough that I won’t have to come back here to find it next time. Maybe.
Beachten Sie, dass der vorherige Kommentar die Frage im Titel beantwortet, nicht im Hauptteil – das schließt das Herausfinden ein Wenn die Datei wurde gelöscht.
– durchschn
16. Dezember 2011 um 16:02 Uhr
Um den Commit zu finden, wurde eine Datei gelöscht in:
git log --diff-filter=D -- path/to/file
– Titanköder
16. März 2012 um 21:28 Uhr
Verwandte: Wie verwerfen Sie nicht bereitgestellte Änderungen in Git?.
– Benutzer456814
28. April 2014 um 5:16 Uhr
Verwandte: So finden Sie eine gelöschte Datei im Commit-Verlauf
– Owen Blacker
3. November 2014 um 14:14 Uhr
@hhh
git checkout deletedFile
wird wiederhergestelltdeletedFile
wenn es gelöscht wurde, aber diese Löschung wurde noch nicht inszeniert oder begangen. Das ist nicht das, wonach die Frage hier fragt; Bei dieser Frage geht es darum, wie eine Datei wiederhergestellt wird, deren Löschung vor vielen Commits festgeschrieben wurde.– Mark Amery
15. April 2017 um 10:33 Uhr