У меня произошел сбой жесткого диска, в результате которого были повреждены некоторые файлы репозитория Git. При запуске git fsck --full
я получаю следующий результат:
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
У меня есть резервные копии репозитория, но единственная резервная копия, которая включает файл пакета, уже повреждена. Поэтому я думаю, что мне нужно найти способ получить отдельные объекты из разных резервных копий и каким-то образом проинструктировать Git создать новый пакет только с правильными объектами.
Не могли бы вы подсказать, как исправить мой репозиторий?
git
corruption
data-recovery
Христианин
источник
источник
.git
папки, конечно) в только что клонированное репо ... а затем сделалgit status
в новом репо ... git правильно обнаруживает все затронутые изменения в моих файлах, и я могу снова начать свою работу.Ответы:
В некоторых предыдущих резервных копиях плохие объекты могли быть упакованы в другие файлы или еще могут быть незакрепленными. Так что ваши объекты могут быть восстановлены.
Кажется, в вашей базе данных есть несколько плохих объектов. Так что вы можете сделать это вручную.
Из - за
git hash-object
,git mktree
иgit commit-tree
не писать объекты потому , что они находятся в пакете, а затем начать делать это:(Ваши пакеты перемещаются из репозитория и снова распаковываются в нем; теперь в базе данных находятся только хорошие объекты)
Ты можешь сделать:
и проверьте тип объекта.
Если типом является blob: получить содержимое файла из предыдущих резервных копий (с помощью
git show
илиgit cat-file
илиgit unpack-file
; тогда вы можетеgit hash-object -w
переписать объект в текущем репозитории.Если тип - дерево: вы можете использовать его
git ls-tree
для восстановления дерева из предыдущих резервных копий; затемgit mktree
снова записать его в текущий репозиторий.Если тип фиксации: то же самое с
git show
,git cat-file
иgit commit-tree
.Конечно, я бы сделал резервную копию вашей исходной рабочей копии перед тем, как начать этот процесс.
Также ознакомьтесь с разделом «Как восстановить поврежденный объект Blob» .
источник
.git/objects/pack/
неБаненгуск направил меня на верный путь. Для получения дополнительной информации я хочу опубликовать шаги, которые я предпринял, чтобы исправить повреждение моего репозитория. Мне посчастливилось найти все необходимые объекты либо в старых пакетах, либо в резервных копиях репозитория.
# 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!
источник
Сначала попробуйте выполнить следующие команды (при необходимости повторите попытку):
И тогда у вас все еще есть проблемы, попробуйте:
удалите все поврежденные объекты, например
удалите все пустые объекты, например
проверьте сообщение о неработающей ссылке:
Это сообщит вам, из какого файла был получен поврежденный объект!
для восстановления файла вам может очень повезти, и это может быть та версия, которую вы уже отметили в своем рабочем дереве:
снова, и если он выводит отсутствующий SHA1 (4b945 ..), все готово!
предполагая, что это была некоторая более старая версия, которая была сломана, самый простой способ сделать это - сделать:
и это покажет вам весь журнал для этого файла (пожалуйста, поймите, что дерево, которое у вас было, может не быть деревом верхнего уровня, поэтому вам нужно выяснить, в каком подкаталоге оно находилось самостоятельно), теперь вы можете воссоздать снова отсутствует объект с хеш-объектом.
чтобы получить список всех ссылок с отсутствующими коммитами, деревьями или каплями:
Возможно, невозможно удалить некоторые из этих ссылок с помощью обычных команд branch -d или tag -d, поскольку они умрут, если git заметит повреждение. Поэтому используйте команду сантехники git update-ref -d $ ref. Обратите внимание, что в случае локальных веток эта команда может оставить устаревшую конфигурацию ветки в .git / config. Его можно удалить вручную (ищите раздел [ветка «$ ref»]).
После того, как все ссылки будут чистыми, в журнале ссылок все еще могут быть неработающие коммиты. Вы можете очистить все рефлоги, используя git reflog expire --expire = now --all. Если вы не хотите терять все свои журналы, вы можете поискать в отдельных ссылках сломанные журналы:
(Обратите внимание на добавленную опцию -g для git rev-list.) Затем используйте git reflog expire --expire = now $ ref для каждого из них. Когда все сломанные ссылки и журналы исчезнут, запустите git fsck --full, чтобы проверить чистоту репозитория. Висячие предметы в порядке.
Ниже вы можете найти расширенное использование команд, которые потенциально могут привести к потере ваших данных в вашем репозитории git, если их не использовать с умом, поэтому сделайте резервную копию, прежде чем вы случайно нанесете дополнительный ущерб вашему git. Попробуйте на свой страх и риск, если знаете, что делаете.
Чтобы перетащить текущую ветку поверх восходящей ветки после выборки:
Вы также можете попробовать проверить новую ветку и удалить старую:
Чтобы найти поврежденный объект в git для удаления, попробуйте следующую команду:
Для OSX используйте
sed -E
вместоsed -r
.Другая идея - распаковать все объекты из файлов пакета, чтобы восстановить все объекты внутри .git / objects, поэтому попробуйте выполнить следующие команды в своем репозитории:
Если приведенное выше не помогает, вы можете попробовать rsync или скопировать объекты git из другого репо, например
Чтобы исправить сломанную ветку при попытке оформления заказа, выполните следующие действия:
Попробуйте удалить его и снова оформить заказ из восходящего потока:
В случае, если git переведет вас в отдельное состояние, проверьте
master
и объедините с ним отдельную ветку.Другая идея - рекурсивно переустановить существующий мастер:
Смотрите также:
источник
Вот шаги, которые я выполнил для восстановления после поврежденного объекта blob.
1) Определите поврежденный blob
Поврежденный большой двоичный объект - 241091723c324aed77b2d35f97a05e856b319efd
2) Переместите испорченный BLOB-объект в безопасное место (на всякий случай)
3) Получить родительский объект поврежденной капли
Родительский хеш - 0716831e1a6c8d3e6b2b541d21c4748cc0ce7180 .
4) Получите имя файла, соответствующее поврежденному BLOB-объекту
Найдите этот конкретный файл в резервной копии или в исходном репозитории git (в моем случае это dump.tar.gz ). Затем скопируйте его где-нибудь в локальном репозитории.
5) Добавить ранее поврежденный файл в базу объектов git
6) Празднуйте!
источник
git ls-tree 9504a07fb803edfdf0c1dd99c5d561274af87982 error: Could not read 19505205fd1f219993da9b75846fff3cf432152d
, и я также попробовал все это снова, без шага 2, и это привело кgit ls-tree 9504a07fb803edfdf0c1dd99c5d561274af87982 error: inflate: data stream error (invalid stored block lengths) fatal: failed to read object 19505205fd1f219993da9b75846fff3cf432152d: Invalid argument
Git checkout действительно может выбирать отдельные файлы из ревизии. Просто дайте ему хеш фиксации и имя файла. Более подробная информация здесь.
Я думаю, что самый простой способ безопасно исправить это - вернуться к новейшей незафиксированной резервной копии, а затем выборочно выбрать неповрежденные файлы из новых коммитов. Удачи!
источник
Вот две функции, которые могут помочь, если ваша резервная копия повреждена или у вас есть несколько частично поврежденных резервных копий (это может произойти при резервном копировании поврежденных объектов).
Запустите оба в репо, которое вы пытаетесь восстановить.
Стандартное предупреждение: используйте только в том случае, если вы действительно в отчаянии и сделали резервную копию своего (поврежденного) репо. Это может ничего не решить, но, по крайней мере, должно подчеркнуть уровень коррупции.
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
источник
Я решил эту проблему, чтобы снова добавить некоторые изменения, например git add -A и git commit.
источник