Sie sollten in der Lage sein, alle Dateien wiederherzustellen, die Sie dem Index hinzugefügt haben (z. B. wie in Ihrer Situation mit git add .
), obwohl dies möglicherweise ein wenig Arbeit ist. Um dem Index eine Datei hinzuzufügen, fügt git sie der Objektdatenbank hinzu. Dies bedeutet, dass sie wiederhergestellt werden kann, solange die Speicherbereinigung noch nicht erfolgt ist. Ein Beispiel dafür finden Sie in Jakub Narębskis Antwort hier:
Ich habe das jedoch in einem Test-Repository ausprobiert, und es gab ein paar Probleme - --cached
sollte es sein --cache
, und ich stellte fest, dass das .git/lost-found
Verzeichnis nicht tatsächlich erstellt wurde . Die folgenden Schritte haben jedoch bei mir funktioniert:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)")
Das sollte alle Objekte in der Objektdatenbank ausgeben, die mit keinem Verweis, im Index oder über das Reflog erreichbar sind. Die Ausgabe sieht ungefähr so aus:
unreachable blob 907b308167f0880fb2a5c0e1614bb0c7620f9dc3
unreachable blob 72663d3adcf67548b9e0f0b2eeef62bce3d53e03
... und für jeden dieser Blobs können Sie Folgendes tun:
git show 907b308
So geben Sie den Inhalt der Datei aus
Zu viel Output?
Update als Antwort auf den Kommentar von sehe unten:
Wenn Sie feststellen, dass in der Ausgabe dieses Befehls viele Commits und Bäume aufgeführt sind, möchten Sie möglicherweise alle Objekte aus der Ausgabe entfernen, auf die aus nicht referenzierten Commits verwiesen wird. (Normalerweise können Sie über das Reflog ohnehin zu diesen Commits zurückkehren. Wir sind nur an Objekten interessiert, die dem Index hinzugefügt wurden, aber niemals über ein Commit gefunden werden können.)
Speichern Sie zunächst die Ausgabe des Befehls mit:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") > all
Jetzt können die Objektnamen dieser nicht erreichbaren Commits gefunden werden mit:
egrep commit all | cut -d ' ' -f 3
Sie können also nur die Bäume und Objekte finden, die dem Index hinzugefügt, aber zu keinem Zeitpunkt festgeschrieben wurden, mit:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") \
$(egrep commit all | cut -d ' ' -f 3)
Das reduziert die Anzahl der Objekte, die Sie berücksichtigen müssen, enorm.
Update: Philip Oakley unten schlägt eine andere Möglichkeit vor, die Anzahl der zu berücksichtigenden Objekte zu verringern, nämlich nur die zuletzt geänderten Dateien unter .git/objects
. Sie finden diese mit:
find .git/objects/ -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort
(Ich habe diesen find
Aufruf hier gefunden .) Das Ende dieser Liste könnte folgendermaßen aussehen:
2011-08-22 11:43:43.0234896770 .git/objects/b2/1700b09c0bc0fc848f67dd751a9e4ea5b4133b
2011-09-13 07:36:37.5868133260 .git/objects/de/629830603289ef159268f443da79968360913a
In diesem Fall können Sie diese Objekte sehen mit:
git show b21700b09c0bc0fc848f67dd751a9e4ea5b4133b
git show de629830603289ef159268f443da79968360913a
(Beachten Sie, dass Sie das /
am Ende des Pfads entfernen müssen , um den Objektnamen zu erhalten.)