Wie Git Objekte beschädigt durch Festplattenfehler erholen?
-
03-07-2019 - |
Frage
Ich habe einen Festplattenfehler hat, die in einigen Dateien einer Git-Repository führte immer beschädigt. Wenn git fsck --full
läuft ich folgende Ausgabe:
error: .git/objects/pack/pack-6863e0a0e4b4ded6090fac5d12eba6ca7346b19c.pack SHA1 checksum mismatch
error: index CRC mismatch for object 6c8cae4994b5ec7891ccb1527d30634997a978ee from .git/objects/pack/pack-6863e0a0e4b4ded6090fac5d12eba6ca7346b19c.pack at offset 97824129
error: inflate: data stream error (invalid code lengths set)
error: cannot unpack 6c8cae4994b5ec7891ccb1527d30634997a978ee from .git/objects/pack/pack-6863e0a0e4b4ded6090fac5d12eba6ca7346b19c.pack at offset 97824129
error: inflate: data stream error (invalid stored block lengths)
error: failed to read object 0dcf6723cc69cc7f91d4a7432d0f1a1f05e77eaa at offset 276988017 from .git/objects/pack/pack-6863e0a0e4b4ded6090fac5d12eba6ca7346b19c.pack
fatal: object 0dcf6723cc69cc7f91d4a7432d0f1a1f05e77eaa is corrupted
Ich habe Sicherungen des Repository, aber die einzige Sicherung, die die Paketdatei enthält es bereits beschädigt. Deshalb denke ich, dass muss ich einen Weg herauszufinden, die einzelnen Objekte aus verschiedenen Sicherungen abzurufen und irgendwie Git anweisen, nur mit richtigen Objekte eine neue Packung zu erzeugen.
Können Sie bitte geben Sie mir Hinweise, wie mein Repository zu beheben?
Lösung
In einigen früheren Backups, Ihre schlechten Objekte in verschiedenen Dateien gepackt worden sein oder lose Gegenstände noch sein. So Ihre Objekte gewonnen werden können.
Es scheint, gibt es ein paar schlechten Objekte in der Datenbank befindet. So können Sie es die manuelle Art und Weise tun könnte.
Durch git hash-object
, git mktree
und git commit-tree
die Objekte nicht schreiben, weil sie in der Packung zu finden sind, dann beginnen dies zu tun:
mv .git/objects/pack/* <somewhere>
for i in <somewhere>/*.pack; do
git unpack-objects -r < $i
done
rm <somewhere>/*
(Ihre Pakete werden aus dem Repository ausgezogen und wieder ausgepackt darin, nur die guten Objekte sind nun in der Datenbank)
Sie können tun:
git cat-file -t 6c8cae4994b5ec7891ccb1527d30634997a978ee
und prüfen Sie den Typ des Objekts an.
Wenn der Typ Blob:. Den Inhalt der Datei aus früheren Backups abrufen (mit git show
oder git cat-file
oder git unpack-file
, dann können Sie git hash-object -w
das Objekt in der aktuellen Repository neu zu schreiben
Wenn der Typ ist Baum: Sie git ls-tree
verwenden könnten den Baum aus früheren Backups zu erholen; dann git mktree
es wieder in Ihrem aktuellen Repository zu schreiben.
Wenn der Typ begehen. Das gleiche mit git show
, git cat-file
und git commit-tree
Natürlich würde ich ein Backup Ihre ursprüngliche Arbeitskopie vor, diesen Prozess zu starten.
Werfen Sie auch einen Blick auf Wie verderbtes Blob Objekt erholen.
Andere Tipps
Banengusk legte mich auf dem richtigen Weg. Für weitere Referenz möchte ich die Schritte posten Ich habe meine Repository Korruption zu beheben. Ich habe das Glück, alle benötigten Objekte zu finden, entweder in älteren Pack oder in Repository-Backups.
# Unpack last non-corrupted pack
$ mv .git/objects/pack .git/objects/pack.old
$ git unpack-objects -r < .git/objects/pack.old/pack-012066c998b2d171913aeb5bf0719fd4655fa7d0.pack
$ git log
fatal: bad object HEAD
$ cat .git/HEAD
ref: refs/heads/master
$ ls .git/refs/heads/
$ cat .git/packed-refs
# pack-refs with: peeled
aa268a069add6d71e162c4e2455c1b690079c8c1 refs/heads/master
$ git fsck --full
error: HEAD: invalid sha1 pointer aa268a069add6d71e162c4e2455c1b690079c8c1
error: refs/heads/master does not point to a valid object!
missing blob 75405ef0e6f66e48c1ff836786ff110efa33a919
missing blob 27c4611ffbc3c32712a395910a96052a3de67c9b
dangling tree 30473f109d87f4bcde612a2b9a204c3e322cb0dc
# Copy HEAD object from backup of repository
$ cp repobackup/.git/objects/aa/268a069add6d71e162c4e2455c1b690079c8c1 .git/objects/aa
# Now copy all missing objects from backup of repository and run "git fsck --full" afterwards
# Repeat until git fsck --full only reports dangling objects
# Now garbage collect repo
$ git gc
warning: reflog of 'HEAD' references pruned commits
warning: reflog of 'refs/heads/master' references pruned commits
Counting objects: 3992, done.
Delta compression using 2 threads.
fatal: object bf1c4953c0ea4a045bf0975a916b53d247e7ca94 inconsistent object length (6093 vs 415232)
error: failed to run repack
# Check reflogs...
$ git reflog
# ...then clean
$ git reflog expire --expire=0 --all
# Now garbage collect again
$ git gc
Counting objects: 3992, done.
Delta compression using 2 threads.
Compressing objects: 100% (3970/3970), done.
Writing objects: 100% (3992/3992), done.
Total 3992 (delta 2060), reused 0 (delta 0)
Removing duplicate objects: 100% (256/256), done.
# Done!
Versuchen Sie, die folgenden Befehle auf dem ersten (re-run wieder, wenn nötig):
$ git fsck --full
$ git gc
$ git gc --prune=today
$ git fetch --all
$ git pull --rebase
Und dann haben Sie immer noch die Probleme, versuchen Sie folgende Möglichkeiten:
-
all korrupt Objekte entfernen, z.
fatal: loose object 91c5...51e5 (stored in .git/objects/06/91c5...51e5) is corrupt $ rm -v .git/objects/06/91c5...51e5
-
alle leeren Objekte entfernen, z.
error: object file .git/objects/06/91c5...51e5 is empty $ find .git/objects/ -size 0 -exec rm -vf "{}" \;
-
überprüfen "broken link" Nachricht von:
git ls-tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
Dies wird erzählt, was die korrupte BLOB-Datei kam!
-
Datei wiederherzustellen, könnten Sie wirklich glücklich sein, und es kann die Version, die Sie bereits überprüft haben, in Ihrem Arbeits Baum aus:
git hash-object -w my-magic-file
erneut, und wenn es die fehlenden SHA1-Ausgänge (4b945 ..) Sie jetzt fertig!
-
unter der Annahme, dass es einige ältere Version war, die gebrochen wurde, ist der einfachste Weg, es zu tun, ist zu tun:
git log --raw --all --full-history -- subdirectory/my-magic-file
und zeigen Ihnen das ganze Protokoll für diese Datei (bitte merken, dass der Baum nicht die Top-Level-Baum sein hatte können, damit Sie heraus müssen, welche das Unterverzeichnis war es in auf eigene Faust), dann können Sie neu erstellen nun das fehlende Objekt mit Hash-Objekt wieder.
-
eine Liste aller Refs bekommen mit Commits, Bäume oder Blobs fehlt:
$ git for-each-ref --format='%(refname)' | while read ref; do git rev-list --objects $ref >/dev/null || echo "in $ref"; done
Es kann nicht möglich sein, einige dieser Refs -d, Befehle mit dem regulären Zweig -d oder Tag zu entfernen, da sie wird sterben, wenn git die Korruption bemerkt. So verwenden Sie die Sanitär-Befehl git update-ref -d $ ref statt. Beachten Sie, dass im Fall von lokalen Niederlassungen, dieser Befehl abgestanden Zweig Konfiguration hinter in .git / config verlassen. Es kann manuell gelöscht werden (suchen Sie nach dem [Zweig "$ ref"] -Abschnitt).
-
Nachdem alle Refs sauber sind, gibt es noch gebrochen Commits im reflog sein kann. Sie können alle reflogs löschen git jetzt mit --all reflog verfallen --expire =. Wenn Sie alle Ihre reflogs nicht verlieren möchten, können Sie die einzelnen Refs für defekte reflogs suchen:
$ (echo HEAD; git for-each-ref --format='%(refname)') | while read ref; do git rev-list -g --objects $ref >/dev/null || echo "in $ref"; done
(Beachten Sie die zusätzliche Option -g git rev-Liste.) Dann Verwendung git reflog verfallen --expire = Jetzt $ ref auf jeder von denen. Wenn alle gebrochenen Refs und reflogs weg sind, laufen git fsck --full, um zu überprüfen, ob das Repository sauber ist. Baumelnden Objekte sind in Ordnung.
Weiter unten finden Sie erweiterte Nutzung von Befehlen finden können, die möglicherweise Ihrer Daten in Ihrem Git Repository verloren führen kann, wenn nicht sinnvoll genutzt, so eine Sicherung vornehmen, bevor Sie versehentlich weitere Schäden tun, um Ihren git. Versuchen Sie, auf Ihr eigenes Risiko, wenn Sie wissen, was Sie tun.
Um den aktuellen Zweig auf dem Upstream-Zweig nach Abrufen ziehen:
$ git pull --rebase
Sie können auch versuchen, neue Niederlassung zur Kasse und löschen die alten:
$ git checkout -b new_master origin/master
Um das beschädigte Objekt in git zum Entfernen zu finden, versuchen Sie den folgenden Befehl ein:
while [ true ]; do f=`git fsck --full 2>&1|awk '{print $3}'|sed -r 's/(^..)(.*)/objects\/\1\/\2/'`; if [ ! -f "$f" ]; then break; fi; echo delete $f; rm -f "$f"; done
Für OSX verwenden sed -E
statt sed -r
.
Weitere Idee ist, alle Objekte aus dem Pack-Dateien entpacken Sie alle Objekte innerhalb .git / Objekte zu regenerieren, so versuchen Sie die folgenden Befehle in Ihrem Repository auszuführen:
$ cp -fr .git/objects/pack .git/objects/pack.bak
$ for i in .git/objects/pack.bak/*.pack; do git unpack-objects -r < $i; done
$ rm -frv .git/objects/pack.bak
Wenn oben nicht hilft, können Sie versuchen, die git Objekte aus einem anderen Repo in rsync oder kopieren, z.
$ rsync -varu git_server:/path/to/git/.git local_git_repo/
$ rsync -varu /local/path/to/other-working/git/.git local_git_repo/
$ cp -frv ../other_repo/.git/objects .git/objects
Um den abgebrochenen Ast zu beheben, wenn sie versuchen wie folgt zur Kasse:
$ git checkout -f master
fatal: unable to read tree 5ace24d474a9535ddd5e6a6c6a1ef480aecf2625
Versuchen Sie es und Check-out von stromaufwärts wieder zu entfernen:
$ git branch -D master
$ git checkout -b master github/master
Im Fall, wenn git Sie in abgenommenen Zustand erhalten, die master
Kasse und in den frei stehenden Zweig zusammenführen.
Eine weitere Idee ist es, die bestehenden Master rebase rekursiv:
$ git reset HEAD --hard
$ git rebase -s recursive -X theirs origin/master
Siehe auch:
- Einige Tricks zu rekonstruieren Blob Objekte, um ein beschädigtes Repository zu beheben.
- Wie ein gebrochenes Repository zu beheben?
- Wie alle zerbrochenen Refs aus einem Repository entfernen?
- Wie beschädigte git-Repository zu beheben? (Seeques)
- Wie beschädigte git-Repository zu beheben? (Qnundrum)
- Fehler bei der Verwendung von SourceTree mit Git: 'Zusammenfassung' ist fehlgeschlagen mit Code 128: fatal: unable Baum lesen
- Wiederherstellen eines korrupten Git Bare Repository
- Wiederherstellen eines beschädigten Git Repository
- Wie git Fehler zu beheben: Objekt ist empy / korrupt
- Wie zu diagnostizieren und zu beheben git fatal : nicht in der Lage Baum lesen
- Wie mit diesem git Fehler behandeln
- Wie beschädigte git-Repository zu beheben?
- Wie bin ich überschreiben ‘, anstatt 'merge', ein Zweig auf einem anderen Zweig in Git?
- Wie master Branch in Git ersetzen , ganz, von einem anderen Zweig?
- Git: "Korrupte loses Objekt"
- Git reset = fatal: unable Baum lesen
Hier sind die Schritte, die ich gefolgt von einem korrupten Blob-Objekt zu erholen.
1) Stellen Sie korrupte Blob
git fsck --full
error: inflate: data stream error (incorrect data check)
error: sha1 mismatch 241091723c324aed77b2d35f97a05e856b319efd
error: 241091723c324aed77b2d35f97a05e856b319efd: object corrupt or missing
...
Corrupt Blob ist 241091723c324aed77b2d35f97a05e856b319efd
2) Bewegen Sie korrupte Blob an einen sicheren Ort (für alle Fälle)
mv .git/objects/24/1091723c324aed77b2d35f97a05e856b319efd ../24/
3) Holen Eltern von korrupten Blob
git fsck --full
Checking object directories: 100% (256/256), done.
Checking objects: 100% (70321/70321), done.
broken link from tree 0716831e1a6c8d3e6b2b541d21c4748cc0ce7180
to blob 241091723c324aed77b2d35f97a05e856b319efd
Eltern Hash ist 0716831e1a6c8d3e6b2b541d21c4748cc0ce7180 .
4) Erhalten Sie Dateinamen zu korrumpieren blob entsprechenden
git ls-tree 0716831e1a6c8d3e6b2b541d21c4748cc0ce7180
...
100644 blob 241091723c324aed77b2d35f97a05e856b319efd dump.tar.gz
...
Sie finden diese bestimmte Datei in einem Backup oder im Upstream-Git Repository (in meinem Fall ist es dump.tar.gz ). Dann kopieren Sie sie irgendwo in Ihrem lokalen Repository.
5) In zuvor beschädigte Datei im Git-Objektdatenbank
git hash-object -w dump.tar.gz
6) Feiern Sie!
git gc
Counting objects: 75197, done.
Compressing objects: 100% (21805/21805), done.
Writing objects: 100% (75197/75197), done.
Total 75197 (delta 52999), reused 69857 (delta 49296)
Git Kasse kann tatsächlich auszusuchen einzelne Dateien von einer Revision. geben Sie einfach die Commit Hash und den Dateinamen. Detailliertere Informationen
Hier sind zwei Funktionen, die helfen können, ob die Sicherung beschädigt ist, oder Sie haben ein paar teilweise auch beschädigte Sicherungen (dies kann passieren, wenn Sie ein Backup der beschädigten Objekte). Führen Sie beide in den Repo Sie wiederherstellen versuchen. Standard Warnung: nur verwenden, wenn Sie wirklich verzweifelt sind und Sie haben Ihre (beschädigt) Repo gesichert. Dies könnte nicht alles lösen, aber zumindest sollte das Ausmaß der Korruption markieren. und fsck_rm_corrupted() {
corrupted='a'
while [ "$corrupted" ]; do
corrupted=$( \
git fsck --full --no-dangling 2>&1 >/dev/null \
| grep 'stored in' \
| sed -r 's:.*(\.git/.*)\).*:\1:' \
)
echo "$corrupted"
rm -f "$corrupted"
done
}
if [ -z "$1" ] || [ ! -d "$1" ]; then
echo "'$1' is not a directory. Please provide the directory of the git repo"
exit 1
fi
pushd "$1" >/dev/null
fsck_rm_corrupted
popd >/dev/null
unpack_rm_corrupted() {
corrupted='a'
while [ "$corrupted" ]; do
corrupted=$( \
git unpack-objects -r < "$1" 2>&1 >/dev/null \
| grep 'stored in' \
| sed -r 's:.*(\.git/.*)\).*:\1:' \
)
echo "$corrupted"
rm -f "$corrupted"
done
}
if [ -z "$1" ] || [ ! -d "$1" ]; then
echo "'$1' is not a directory. Please provide the directory of the git repo"
exit 1
fi
for p in $1/objects/pack/pack-*.pack; do
echo "$p"
unpack_rm_corrupted "$p"
done
ich beschlossen haben, dieses Problem etwas ändern wie git hinzuzufügen hinzufügen -A und git commit wieder.