Frage Suchen und Wiederherstellen einer gelöschten Datei in einem Git-Repository


Angenommen, ich bin in einem Git-Repository. Ich lösche eine Datei und bestätige diese Änderung. Ich arbeite weiter und mache noch ein paar Commits. Dann muss ich diese Datei wiederherstellen.

Ich weiß, dass ich eine Datei mit einer Datei auschecken kann git checkout HEAD^ foo.bar, aber ich weiß nicht wirklich, wann diese Datei gelöscht wurde.

  1. Was wäre der schnellste Weg, den Commit zu finden, der einen bestimmten Dateinamen gelöscht hat?
  2. Was wäre der einfachste Weg, um diese Datei wieder in meine Arbeitskopie zu bekommen?

Ich hoffe, ich muss meine Protokolle nicht manuell durchsuchen, das gesamte Projekt für eine bestimmte SHA auschecken und diese Datei dann manuell in meine ursprüngliche Projektausleihe kopieren.


2382
2018-06-04 22:40


Ursprung


Antworten:


Finden Sie das letzte Commit, das den angegebenen Pfad beeinflusst hat. Da die Datei nicht im HEAD-Commit enthalten ist, muss dieses Commit sie gelöscht haben.

git rev-list -n 1 HEAD -- <file_path>

Dann check die Version beim Commit vorher mit dem Caret (^) Symbol:

git checkout <deleting_commit>^ -- <file_path>

Oder in einem Befehl, wenn $file ist die Datei in Frage.

git checkout $(git rev-list -n 1 HEAD -- "$file")^ -- "$file"

Wenn Sie zsh verwenden und die Option EXTENDED_GLOB aktiviert ist, funktioniert das Caret-Symbol nicht. Sie können verwenden ~1 stattdessen.

git checkout $(git rev-list -n 1 HEAD -- "$file")~1 -- "$file"

2718
2017-07-11 07:12



  1. Benutzen git log --diff-filter=D --summary um alle Commits zu erhalten, die Dateien gelöscht haben und die Dateien gelöscht haben;
  2. Benutzen git checkout $commit~1 filename um die gelöschte Datei wiederherzustellen.

Woher $commit ist der Wert des Commits, das Sie in Schritt 1 gefunden haben, z. e4cf499627


723
2018-06-04 23:10



Um alle gelöschten Dateien in einem Ordner wiederherzustellen, geben Sie den folgenden Befehl ein.

git ls-files -d | xargs git checkout --

301
2017-12-02 06:11



Ich kam zu dieser Frage, um eine Datei wiederherzustellen, die ich gerade gelöscht hatte, aber ich hatte die Änderung noch nicht vorgenommen. Für den Fall, dass Sie sich in dieser Situation befinden, müssen Sie nur Folgendes tun:

git checkout HEAD -- path/to/file.ext


99
2018-04-10 00:03



Wenn Sie verrückt sind, verwenden Sie git-bisect. Hier ist was zu tun ist:

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 durchzuführen. Der Shell-Befehl '[ -e foo.bar ]' wird 0 zurückgeben, wenn foo.bar existiert, und 1 sonst. Der "run" -Befehl von git-bisect wird die binäre Suche verwenden, um automatisch das erste Commit zu finden, bei dem der Test fehlschlägt. Es beginnt in der Mitte des angegebenen Bereichs (von gut bis schlecht) und schneidet es auf der Grundlage des Ergebnisses des angegebenen Tests halbiert.

git bisect run '[ -e foo.bar ]'

Jetzt bist du beim Commit, der es gelöscht hat. Von hier aus können Sie zurück in die Zukunft springen und verwenden git-revert um die Veränderung rückgängig zu machen,

git bisect reset
git revert <the offending commit>

Oder du könntest einen Commit zurücklegen und den Schaden manuell untersuchen:

git checkout HEAD^
cp foo.bar /tmp
git bisect reset
cp /tmp/foo.bar .

82
2018-06-04 22:46



Mein neuer Lieblingsalias, basierend auf bonyiiiist es Antworten (upvoted), und meine eigene Antwort über "Übergeben Sie ein Argument an einen Git Alias-Befehl":

git config alias.restore '!f() { git checkout $(git rev-list -n 1 HEAD -- $1)~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- $1)~1 | grep '^D' | cut -f 2); }; f'

Ich habe eine Datei verloren, die versehentlich vor ein paar Commits gelöscht wurde?
Schnell:

git restore my_deleted_file

Krise abgewendet.


Robert Dailey schlägt vor in den Kommentaren folgender Alias:

restore-file = !git checkout $(git rev-list -n 1 HEAD -- "$1")^ -- "$1"

Und Jegan fügt hinzu in den Kommentaren:

Um den Alias ​​von der Kommandozeile aus zu setzen, habe ich diesen Befehl verwendet:

git config --global alias.restore "\!git checkout \$(git rev-list -n 1 HEAD -- \"\$1\")^ -- \"\$1\"" 

61
2018-02-17 15:33



Wenn Sie den Dateinamen kennen, ist dies ein einfacher Weg mit grundlegenden Befehlen:

Listen Sie alle Commits für diese Datei auf.

git log -- path/to/file

Der letzte Commit (oberste) ist derjenige, der die Datei gelöscht hat. Sie müssen also das vorletzte Commit wiederherstellen.

git checkout {second to last commit} -- path/to/file

42
2018-02-27 01:50