Chr*_*ian 92 git corruption data-recovery
我遇到了硬盘故障导致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
Run Code Online (Sandbox Code Playgroud)
我有存储库的备份,但包含包文件的唯一备份已经损坏了.所以我认为我必须找到一种方法从不同的备份中检索单个对象,并以某种方式指示Git生成一个只有正确对象的新包.
你能否告诉我如何修复我的存储库?
Dan*_*jul 82
在以前的一些备份中,您的坏对象可能已经打包在不同的文件中,或者可能是松散的对象.所以你的对象可能会被恢复.
看来你的数据库中有一些坏对象.所以你可以用手动的方式做到这一点.
因为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>/*
Run Code Online (Sandbox Code Playgroud)
(您的包将从存储库中移出,并在其中再次解压缩;只有好的对象现在在数据库中)
你可以做:
git cat-file -t 6c8cae4994b5ec7891ccb1527d30634997a978ee
Run Code Online (Sandbox Code Playgroud)
并检查对象的类型.
如果类型是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对象.
Chr*_*ian 38
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!
Run Code Online (Sandbox Code Playgroud)
ken*_*orb 17
首先尝试以下命令(如果需要,再次重新运行):
$ git fsck --full
$ git gc
$ git gc --prune=today
$ git fetch --all
$ git pull --rebase
Run Code Online (Sandbox Code Playgroud)
然后你还有问题,试试可以:
删除所有损坏的对象,例如
fatal: loose object 91c5...51e5 (stored in .git/objects/06/91c5...51e5) is corrupt
$ rm -v .git/objects/06/91c5...51e5
Run Code Online (Sandbox Code Playgroud)删除所有空对象,例如
error: object file .git/objects/06/91c5...51e5 is empty
$ find .git/objects/ -size 0 -exec rm -vf "{}" \;
Run Code Online (Sandbox Code Playgroud)通过以下方式检查"损坏的链接"消息:
git ls-tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
Run Code Online (Sandbox Code Playgroud)
这将告诉你腐败blob来自哪个文件!
要恢复文件,您可能真的很幸运,它可能是您已在工作树中检出的版本:
git hash-object -w my-magic-file
Run Code Online (Sandbox Code Playgroud)
再次,如果它输出缺少的SHA1(4b945 ..),你现在都完成了!
假设它是一些破旧的旧版本,最简单的方法是:
git log --raw --all --full-history -- subdirectory/my-magic-file
Run Code Online (Sandbox Code Playgroud)
这将显示该文件的整个日志(请注意您所拥有的树可能不是顶级树,因此您需要自己确定它所在的子目录),然后您现在可以重新创建再次丢失带有哈希对象的对象.
获取缺少提交,树或blob的所有引用的列表:
$ git for-each-ref --format='%(refname)' | while read ref; do git rev-list --objects $ref >/dev/null || echo "in $ref"; done
Run Code Online (Sandbox Code Playgroud)
可能无法使用常规分支-d或tag -d命令删除其中一些引用,因为如果git注意到损坏,它们将会死亡.所以请改用管道命令git update-ref -d $ ref.请注意,在本地分支的情况下,此命令可能会在.git/config中留下过时的分支配置.它可以手动删除(查找[branch"$ ref"]部分).
在所有refs都是干净的之后,reflog中的提交可能仍然存在.您可以使用git reflog expire --expire = now --all清除所有reflog.如果您不想丢失所有的reflog,可以在单个refs中搜索损坏的reflog:
$ (echo HEAD; git for-each-ref --format='%(refname)') | while read ref; do git rev-list -g --objects $ref >/dev/null || echo "in $ref"; done
Run Code Online (Sandbox Code Playgroud)
(注意git rev-list添加了-g选项.)然后,对每个使用git reflog expire --expire = now $ ref.当所有损坏的ref和reflog都消失后,运行git fsck --full以检查存储库是否干净.悬空物体还可以.
下面你可以找到命令的高级用法,如果没有明智地使用它们可能会导致你的git存储库中的数据丢失,所以在你不小心对你的git进行进一步的损害之前做一个备份.如果你知道自己在做什么,请自行承担风险.
在获取后将当前分支拉到上游分支的顶部:
$ git pull --rebase
Run Code Online (Sandbox Code Playgroud)
您也可以尝试签出新分支并删除旧分支:
$ git checkout -b new_master origin/master
Run Code Online (Sandbox Code Playgroud)
要在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
Run Code Online (Sandbox Code Playgroud)
对于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
Run Code Online (Sandbox Code Playgroud)
如果上面没有帮助,您可以尝试rsync或从另一个repo复制git对象,例如
$ 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
Run Code Online (Sandbox Code Playgroud)
在尝试签出时修复损坏的分支,如下所示:
$ git checkout -f master
fatal: unable to read tree 5ace24d474a9535ddd5e6a6c6a1ef480aecf2625
Run Code Online (Sandbox Code Playgroud)
尝试将其删除并再次从上游结帐:
$ git branch -D master
$ git checkout -b master github/master
Run Code Online (Sandbox Code Playgroud)
如果git让你进入分离状态,请检查master并合并分离的分支.
另一个想法是递归地重新定义现有的master:
$ git reset HEAD --hard
$ git rebase -s recursive -X theirs origin/master
Run Code Online (Sandbox Code Playgroud)
也可以看看:
| 归档时间: |
|
| 查看次数: |
94835 次 |
| 最近记录: |