Angenommen, ich befinde mich in einem Git-Repository. Ich lösche eine Datei und übertrage diese Änderung. Ich arbeite weiter und nehme weitere Übertragungen vor. Dann stelle ich fest, dass ich die Datei wiederherstellen muss.
Ich weiß, dass ich eine Datei mit git checkout HEAD^ foo.bar
auschecken kann, aber ich weiß nicht wirklich, wann diese Datei gelöscht wurde.
Ich hoffe, ich muss nicht manuell meine Logs durchsuchen, das gesamte Projekt für einen bestimmten SHA auschecken und dann diese Datei manuell in mein ursprüngliches Projekt-Checkout kopieren.
Findet den letzten Commit, der den angegebenen Pfad betrifft. Da die Datei nicht im HEAD-Commit enthalten ist, muss dieser Commit sie gelöscht haben.
git rev-list -n 1 HEAD -- <file_path>
Checken Sie dann die Version des vorherigen Commits aus, indem Sie das Caret (^
) Symbol verwenden:
git checkout <deleting_commit>^ -- <file_path>
Oder in einem Befehl, wenn $file
die betreffende Datei ist.
git checkout $(git rev-list -n 1 HEAD -- "$file")^ -- "$file"
Wenn Sie zsh verwenden und die Option EXTENDED_GLOB aktiviert haben, wird das Caret-Symbol nicht funktionieren. Sie können stattdessen ~1
verwenden.
git checkout $(git rev-list -n 1 HEAD -- "$file")~1 -- "$file"
git log --diff-filter=D --summary
, um alle Commits, die Dateien gelöscht haben, und die gelöschten Dateien zu erhalten;git checkout $commit~1 path/to/file.ext
, um die gelöschte Datei wiederherzustellen.Dabei ist "$commit" der Wert des Commits, den Sie in Schritt 1 gefunden haben, z.B. "e4cf499627".
Wenn Sie wahnsinnig 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>
Nun 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 andernfalls. Der Befehl "run" von git-bisect
verwendet die binäre Suche, um automatisch die erste Übertragung zu finden, bei der der Test fehlschlägt. Er beginnt in der Mitte des angegebenen Bereichs (von "gut" bis "schlecht") und halbiert ihn auf der Grundlage des Ergebnisses des angegebenen Tests.
git bisect run '[ -e foo.bar ]'
Jetzt sind Sie bei dem Commit, das den Test gelöscht hat. Von hier aus können Sie zurück in die Zukunft springen und git-revert
verwenden, um die Änderung rückgängig zu machen,
git bisect reset
git revert <the offending commit>
oder Sie können einen Commit zurückgehen und den Schaden manuell überprüfen:
git checkout HEAD^
cp foo.bar /tmp
git bisect reset
cp /tmp/foo.bar .