So stellen Sie ein defektes / teilweise gelöschtes Git-Repository wieder her

7

Ich habe versehentlich ein rm -rin meinem .git-Verzeichnis ausgeführt. Zum Glück hat es rmaufgehört, als es zu einer schreibgeschützten Datei kam, aber ich habe immer noch einige Dinge in meinem .git verloren.

Dateien, die ich noch habe:

FETCH_HEAD
ORIG_HEAD
config
gitk.cache
logs/
objects/

Dateien, die ich verloren habe:

HEAD
description
hooks/
index
info/
packed-refs
refs/

Nach allem, was ich sagen kann, sind die einzigen Dinge, die ich verloren habe und die ich nicht erneut klonen kann, die Änderungen in meinem Staging-Bereich und meinen Schiedsrichtern. Ich bin bereit, meine Staging-Änderungen zu verlieren, aber ich muss wirklich meinen KOPF und meine Zweige wiederherstellen. Gibt es eine Möglichkeit, dies zu tun? Sagen wir, indem Sie Commits finden, die keine Kinder haben, sie überprüfen, um zu sehen, was sie sind, und Zweige für sie erstellen? Im Moment erkennt git mein Repository jedoch nicht mehr als Repository.

Shum
quelle

Antworten:

11

Alle Commits und Dateien, auf die sie verweisen, werden als Objekte im objectsVerzeichnis gespeichert . Git erstellt diese als schreibgeschützt, daher sollten sie alle noch vorhanden sein.

Zur Wiederherstellung würde ich empfehlen, ein neues, leeres Repository zu erstellen und den Inhalt des objectsVerzeichnisses Ihres defekten Repositorys in das des neuen zu kopieren . Das sollte Sie zu einem Punkt bringen, an dem Git zumindest erkennt, dass es sich um ein Repository handelt und alle Ihre Objekte enthält. Das Arbeiten mit einer Kopie hilft auch dabei, zu vermeiden, dass beim Versuch, Dinge zu reparieren, noch mehr Schaden verursacht wird.

Shell-Befehle zum Erstellen des temporären Repositorys und zum Kopieren über die Objekte:

git init /tmp/recovery
cd /tmp/recovery
cp -r /path/to/broken/repo/.git/objects .git

Sobald dies erledigt ist, können Sie git fsckeine Liste von Objekten abrufen, auf die von nichts verwiesen wird. Dies sollte alle Zweigstellenleiter einschließen, aber auch alle Commits, die durch git commit --amendoder durch Umbasierung überholt wurden.

Da Sie immer noch das Protokollverzeichnis haben, ist dies wahrscheinlich eine noch größere Hilfe. logs/refs/heads/<branch>Für jeden Zweig, den Sie hatten, sollte eine Datei vorhanden sein. Die zweite Spalte der letzten Zeile enthält die ID des Commits, das sich zum Zeitpunkt des Löschens am Kopf dieses Zweigs befand. Es sollte auch logs/HEADdie gleichen Informationen darüber geben, wo sich der HEAD befand. Wenn Sie jedoch nicht mit einem abgetrennten HEAD gearbeitet haben, ist es wahrscheinlich besser, nur die Zweige wiederherzustellen und dann einen Zweig normal auszuchecken.

Für jeden Zweig, den Sie wiederherstellen möchten, können Sie Folgendes ausführen:

git branch <name> <commit_id>

Sobald Sie die Zweige wiederhergestellt haben, können Sie sie über die Konfigurationsdatei kopieren, und Sie sollten sich ziemlich nahe an dem Ort befinden, an dem Sie sich zum Zeitpunkt des letzten Commits befanden.

qqx
quelle