I have had a hard disk failure which resulted in some files of a Git repository getting damaged. When running git fsck --full
I get the following output:
我遇到了硬盘故障,导致Git仓库的一些文件被损坏。在运行git fsck时,我得到如下输出:
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
I have backups of the repository, but the only backup that includes the pack file has it already damaged. So I think that I have to find out a way to retrieve the single objects from different backups and somehow instruct Git to produce a new pack with only correct objects.
我有存储库的备份,但是包含包文件的唯一备份已经损坏了。因此,我认为我必须找到一种方法来从不同的备份中检索单个对象,并以某种方式指示Git生成一个只有正确对象的新包。
Can you please give me hints how to fix my repository?
你能告诉我如何修复我的仓库吗?
7 个解决方案
#1
78
In some previous backups, your bad objects may have been packed in different files or may be loose objects yet. So your objects may be recovered.
在以前的一些备份中,您的坏对象可能已经被打包在不同的文件中,或者可能是松散的对象。所以你的物品可能会被回收。
It seems there are a few bad objects in your database. So you could do it the manual way.
在您的数据库中似乎有一些坏的对象。你可以用手工的方法。
Because of git hash-object
, git mktree
and git commit-tree
do not write the objects because they are found in the pack, then start doing this:
因为git hashobject, git mktree和git committree不写对象,因为它们是在包中找到的,然后开始执行以下操作:
mv .git/objects/pack/* <somewhere>
for i in <somewhere>/*.pack; do
git unpack-objects -r < $i
done
rm <somewhere>/*
(Your packs are moved out from the repository, and unpacked again in it; only the good objects are now in the database)
(您的包从存储库中移出,并在其中重新打包;只有好的对象现在在数据库中)
You can do:
你能做什么:
git cat-file -t 6c8cae4994b5ec7891ccb1527d30634997a978ee
and check the type of the object.
检查对象的类型。
If the type is blob: retrieve the contents of the file from previous backups (with git show
or git cat-file
or git unpack-file
; then you may git hash-object -w
to rewrite the object in your current repository.
如果类型是blob:从以前的备份中检索文件的内容(使用git show或git catt文件或git unpack-file);然后,可以在当前存储库中重新编写该对象。
If the type is tree: you could use git ls-tree
to recover the tree from previous backups; then git mktree
to write it again in your current repository.
如果类型是树:您可以使用git ls树来从以前的备份中恢复树;然后git mktree在当前存储库中再次编写它。
If the type is commit: the same with git show
, git cat-file
and git commit-tree
.
如果类型是commit:与git显示、git文件和git提交树相同。
Of course, I would backup your original working copy before starting this process.
当然,在开始这个过程之前,我会备份您的原始工作副本。
Also, take a look at How to Recover Corrupted Blob Object.
另外,看看如何恢复被损坏的Blob对象。
#2
38
Banengusk was putting me on the right track. For further reference, I want to post the steps I took to fix my repository corruption. I was lucky enough to find all needed objects either in older packs or in repository backups.
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!
#3
13
Try the following commands at first (re-run again if needed):
首先尝试以下命令(如果需要,重新运行):
$ git fsck --full
$ git gc
$ git gc --prune=today
$ git fetch --all
$ git pull --rebase
And then you you still have the problems, try can:
然后你仍然有问题,试着:
-
remove all the corrupt objects, e.g.
删除所有损坏的对象。
fatal: loose object 91c5...51e5 (stored in .git/objects/06/91c5...51e5) is corrupt $ rm -v .git/objects/06/91c5...51e5
-
remove all the empty objects, e.g.
删除所有空对象,例如:
error: object file .git/objects/06/91c5...51e5 is empty $ find .git/objects/ -size 0 -exec rm -vf "{}" \;
-
check a "broken link" message by:
查看“断开链接”信息:
git ls-tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
This will tells you what file the corrupt blob came from!
这将告诉您什么文件损坏的blob来自!
-
to recover file, you might be really lucky, and it may be the version that you already have checked out in your working tree:
要恢复文件,您可能非常幸运,它可能是您已经在工作树中签出的版本:
git hash-object -w my-magic-file
again, and if it outputs the missing SHA1 (4b945..) you're now all done!
再一次,如果它输出丢失的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.
这将向您显示该文件的整个日志(请注意,您所拥有的树可能不是*树,因此您需要找出它属于您自己的子目录),然后您可以再次使用hash-object重新创建丢失的对象。
-
to get a list of all refs with missing commits, trees or blobs:
要得到所有未提交的refs的列表,树或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).
使用常规的分支-d或标记-d命令,可能不可能删除一些refs,因为如果git注意到损坏,它们将会死。因此,使用管道命令git update-ref -d $ref。注意,在本地分支的情况下,这个命令可能会在.git/config中留下陈旧的分支配置。可以手动删除它(查找[分支“$ref”]部分)。
-
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:
在所有的裁判都是干净的之后,仍然有可能在重鞭策中被破坏。您可以使用git reflog终止所有的reflogs——过期=现在—所有。如果你不想失去所有的reflogs,你可以搜索破碎的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.
(注意,git rev-list中添加的-g选项。)然后,使用git reflog过期——过期=现在$ref。当所有破碎的refs和reflogs都消失后,运行git fsck——以检查存储库是否干净。晃来晃去的对象是好的。
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.
下面,您可以找到一些命令的高级用法,这些命令可能会导致git存储库中的数据丢失,如果不明智地使用,那么在意外地对您的git造成进一步损害之前,先进行备份。如果你知道自己在做什么,试试自己的风险。
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:
要在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
For OSX, use sed -E
instead of sed -r
.
对于OSX,使用sed -E而不是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:
其他的想法是将所有的对象从包文件中解压,以便在.git/对象中重新生成所有对象,所以尝试在您的存储库中运行以下命令:
$ 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或从另一个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
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.
如果git使您进入分离状态,签出主并将其合并到分离的分支中。
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.
- 为了修复已损坏的存储库,需要一些技巧来重构blob对象。
- How to fix a broken repository?
- 如何修复破碎的存储库?
- How to remove all broken refs from a repository?
- 如何从一个存储库中移除所有破碎的refs ?
- How to fix corrupted git repository? (seeques)
- 如何修复已损坏的git存储库?(seeques)
- How to fix corrupted git repository? (qnundrum)
- 如何修复已损坏的git存储库?(qnundrum)
- Error when using SourceTree with Git: 'Summary' failed with code 128: fatal: unable to read tree
- 使用Git使用SourceTree时出现错误:“Summary”失败,代码128:致命:无法读取树。
- Recover A Corrupt Git Bare Repository
- 恢复一个损坏的Git裸库。
- Recovering a damaged git repository
- 恢复损坏的git存储库。
- How to fix git error: object is empy / corrupt
- 如何修正git错误:对象是empy /损坏的?
- How to diagnose and fix git fatal: unable to read tree
- 如何诊断和修复git致命:无法读取树?
- How to deal with this git error
- 如何处理这个git错误?
- How to fix corrupted git repository?
- 如何修复已损坏的git存储库?
- How do I 'overwrite', rather than 'merge', a branch on another branch in Git?
- 如何“覆盖”,而不是“合并”,在Git中另一个分支上的分支?
- How to replace master branch in git, entirely, from another branch?
- 如何从另一个分支中完全替换git中的主分支?
- Git: "Corrupt loose object"
- Git:“腐败的松散的对象”
- Git reset = fatal: unable to read tree
- Git reset =致命:无法读取树。
#4
2
Here are the steps I followed to recover from a corrupt blob object.
下面是我从一个腐败的blob对象中恢复的步骤。
1) Identify corrupt blob
1)识别腐败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
腐败的团是241091723 c324aed77b2d35f97a05e856b319efd
2) Move corrupt blob to a safe place (just in case)
2)将腐败团移到安全的地方(以防万一)
mv .git/objects/24/1091723c324aed77b2d35f97a05e856b319efd ../24/
3) Get parent of corrupt blob
3)得到腐败分子的父母。
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.
父散列是0716831 e1a6c8d3e6b2b541d21c4748cc0ce7180。
4) Get file name corresponding to corrupt blob
4)获取与腐败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.
在备份或上游git存储库中找到这个特定的文件(在我的例子中是dump.tar.gz)。然后将其复制到本地存储库中的某个地方。
5) Add previously corrupted file in the git object database
5)在git对象数据库中添加先前损坏的文件。
git hash-object -w dump.tar.gz
6) Celebrate!
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)
#5
1
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.
Git checkout实际上可以从修订中挑选出单个文件。只要给它提交哈希和文件名。更详细的信息。
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!
我认为最简单的解决方法是还原到最新的未启动备份,然后有选择地从新的提交中选择未损坏的文件。好运!
#6
1
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.
在你试图恢复的repo中运行。
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.
标准警告:只有在你非常绝望的时候才使用,并且你已经备份了(损坏的)repo。这可能无法解决任何问题,但至少应该突显腐败的程度。
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
#7
0
I have resolved this problem to add some change like git add -A and git commit again.
我已经解决了这个问题,以添加一些诸如git add -A和git提交的更改。
#1
78
In some previous backups, your bad objects may have been packed in different files or may be loose objects yet. So your objects may be recovered.
在以前的一些备份中,您的坏对象可能已经被打包在不同的文件中,或者可能是松散的对象。所以你的物品可能会被回收。
It seems there are a few bad objects in your database. So you could do it the manual way.
在您的数据库中似乎有一些坏的对象。你可以用手工的方法。
Because of git hash-object
, git mktree
and git commit-tree
do not write the objects because they are found in the pack, then start doing this:
因为git hashobject, git mktree和git committree不写对象,因为它们是在包中找到的,然后开始执行以下操作:
mv .git/objects/pack/* <somewhere>
for i in <somewhere>/*.pack; do
git unpack-objects -r < $i
done
rm <somewhere>/*
(Your packs are moved out from the repository, and unpacked again in it; only the good objects are now in the database)
(您的包从存储库中移出,并在其中重新打包;只有好的对象现在在数据库中)
You can do:
你能做什么:
git cat-file -t 6c8cae4994b5ec7891ccb1527d30634997a978ee
and check the type of the object.
检查对象的类型。
If the type is blob: retrieve the contents of the file from previous backups (with git show
or git cat-file
or git unpack-file
; then you may git hash-object -w
to rewrite the object in your current repository.
如果类型是blob:从以前的备份中检索文件的内容(使用git show或git catt文件或git unpack-file);然后,可以在当前存储库中重新编写该对象。
If the type is tree: you could use git ls-tree
to recover the tree from previous backups; then git mktree
to write it again in your current repository.
如果类型是树:您可以使用git ls树来从以前的备份中恢复树;然后git mktree在当前存储库中再次编写它。
If the type is commit: the same with git show
, git cat-file
and git commit-tree
.
如果类型是commit:与git显示、git文件和git提交树相同。
Of course, I would backup your original working copy before starting this process.
当然,在开始这个过程之前,我会备份您的原始工作副本。
Also, take a look at How to Recover Corrupted Blob Object.
另外,看看如何恢复被损坏的Blob对象。
#2
38
Banengusk was putting me on the right track. For further reference, I want to post the steps I took to fix my repository corruption. I was lucky enough to find all needed objects either in older packs or in repository backups.
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!
#3
13
Try the following commands at first (re-run again if needed):
首先尝试以下命令(如果需要,重新运行):
$ git fsck --full
$ git gc
$ git gc --prune=today
$ git fetch --all
$ git pull --rebase
And then you you still have the problems, try can:
然后你仍然有问题,试着:
-
remove all the corrupt objects, e.g.
删除所有损坏的对象。
fatal: loose object 91c5...51e5 (stored in .git/objects/06/91c5...51e5) is corrupt $ rm -v .git/objects/06/91c5...51e5
-
remove all the empty objects, e.g.
删除所有空对象,例如:
error: object file .git/objects/06/91c5...51e5 is empty $ find .git/objects/ -size 0 -exec rm -vf "{}" \;
-
check a "broken link" message by:
查看“断开链接”信息:
git ls-tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
This will tells you what file the corrupt blob came from!
这将告诉您什么文件损坏的blob来自!
-
to recover file, you might be really lucky, and it may be the version that you already have checked out in your working tree:
要恢复文件,您可能非常幸运,它可能是您已经在工作树中签出的版本:
git hash-object -w my-magic-file
again, and if it outputs the missing SHA1 (4b945..) you're now all done!
再一次,如果它输出丢失的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.
这将向您显示该文件的整个日志(请注意,您所拥有的树可能不是*树,因此您需要找出它属于您自己的子目录),然后您可以再次使用hash-object重新创建丢失的对象。
-
to get a list of all refs with missing commits, trees or blobs:
要得到所有未提交的refs的列表,树或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).
使用常规的分支-d或标记-d命令,可能不可能删除一些refs,因为如果git注意到损坏,它们将会死。因此,使用管道命令git update-ref -d $ref。注意,在本地分支的情况下,这个命令可能会在.git/config中留下陈旧的分支配置。可以手动删除它(查找[分支“$ref”]部分)。
-
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:
在所有的裁判都是干净的之后,仍然有可能在重鞭策中被破坏。您可以使用git reflog终止所有的reflogs——过期=现在—所有。如果你不想失去所有的reflogs,你可以搜索破碎的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.
(注意,git rev-list中添加的-g选项。)然后,使用git reflog过期——过期=现在$ref。当所有破碎的refs和reflogs都消失后,运行git fsck——以检查存储库是否干净。晃来晃去的对象是好的。
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.
下面,您可以找到一些命令的高级用法,这些命令可能会导致git存储库中的数据丢失,如果不明智地使用,那么在意外地对您的git造成进一步损害之前,先进行备份。如果你知道自己在做什么,试试自己的风险。
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:
要在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
For OSX, use sed -E
instead of sed -r
.
对于OSX,使用sed -E而不是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:
其他的想法是将所有的对象从包文件中解压,以便在.git/对象中重新生成所有对象,所以尝试在您的存储库中运行以下命令:
$ 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或从另一个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
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.
如果git使您进入分离状态,签出主并将其合并到分离的分支中。
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.
- 为了修复已损坏的存储库,需要一些技巧来重构blob对象。
- How to fix a broken repository?
- 如何修复破碎的存储库?
- How to remove all broken refs from a repository?
- 如何从一个存储库中移除所有破碎的refs ?
- How to fix corrupted git repository? (seeques)
- 如何修复已损坏的git存储库?(seeques)
- How to fix corrupted git repository? (qnundrum)
- 如何修复已损坏的git存储库?(qnundrum)
- Error when using SourceTree with Git: 'Summary' failed with code 128: fatal: unable to read tree
- 使用Git使用SourceTree时出现错误:“Summary”失败,代码128:致命:无法读取树。
- Recover A Corrupt Git Bare Repository
- 恢复一个损坏的Git裸库。
- Recovering a damaged git repository
- 恢复损坏的git存储库。
- How to fix git error: object is empy / corrupt
- 如何修正git错误:对象是empy /损坏的?
- How to diagnose and fix git fatal: unable to read tree
- 如何诊断和修复git致命:无法读取树?
- How to deal with this git error
- 如何处理这个git错误?
- How to fix corrupted git repository?
- 如何修复已损坏的git存储库?
- How do I 'overwrite', rather than 'merge', a branch on another branch in Git?
- 如何“覆盖”,而不是“合并”,在Git中另一个分支上的分支?
- How to replace master branch in git, entirely, from another branch?
- 如何从另一个分支中完全替换git中的主分支?
- Git: "Corrupt loose object"
- Git:“腐败的松散的对象”
- Git reset = fatal: unable to read tree
- Git reset =致命:无法读取树。
#4
2
Here are the steps I followed to recover from a corrupt blob object.
下面是我从一个腐败的blob对象中恢复的步骤。
1) Identify corrupt blob
1)识别腐败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
腐败的团是241091723 c324aed77b2d35f97a05e856b319efd
2) Move corrupt blob to a safe place (just in case)
2)将腐败团移到安全的地方(以防万一)
mv .git/objects/24/1091723c324aed77b2d35f97a05e856b319efd ../24/
3) Get parent of corrupt blob
3)得到腐败分子的父母。
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.
父散列是0716831 e1a6c8d3e6b2b541d21c4748cc0ce7180。
4) Get file name corresponding to corrupt blob
4)获取与腐败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.
在备份或上游git存储库中找到这个特定的文件(在我的例子中是dump.tar.gz)。然后将其复制到本地存储库中的某个地方。
5) Add previously corrupted file in the git object database
5)在git对象数据库中添加先前损坏的文件。
git hash-object -w dump.tar.gz
6) Celebrate!
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)
#5
1
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.
Git checkout实际上可以从修订中挑选出单个文件。只要给它提交哈希和文件名。更详细的信息。
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!
我认为最简单的解决方法是还原到最新的未启动备份,然后有选择地从新的提交中选择未损坏的文件。好运!
#6
1
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.
在你试图恢复的repo中运行。
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.
标准警告:只有在你非常绝望的时候才使用,并且你已经备份了(损坏的)repo。这可能无法解决任何问题,但至少应该突显腐败的程度。
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
#7
0
I have resolved this problem to add some change like git add -A and git commit again.
我已经解决了这个问题,以添加一些诸如git add -A和git提交的更改。