하드 디스크 오류로 손상된 Git 개체를 복구하는 방법은 무엇입니까?
하드 디스크 오류가 발생하여 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 hash-object
, git mktree
그리고 git commit-tree
그들이 팩에서 발견되기 때문에 개체를 작성하지,이 일을 시작합니다
mv .git/objects/pack/* <somewhere>
for i in <somewhere>/*.pack; do
git unpack-objects -r < $i
done
rm <somewhere>/*
(팩이 저장소에서 이동 한 후 다시 압축이 풀립니다. 이제 좋은 개체 만 데이터베이스에 있습니다.)
넌 할 수있어:
git cat-file -t 6c8cae4994b5ec7891ccb1527d30634997a978ee
개체의 유형을 확인하십시오.
유형이 blob 인 경우 : git show
또는 git cat-file
또는 사용 하여 이전 백업에서 파일의 내용을 검색 git unpack-file
한 다음 git hash-object -w
현재 저장소에서 객체를 다시 작성할 수 있습니다 .
유형이 트리 인 경우 : git ls-tree
이전 백업에서 트리를 복구하는 데 사용할 수 있습니다. 그런 다음 git mktree
현재 저장소에 다시 작성하십시오.
유형이 commit 인 경우 git show
, git cat-file
및과 동일 git commit-tree
합니다.
물론이 프로세스를 시작하기 전에 원본 작업 복사본을 백업합니다.
또한 손상된 Blob 개체를 복구하는 방법을 살펴보십시오 .
Banengusk 는 나를 올바른 길로 인도 했습니다. 추가 참조를 위해 저장소 손상을 수정하기 위해 취한 단계를 게시하고 싶습니다. 운 좋게도 이전 팩이나 저장소 백업에서 필요한 모든 개체를 찾을 수있었습니다.
# 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!
처음에 다음 명령을 시도하십시오 (필요한 경우 다시 실행하십시오).
$ git fsck --full
$ git gc
$ git gc --prune=today
$ git fetch --all
$ git pull --rebase
그리고 여전히 문제가 있습니다. 시도해보십시오.
모든 손상된 개체를 제거하십시오.
fatal: loose object 91c5...51e5 (stored in .git/objects/06/91c5...51e5) is corrupt $ rm -v .git/objects/06/91c5...51e5
모든 빈 개체를 제거합니다.
error: object file .git/objects/06/91c5...51e5 is empty $ find .git/objects/ -size 0 -exec rm -vf "{}" \;
다음 방법으로 "깨진 링크"메시지를 확인하십시오.
git ls-tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
이것은 손상된 blob이 어떤 파일에서 왔는지 알려줍니다!
파일을 복구하려면 정말 운이 좋을 수 있으며 작업 트리에서 이미 체크 아웃 한 버전 일 수 있습니다.
git hash-object -w my-magic-file
다시, 누락 된 SHA1 (4b945 ..)이 출력되면 이제 모든 작업이 완료된 것입니다!
assuming that it was some older version that was broken, the easiest way to do it is to do:
git log --raw --all --full-history -- subdirectory/my-magic-file
and that will show you the whole log for that file (please realize that the tree you had may not be the top-level tree, so you need to figure out which subdirectory it was in on your own), then you can now recreate the missing object with hash-object again.
to get a list of all refs with missing commits, trees or blobs:
$ git for-each-ref --format='%(refname)' | while read ref; do git rev-list --objects $ref >/dev/null || echo "in $ref"; done
It may not be possible to remove some of those refs using the regular branch -d or tag -d commands, since they will die if git notices the corruption. So use the plumbing command git update-ref -d $ref instead. Note that in case of local branches, this command may leave stale branch configuration behind in .git/config. It can be deleted manually (look for the [branch "$ref"] section).
After all refs are clean, there may still be broken commits in the reflog. You can clear all reflogs using git reflog expire --expire=now --all. If you do not want to lose all of your reflogs, you can search the individual refs for broken reflogs:
$ (echo HEAD; git for-each-ref --format='%(refname)') | while read ref; do git rev-list -g --objects $ref >/dev/null || echo "in $ref"; done
(Note the added -g option to git rev-list.) Then, use git reflog expire --expire=now $ref on each of those. When all broken refs and reflogs are gone, run git fsck --full in order to check that the repository is clean. Dangling objects are Ok.
Below you can find advanced usage of commands which potentially can cause lost of your data in your git repository if not used wisely, so make a backup before you accidentally do further damages to your git. Try on your own risk if you know what you're doing.
To pull the current branch on top of the upstream branch after fetching:
$ git pull --rebase
You also may try to checkout new branch and delete the old one:
$ git checkout -b new_master origin/master
To find the corrupted object in git for removal, try the following command:
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
For OSX, use sed -E
instead of sed -r
.
Other idea is to unpack all objects from pack files to regenerate all objects inside .git/objects, so try to run the following commands within your repository:
$ 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
If above doesn't help, you may try to rsync or copy the git objects from another repo, e.g.
$ 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
To fix the broken branch when trying to checkout as follows:
$ git checkout -f master
fatal: unable to read tree 5ace24d474a9535ddd5e6a6c6a1ef480aecf2625
Try to remove it and checkout from upstream again:
$ git branch -D master
$ git checkout -b master github/master
In case if git get you into detached state, checkout the master
and merge into it the detached branch.
Another idea is to rebase the existing master recursively:
$ git reset HEAD --hard
$ git rebase -s recursive -X theirs origin/master
See also:
- Some tricks to reconstruct blob objects in order to fix a corrupted repository.
- How to fix a broken repository?
- How to remove all broken refs from a repository?
- How to fix corrupted git repository? (seeques)
- How to fix corrupted git repository? (qnundrum)
- Error when using SourceTree with Git: 'Summary' failed with code 128: fatal: unable to read tree
- Recover A Corrupt Git Bare Repository
- Recovering a damaged git repository
- How to fix git error: object is empy / corrupt
- How to diagnose and fix git fatal: unable to read tree
- How to deal with this git error
- How to fix corrupted git repository?
- How do I 'overwrite', rather than 'merge', a branch on another branch in Git?
- How to replace master branch in git, entirely, from another branch?
- Git: "Corrupt loose object"
- Git reset = fatal: unable to read tree
Here are the steps I followed to recover from a corrupt blob object.
1) Identify corrupt blob
git fsck --full
error: inflate: data stream error (incorrect data check)
error: sha1 mismatch 241091723c324aed77b2d35f97a05e856b319efd
error: 241091723c324aed77b2d35f97a05e856b319efd: object corrupt or missing
...
Corrupt blob is 241091723c324aed77b2d35f97a05e856b319efd
2) Move corrupt blob to a safe place (just in case)
mv .git/objects/24/1091723c324aed77b2d35f97a05e856b319efd ../24/
3) Get parent of corrupt 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
Parent hash is 0716831e1a6c8d3e6b2b541d21c4748cc0ce7180.
4) Get file name corresponding to corrupt blob
git ls-tree 0716831e1a6c8d3e6b2b541d21c4748cc0ce7180
...
100644 blob 241091723c324aed77b2d35f97a05e856b319efd dump.tar.gz
...
Find this particular file in a backup or in the upstream git repository (in my case it is dump.tar.gz). Then copy it somewhere inside your local repository.
5) Add previously corrupted file in the git object database
git hash-object -w dump.tar.gz
6) Celebrate!
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 checkout can actually pick out individual files from a revision. Just give it the commit hash and the file name. More detailed info here.
I guess the easiest way to fix this safely is to revert to the newest uncommited backup and then selectively pick out uncorrupted files from newer commits. Good luck!
Here are two functions that may help if your backup is corrupted, or you have a few partially corrupted backups as well (this may happen if you backup the corrupted objects).
Run both in the repo you're trying to recover.
Standard warning: only use if you're really desperate and you have backed up your (corrupted) repo. This might not resolve anything, but at least should highlight the level of corruption.
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
and
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
I have resolved this problem to add some change like git add -A and git commit again.
참고URL : https://stackoverflow.com/questions/801577/how-to-recover-git-objects-damaged-by-hard-disk-failure
'development' 카테고리의 다른 글
EDMX 모델에서 특정 테이블을 빨리 찾으려면 어떻게합니까? (0) | 2020.09.02 |
---|---|
웹 API 라우팅-api / {controller} / {action} / {id} "dysfunctions"api / {controller} / {id} (0) | 2020.09.01 |
Git에서 고아 커밋 찾아보기 (0) | 2020.09.01 |
사용중인 Javascript 버전을 어떻게 알 수 있습니까? (0) | 2020.09.01 |
.d.ts없이 typescript의 외부 비 typescript 라이브러리를 어떻게 사용합니까? (0) | 2020.09.01 |