하드 디스크 오류가 발생하여 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 ..)이 출력되면 이제 모든 작업이 완료된 것입니다!
-
고장난 이전 버전이라고 가정하면 가장 쉬운 방법은 다음과 같습니다.
git log --raw --all --full-history -- subdirectory/my-magic-file
그러면 해당 파일에 대한 전체 로그가 표시됩니다 (가지고있는 트리가 최상위 트리가 아닐 수 있으므로 자신이 어떤 하위 디렉터리에 있었는지 알아 내야합니다). 이제 다시 생성 할 수 있습니다. 해시 개체가있는 개체가 다시 누락되었습니다.
-
커밋, 트리 또는 블롭이 누락 된 모든 참조 목록을 가져 오려면 :
$ git for-each-ref --format='%(refname)' | while read ref; do git rev-list --objects $ref >/dev/null || echo "in $ref"; done
일반 브랜치 -d 또는 태그 -d 명령을 사용하여 이러한 참조 중 일부를 제거하는 것은 불가능할 수 있습니다. git이 손상을 발견하면 죽기 때문입니다. 따라서 배관 명령 git update-ref -d $ ref를 대신 사용하십시오. 로컬 브랜치의 경우이 명령은 .git / config에 오래된 브랜치 구성을 남길 수 있습니다. 수동으로 삭제할 수 있습니다 ([branch “$ ref”] 섹션을 찾으십시오).
-
모든 ref가 정리 된 후에도 reflog에 여전히 깨진 커밋이있을 수 있습니다. git reflog expire –expire = now –all을 사용하여 모든 reflog를 지울 수 있습니다. 모든 리플 로그를 잃지 않으려면 개별 ref에서 깨진 리플 로그를 검색 할 수 있습니다.
$ (echo HEAD; git for-each-ref --format='%(refname)') | while read ref; do git rev-list -g --objects $ref >/dev/null || echo "in $ref"; done
(git rev-list에 추가 된 -g 옵션을 참고하십시오.) 그런 다음 각각에 git reflog expire –expire = now $ ref를 사용하십시오. 모든 깨진 refs 및 reflog가 사라지면 저장소가 깨끗한 지 확인하기 위해 git fsck –full을 실행하십시오. 매달린 물체는 괜찮습니다.
아래에서 현명하게 사용하지 않을 경우 잠재적으로 git 저장소의 데이터를 잃을 수있는 명령의 고급 사용법을 찾을 수 있으므로 실수로 git에 추가 손상을 입히기 전에 백업을 만드십시오. 자신이 무엇을하고 있는지 알고 있다면 자신의 위험을 감수하십시오.
가져온 후 업스트림 분기의 맨 위에 현재 분기를 가져 오려면 다음을 수행하십시오.
$ git pull --rebase
새 브랜치를 체크 아웃하고 이전 브랜치를 삭제할 수도 있습니다.
$ git checkout -b new_master origin/master
제거를 위해 git에서 손상된 개체를 찾으려면 다음 명령을 시도하십시오.
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
OSX sed -E
의 경우 sed -r
.
다른 아이디어는 팩 파일에서 모든 개체를 압축 해제하여 .git / objects 내의 모든 개체를 다시 생성하는 것이므로 저장소 내에서 다음 명령을 실행 해보십시오.
$ 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
위의 방법이 도움이되지 않으면 다른 저장소에서 git 객체를 rsync하거나 복사 할 수 있습니다.
$ 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
다음과 같이 결제를 시도 할 때 끊어진 분기를 수정하려면 :
$ git checkout -f master
fatal: unable to read tree 5ace24d474a9535ddd5e6a6c6a1ef480aecf2625
제거하고 업스트림에서 다시 체크 아웃하십시오.
$ git branch -D master
$ git checkout -b master github/master
git이 분리 된 상태로 들어가면 분리 master
된 분기를 확인 하고 병합하십시오.
또 다른 아이디어는 기존 마스터를 재귀 적으로 리베이스하는 것입니다.
$ git reset HEAD --hard
$ git rebase -s recursive -X theirs origin/master
또한보십시오:
- 손상된 저장소를 수정하기 위해 Blob 개체를 재구성하는 몇 가지 트릭입니다.
- 손상된 저장소를 수정하는 방법은 무엇입니까?
- 저장소에서 깨진 참조를 모두 제거하는 방법은 무엇입니까?
- 손상된 git 저장소를 수정하는 방법은 무엇입니까? (seeques)
- 손상된 git 저장소를 수정하는 방법은 무엇입니까? (qnundrum)
- Git과 함께 SourceTree를 사용할 때 오류 : ‘Summary’실패, 코드 128 : 치명적 : 트리를 읽을 수 없음
- 손상된 Git 베어 리포지토리 복구
- 손상된 git 저장소 복구
- Git 오류 수정 방법 : 개체가 empy / 손상되었습니다.
- git fatal 진단 및 수정 방법 : 트리를 읽을 수 없음
- 이 자식 오류를 처리하는 방법
- 손상된 git 저장소를 수정하는 방법은 무엇입니까?
- Git의 다른 분기에있는 분기를 ‘병합’하는 대신 ‘덮어 쓰는’방법은 무엇입니까?
- git에서 마스터 브랜치를 완전히 다른 브랜치에서 대체하는 방법은 무엇입니까?
- 힘내 : “손상된 느슨한 개체”
- Git 재설정 = 치명적 : 트리를 읽을 수 없음
답변
다음은 손상된 Blob 개체에서 복구하기 위해 수행 한 단계입니다.
1) 손상된 Blob 식별
git fsck --full
error: inflate: data stream error (incorrect data check)
error: sha1 mismatch 241091723c324aed77b2d35f97a05e856b319efd
error: 241091723c324aed77b2d35f97a05e856b319efd: object corrupt or missing
...
손상된 blob은 241091723c324aed77b2d35f97a05e856b319efd입니다.
2) 손상된 blob을 안전한 장소로 이동 (만약 경우에 대비)
mv .git/objects/24/1091723c324aed77b2d35f97a05e856b319efd ../24/
3) 손상된 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
부모 해시는 0716831e1a6c8d3e6b2b541d21c4748cc0ce7180 입니다.
4) 손상된 Blob에 해당하는 파일 이름 가져 오기
git ls-tree 0716831e1a6c8d3e6b2b541d21c4748cc0ce7180
...
100644 blob 241091723c324aed77b2d35f97a05e856b319efd dump.tar.gz
...
백업 또는 업스트림 git 저장소에서이 특정 파일을 찾으십시오 (제 경우에는 dump.tar.gz입니다 ). 그런 다음 로컬 저장소 내부에 복사하십시오.
5) git 개체 데이터베이스에 이전에 손상된 파일 추가
git hash-object -w dump.tar.gz
6) 축하하세요!
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)
답변
답변
다음은 백업이 손상되었거나 부분적으로 손상된 백업이있는 경우에 도움이 될 수있는 두 가지 기능입니다 (손상된 개체를 백업하는 경우 발생할 수 있음).
복구하려는 저장소에서 둘 다 실행하십시오.
표준 경고 : 정말 절박하고 (손상된) 저장소를 백업 한 경우에만 사용하십시오. 이것은 아무것도 해결하지 못할 수도 있지만 적어도 부패 수준을 강조해야합니다.
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과 같은 변경 사항을 다시 추가했습니다.