Wie stellen Sie ein beschädigtes Objekt in einem Git-Repository wieder her (für Neulinge)?
Lesezeit: 14 Minuten
Bescheidener Pinguin
Ich habe heute versucht, mein Repository zu öffnen, und es wurde kein Commit-Verlauf angezeigt. Alles, was ich versucht habe (git status, git log, git checkout …) hat einen Fehler über ein beschädigtes Objekt ausgegeben.
Ich habe dieses Problem online recherchiert und das gefunden Artikel von Linus Torvalds, ging aber an dem Punkt verloren, an dem er die defekte Link-ID fand: Keine meiner Datei-IDs, Baum oder Blob, stimmt mit der Täter-ID überein, die von der Fehlermeldung geworfen wurde.
Ich kehrte dann zu dem Artikel über die Wiederherstellung von „Git-Objekten, die durch einen Festplattenausfall beschädigt wurden“ zurück und arbeitete mich (nachdem ich das Schuldobjekt aus dem Weg geräumt hatte) bis durch
$ cat packed-refs
An diesem Punkt sagte mein Computer: cat: packed-refs: No such file or directory
Ich übersprang diesen Schritt und tat das
$ git fsck --full
und bekam die entsprechende Ausgabe, aber dann sollte ich den Täter (oder was ich als den Täter bezeichnete, die durch den Fehler ausgelöste sha1-ID) aus einem Backup-Repository zurück in das Haupt-Repository kopieren und dann die fehlenden Objekte kopieren aus das Backup-Repository in das Haupt-Repository, soweit ich das beurteilen kann; und ich will nichts tun auch drastisch oder ich könnte etwas erzwingen, das ich später nicht mehr aufheben kann.
Also meine Frage(n) ist (sind), hätte ich ein Backup machen sollen (Oh, Neuling-Alarm), oder ist das passiert, als ich die .pack-Datei entpackt habe? Und ist der “Schuld”, den ich zurückkopiere, tatsächlich eine saubere Datei, dh nicht beschädigt?
(Ich denke, es ist nur fair, Ihnen zu sagen, dass ich anfangs durch einen einfachen Bindestrich in Torvalds Datei zwischen “git” und “fsck” verwirrt war. Also bin ich JA WIRKLICH neu dabei.)
FEHLERLISTE
Ursprünglicher Fehler:
$ git status
fatal: object 016660b7605cfc2da85f631bbe809f7cb7962608 is corrupted
Fehler nach dem Verschieben eines beschädigten Objekts:
$ git log --raw --all
fatal: object 016660b7605cfc2da85f631bbe809f7cb7962608 is corrupted
$ cat packed-refs
cat: packed-refs: No such file or directory
$ git fsck --full
fatal: object 016660b7605cfc2da85f631bbe809f7cb7962608 is corrupted
Nach dem Verschieben der Datei wieder heraus:
$ git fsck --full`
error: HEAD: invalid sha1 pointer 016660b7605cfc2da85f631bbe809f7cb7962608
error: refs/heads/RPG does not point to a valid object!
dangling tree 2c1033501b82e301d47dbf53ba0a199003af25a8
dangling blob 531aca5783033131441ac7e132789cfcad82d06d
dangling blob 74a47ff40a8c5149a8701c2f4b29bba408fa36f5
dangling blob b8df4d9751c0518c3560e650b21a182ea6d7bd5e
dangling blob fc2d15aead4bd0c197604a9f9822d265bb986d8b
Nach dem Entpacken der .pack-Datei:
$ git log
fatal: bad object HEAD
$ cat packed-refs
cat: packed-refs: No such file or directory
$ git fsck --full
error: HEAD: invalid sha1 pointer 016660b7605cfc2da85f631bbe809f7cb7962608
error: refs/heads/RPG does not point to a valid object!
dangling tree 2c1033501b82e301d47dbf53ba0a199003af25a8
dangling blob 531aca5783033131441ac7e132789cfcad82d06d
dangling blob 74a47ff40a8c5149a8701c2f4b29bba408fa36f5
dangling blob b8df4d9751c0518c3560e650b21a182ea6d7bd5e
dangling blob fc2d15aead4bd0c197604a9f9822d265bb986d8b
Könnten Sie Ihre Frage bearbeiten und Links zu den von Ihnen erwähnten Artikeln hinzufügen, damit wir sehen können, was Sie getan haben? Ich bin mir nicht sicher, was Sie sonst mit “Entpacken der .pack-Datei” meinen, obwohl dies sicherlich kein Backup ist – die Pack-Datei ist nur eine Reihe von Objekten, die in eine Datei delta-komprimiert wurden. Eine gute Möglichkeit, ein Git-Repository zu sichern, besteht darin, es zu klonen!
– Kaskabel
31. August 2010 um 23:15 Uhr
Wenn diese SO-Frage stackoverflow.com/questions/801577/… der zweite Artikel ist, den Sie erwähnen, klingt es nicht so, als wäre es derselbe Fehler, den Sie erwähnt haben – es sei denn, Sie haben wirklich alle diese Fehler erhalten. Könnten Sie auch die genauen Fehler posten, die Sie erhalten?
– Kaskabel
31. August 2010 um 23:20 Uhr
Und was war das letzte, was Sie davor in Ihrem Repo gemacht haben? Nur für den unwahrscheinlichen Fall, dass es sich nicht um einen Festplattenfehler handelt …
– Kaskabel
31. August 2010 um 23:21 Uhr
Ich habe einige Schritte gekürzt, hauptsächlich aufgrund identischer Fehler oder früherer Funktionen. Ich habe auch einige Schritte ausgelassen, die ähnliche Ergebnisse wie die erwähnten Artikel hatten, und andere, bei denen ich einfach mit dem Computer gerungen habe (hässlich). Das letzte, was ich getan habe, war ein Commit für einige Dateien in Ordner3 in den Zweig, auf dem ich mich befand (nicht Master). Unmittelbar danach habe ich meinen Computer ausgeschaltet. Falls es hilft, manchmal schaltet sich mein Computer manchmal nicht vollständig aus, und dieses unvollständige Herunterfahren trat zu dieser Zeit auch auf. Bei Bedarf kann ich die gesamte Session posten.
– Bescheidener Pinguin
1. September 10 um 3:06
Übrigens, wenn Sie @Jefromi in Ihren Kommentar einfügen, wird SO mich darüber informieren, damit ich mich früher bei Ihnen melden kann. (Dies geschieht automatisch, wenn Sie meine Antwort kommentieren; dort ist dies nicht erforderlich.)
– Kaskabel
1. September 10 um 14:38 Uhr
Cascabel
Okay, also. Aus der zweiten Fehlermeldung können wir ersehen, dass das beschädigte Objekt, das Sie verschoben haben, ein Commit war. (HEAD hat darauf gezeigt!) Leider bedeutet dies, dass es schwierig ist, es manuell zu reparieren. (Mit “schwer” meine ich wahrscheinlich unmöglich, es sei denn, Sie können sich genau erinnern, was die Commit-Nachricht war und wann Sie das Commit durchgeführt haben.) Glücklicherweise bedeutet dies, dass es einfach ist, ein neues Commit mit demselben Dateiinhalt wiederzubeleben – das werden Sie muss nur eine neue Nachricht dafür schreiben.
Bevor Sie beginnen, werfen Sie einen Blick auf den Inhalt von .git/HEAD – Wenn es sich um einen Zweignamen handelt, merken Sie sich das für später.
Zuerst müssen wir herausfinden, was der Elternteil dieses Commits hätte sein sollen. Sie können verwenden git reflog um sich das Reflog von HEAD anzusehen und den SHA1 zu finden, wo HEAD war, kurz bevor Sie 016660b festgeschrieben haben. Es sollte etwa so aussehen:
016660b HEAD@{n}: commit: <subject of commit>
1234abc HEAD@{n-1}: ...
Sie können den SHA1 der vorherigen Position von HEAD kopieren und diesen Commit auschecken:
git checkout 1234abc
Dann können Sie im Baum lesen, dass Ihr beschädigtes Commit Folgendes hatte:
Nun, hier gibt es einige Fragen darüber, was mit Ihren Zweigen hätte passieren sollen. Wenn HEAD auf einen Zweig (z. B. Master) verwies, der wiederum auf das beschädigte Commit verwies, wollen wir das auf jeden Fall reparieren:
git branch -d master # remove the original master branch
git checkout -b master # recreate it here
Wenn es andere Zweige gibt, die das beschädigte Commit enthielten, müssen Sie diese ebenfalls wiederherstellen – lassen Sie es mich wissen, wenn Sie dabei Hilfe benötigen.
Mit beschädigter Datei verschoben: $ git reflog fatal: Bad Object HEAD Mit beschädigter Datei vorhanden: $ git reflog fatal: Objekt 016660b7605cfc2da85f631bbe809f7cb7962608 ist beschädigt Ich habe das Handbuch gelesen und versucht: $ git reflog show HEAD@{1} Was mir Aktivität von 1 gab bis 12, und dann bei 1 neu gestartet und bis zum ersten Pull fortgesetzt, den ich an meinen Repositories durchgeführt hatte. Ist dieser Neustart typisch für den Befehl?
– Bescheidener Pinguin
2. September 10 um 3:36 Uhr
Weiter geht’s… $ git checkout bcbd203 #was HEAD@{1} fatal war: Objekt 016660b7605cfc2da85f631bbe809f7cb7962608 ist beschädigt Soll ich die Datei einfach auslagern und den Checkout erneut versuchen? Entschuldigung für das Fehlen einer benutzerfreundlichen Formatierung in diesen Kommentaren. Ich kenne derzeit keinen besseren Weg, dies zu tun.
– Bescheidener Pinguin
2. September 10 um 3:40 Uhr
@Humble: Hoppla, tut mir leid. Mir ist das noch nicht passiert, also habe ich ungetestete Dinge geschrieben. Ich wusste nicht, dass Reflog tatsächlich versucht hat, die Objekte zu lesen! Wie auch immer, solange Sie herausgefunden haben, was der vorherige Commit war, ist dieser Teil gut. (Man hätte sich auch direkt anschauen können .git/logs/HEAD)
– Kaskabel
02.09.10 um 03:52
@Humble: Für die Kasse … ja, so ziemlich alles, was Sie tun müssen, damit es gelingt. Bewegen Sie das beschädigte Objekt heraus, und wenn das nicht funktioniert … versuchen Sie es checkout -fdann versuche es reset --hard <SHA1>… sobald es funktioniert, sollten Sie weitermachen können.
– Kaskabel
02.09.10 um 03:53
Aha! Git tut einfach sein Bestes, damit Sie keine Informationen wegwerfen – leider wissen wir, dass wir das tun müssen. Du wirst den alten Zweig auf die eine oder andere Weise loswerden müssen. Wenn git branch -f master; git checkout master funktioniert nicht, gehen Sie einfach in das .git-Verzeichnis und ziehen Sie es selbst heraus – entfernen Sie es refs/heads/master und logs/refs/heads/masterdann erstellen Sie es normal.
– Kaskabel
02.09.10 um 21:41 Uhr
unterstrich_d
FWIW, hier ist eine Antwort, die praktischer ist als viele der hoffnungslos optimistischen Antworten auf andere Fragen zu Korruption git Repos – von denen die meisten die unbegründete Annahme machen, dass das arme OP “einfach vom entfernten Ursprung neu klonen kann!” Hmm. Aber. Warte kurz. Was ist, wenn Ich bin der Ursprung?
Der Horror
Die Geschichte beginnt mit dem Versuch, einen einfachen auszuführen git gc --aggressive offenbarte, dass, ohne dass ich es wusste, irgendwann meine – völlig lokale – git repo war irgendwie komplett abgespritzt worden: Es war nicht mehr in der Lage, mehr als vor ein paar Monaten zu protokollieren, wodurch der Großteil seiner Geschichte verloren ging, und schrie guttural, wenn es darum gebeten wurde git fsck --full | grep -v dangling. Mehrere Objekte wurden als verloren von identifiziert git fsck.
git-repair: Minimierung erschreckender Handarbeit seit 2014
Nachdem ich in Panik geriet und viele Fragen mit überbewerteten schlechten Antworten fand, sagte ich nur: “Klonen Sie einfach vom entfernten Ursprung neu!” – was, lassen Sie mich darauf eingehen, ich nicht habe, weil Ich bin der Ursprung – Ich fand git-repairtat eine einfache sudo aptitude install git-repairund lassen Sie es all die mühsamen automatisierbaren Korrekturen durchführen, die mich wahrscheinlich Stunden gedauert hätten (Bitte: Führen Sie es auf einer Kopie Ihres beschädigten Repos aus [duh], ohne --force!)
Das half, die Menge an Horror zu reduzieren, von der berichtet wurde git fsck --full | grep -v dangling. Aber Dinge über Mitte August hinaus waren immer noch unerreichbar.
Insbesondere schien sich alles um einen Commit zu drehen, der nicht abgerufen werden konnte. Wie könnte ich es wiederherstellen? Die Suche nach Stack Overflow war keine große Hilfe!
Du hast ein Backup, richtig?
Hier hatte ich das Glück eine Sicherung haben ab Ende Nov. Du machst Backups, richtig? In meinem Fall war es eine manuelle Zip-Datei des Repos (meine tägliche Backup-Routine ist eine schreckliche inkrementelle tar Sache, die ich eigentlich nie getestet habe … a-hust) … aber Puh, es war gut genug. Es hatte nicht die Demütigung erlitten, die mein Live-Repo heimgesucht hatte.
Aber das fehlende Objekt schien nicht einfach in diesem Backup gespeichert zu sein .git/objects/XY/RESTOFHASHBLAHBLAHBLAH. Das liegt wahrscheinlich daran, dass es sich um ein Commit und nicht um eine Datei handelte. Ich weiß nicht! git ist Zauberei für mich, für immer jenseits meines Fassungsvermögens. Ich brauchte nur schnell eine Lösung. Sind wir nicht deswegen alle hier?
Stellen Sie Objekte aus einem Backup wieder her (das Sie haben, oder?)
Mit dem Backup jetzt in der Hand, hatte ich eine urkomisch dumme Idee, sagte: „Das kann auf keinen Fall funktionieren!“ Und fand das sofort einfach naiv cp -fr /path/to/repo_backup/.git/objects/* /path/to/repo_git-repaired/.git/objects zu Datei zusammenführen.git/objects Verzeichnis des Backups in sein Gegenstück in meinem beschädigten, etwas reparierten Repo … funktionierte, um den gesamten Verlauf wiederherzustellen – gleich zurück zum guten alten initial commit lol. Die Lösung beweisen: git fsck --full war jetzt auch glücklich (trotz aller baumelnden Teile).
Ich habe dann Backups der aktiven/beschädigten, teilweise reparierten und scheinbar wiederhergestellten Repos auf ein separates Laufwerk gemacht, falls ich sie noch einmal benötige.
Sie sollten diese Methodik und diesen Befehl noch einmal überprüfen, bevor Sie sie ausführen, oder vielleicht einen viel besseren Weg finden, an den ich zu faul denke. Ich weiß nicht. Aber für mich hat es mein Repo gerettet. Und zum Thema Zweitmeinung, was ich sage…
Unendliche Haftungsausschlüsse in unendlichen Kombinationen
Nun, all dies kommt natürlich mit Vorbehalten: du musst Probieren Sie alles auf einer Kopie Ihres beschädigten Repos aus, lesen Sie die gesamte Dokumentation, ziehen Sie in Betracht, etwas vorsichtiger zu sein als ich (das erzwungene cp Befehl) und mich nicht für absolut alles, was schief geht, verantwortlich oder haftbar zu machen* … aber es gibt Ihnen etwas Besseres zu versuchen, als ‘einfach vom entfernten Ursprung neu zu klonen!’, oder?
* Wenn aber alles geht Rechts, eine große Spende kann in Ordnung sein. 😉
Wenn mich jemand braucht, werde ich misstrauisch in die Richtung meines Laufwerks starren und hoffentlich eine Backup-Routine entwickeln, deren Wiederherstellung (wenn überhaupt) keine zweistelligen Stunden in Anspruch nimmt, und vielleicht sogar welche bekommen Schlaf.
Hallo, ich kann den Befehl git-repair nicht verwenden, ich habe ‘git git-repair’ ‘git-repair’ auf dem Mac versucht, nichts funktioniert, bitte helfen Sie
– Halid
22. Juli 17 um 11:21 Uhr
Wie in meinem Post erwähnt, natürlich git-repair funktioniert nicht, wenn Sie es nicht installiert haben. Ich weiß nichts über macOS, aber nehme an, Sie können es über einen Paketmanager wie Homebrew bekommen. Oder wenn nicht, ist es sehr wahrscheinlich, dass jemand es irgendwo zusammengestellt und auf seiner eigenen Website als Download angeboten hat. Sie müssen nur danach suchen.
– Unterstrich_d
23. Juli 17 um 9:14 Uhr
Ich habe es geklont, erstellt und auf meinem Mac installiert, kenne aber den Befehl nicht, es zu verwenden
– Halid
23. Juli 17 um 11:07 Uhr
Also Dokumentation lesen? Ich bin mir nicht sicher, was Sie von mir erwarten.
– Unterstrich_d
23. Juli 17 um 14:50 Uhr
Ich hatte das gleiche Problem. Mein Problem wurde jedoch durch das Ändern der Berechtigungen der .git/objects-Ordner und Unterordner (rekursiv) auf dem Server gelöst. Etwas wie:
chmod -R 770 .git/objects
Ich denke, das ist nicht dein Problem, aber in meinem Fall wurde es gelöst.
.
8213200cookie-checkWie stellen Sie ein beschädigtes Objekt in einem Git-Repository wieder her (für Neulinge)?yes
Könnten Sie Ihre Frage bearbeiten und Links zu den von Ihnen erwähnten Artikeln hinzufügen, damit wir sehen können, was Sie getan haben? Ich bin mir nicht sicher, was Sie sonst mit “Entpacken der .pack-Datei” meinen, obwohl dies sicherlich kein Backup ist – die Pack-Datei ist nur eine Reihe von Objekten, die in eine Datei delta-komprimiert wurden. Eine gute Möglichkeit, ein Git-Repository zu sichern, besteht darin, es zu klonen!
– Kaskabel
31. August 2010 um 23:15 Uhr
Wenn diese SO-Frage stackoverflow.com/questions/801577/… der zweite Artikel ist, den Sie erwähnen, klingt es nicht so, als wäre es derselbe Fehler, den Sie erwähnt haben – es sei denn, Sie haben wirklich alle diese Fehler erhalten. Könnten Sie auch die genauen Fehler posten, die Sie erhalten?
– Kaskabel
31. August 2010 um 23:20 Uhr
Und was war das letzte, was Sie davor in Ihrem Repo gemacht haben? Nur für den unwahrscheinlichen Fall, dass es sich nicht um einen Festplattenfehler handelt …
– Kaskabel
31. August 2010 um 23:21 Uhr
Ich habe einige Schritte gekürzt, hauptsächlich aufgrund identischer Fehler oder früherer Funktionen. Ich habe auch einige Schritte ausgelassen, die ähnliche Ergebnisse wie die erwähnten Artikel hatten, und andere, bei denen ich einfach mit dem Computer gerungen habe (hässlich). Das letzte, was ich getan habe, war ein Commit für einige Dateien in Ordner3 in den Zweig, auf dem ich mich befand (nicht Master). Unmittelbar danach habe ich meinen Computer ausgeschaltet. Falls es hilft, manchmal schaltet sich mein Computer manchmal nicht vollständig aus, und dieses unvollständige Herunterfahren trat zu dieser Zeit auch auf. Bei Bedarf kann ich die gesamte Session posten.
– Bescheidener Pinguin
1. September 10 um 3:06
Übrigens, wenn Sie @Jefromi in Ihren Kommentar einfügen, wird SO mich darüber informieren, damit ich mich früher bei Ihnen melden kann. (Dies geschieht automatisch, wenn Sie meine Antwort kommentieren; dort ist dies nicht erforderlich.)
– Kaskabel
1. September 10 um 14:38 Uhr