方法一。
做第git fsck
一个。
$ git fsck --full
error in tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29: contains duplicate file entries
如果这不能解决问题,那你就有麻烦了。您可以忽略该问题,从备份中恢复存储库,或将文件移动到新存储库中。如果您在将 repo 推送到 github 时遇到问题,请尝试将存储库更改为其他存储库或检查:Can't push to GitHub error: pack-objects dead of signal 13 and Can't push new git repository to github。
以下方法仅适用于高级 git 用户。请在开始前做好备份。以下步骤不能保证修复,它可能会使情况变得更糟,所以为了您自己的风险或教育目的而这样做。
方法2。
使用 git ls-tree 识别重复文件。
$ git read-tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29 # Just a hint.
$ git ls-tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29 # Try also with: --full-tree -rt -l
160000 commit def08273a99cc8d965a20a8946f02f8b247eaa66 commerce_coupon_per_user
100644 blob 89a5293b512e28ffbaac1d66dfa1428d5ae65ce0 commerce_coupon_per_user
100644 blob 2f527480ce0009dda7766647e36f5e71dc48213b commerce_coupon_per_user
100644 blob dfdd2a0b740f8cd681a6e7aa0a65a0691d7e6059 commerce_coupon_per_user
100644 blob 45886c0eda2ef57f92f962670fad331e80658b16 commerce_coupon_per_user
100644 blob 9f81b5ca62ed86c1a2363a46e1e68da1c7b452ee commerce_coupon_per_user
如您所见,它包含重复的文件条目(commerce_coupon_per_user)!
$ git show bb81a5af7e9203f36c3201f2736fca77ab7c8f29
tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29
commerce_coupon_per_user
commerce_coupon_per_user
commerce_coupon_per_user
commerce_coupon_per_user
commerce_coupon_per_user
commerce_coupon_per_user
同样,您可以看到重复的文件条目 (commerce_coupon_per_user)!
您可以尝试使用git show
每个列出的 blob 并检查每个文件的内容。
然后在你的不同 git 克隆中继续为那个无效的 ls-tree 对象运行 ls-tree,看看你是否可以跟踪有效的对象,或者是否所有对象都损坏了。
git ls-tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29
If you found the valid object containing non-duplicated file entries, save it into the file and re-create by using `git mktree` and `git replace`, e.g.
remote$ git ls-tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29 > working_tree.txt
$ cat working_tree.txt | git mktree
NEWTREEbb81a5af7e9203f36c3201f2736fca77ab7c8f29
$ git replace bb81a5af7e9203f36c3201f2736fca77ab7c8f29 NEWTREE4b825dc642cb6eb9a060e54bf8d69288fbee4904
如果这没有帮助,您可以通过以下方式撤消更改:
$ git replace -d NEWTREE4b825dc642cb6eb9a060e54bf8d69288fbee4904
方法3。
当您知道哪个文件/目录条目重复时,您可以尝试删除该文件并稍后重新创建它。例如:
$ find . -name commerce_coupon_per_user # Find the duplicate entry.
$ git rm --cached `find . -name commerce_coupon_per_user` # Add -r for the dir.
$ git commit -m'Removing invalid git entry for now.' -a
$ git gc --aggressive --prune # Deletes loose objects! Please do the backup before just in case.
阅读更多:
方法4。
检查您的提交是否有无效条目。
让我们再次检查我们的树。
$ git ls-tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29 --full-tree -rt -l
160000 commit def08273a99cc8d965a20a8946f02f8b247eaa66 commerce_coupon_per_user
100644 blob 89a5293b512e28ffbaac1d66dfa1428d5ae65ce0 270 commerce_coupon_per_user
....
$ git show def08273a99cc8d965a20a8946f02f8b247eaa66
fatal: bad object def08273a99cc8d965a20a8946f02f8b247eaa66
$ git cat-file commit def08273a99cc8d965a20a8946f02f8b247eaa66
fatal: git cat-file def08273a99cc8d965a20a8946f02f8b247eaa66: bad file
似乎上面的提交是无效的,让我们使用以下命令之一扫描我们的 git 日志以检查发生了什么:
$ git log -C3 --patch | less +/def08273a99cc8d965a20a8946f02f8b247eaa66
$ git log -C3 --patch | grep -C10 def08273a99cc8d965a20a8946f02f8b247eaa66
commit 505446e02c68fe306aec5b0dc2ccb75b274c75a9
Date: Thu Jul 3 16:06:25 2014 +0100
Added dir.
new file mode 160000
index 0000000..def0827
--- /dev/null
+++ b/sandbox/commerce_coupon_per_user
@@ -0,0 +1 @@
+Subproject commit def08273a99cc8d965a20a8946f02f8b247eaa66
在这种特殊情况下,我们的提交指向了错误的对象,因为它是作为 git 子项目的一部分提交的,它不再存在(检查git submodule status
)。
您可以通过以下方式从 ls-tree 中排除该无效对象并重新创建没有此坏对象的树:
$ git ls-tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29 | grep -v def08273a99cc8d965a20a8946f02f8b247eaa66 | git mktree
b964946faf34468cb2ee8e2f24794ae1da1ebe20
$ git replace bb81a5af7e9203f36c3201f2736fca77ab7c8f29 b964946faf34468cb2ee8e2f24794ae1da1ebe20
$ git ls-tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29 # Re-test.
$ git fsck -full
注意:旧对象仍应抛出重复的文件条目,但如果您现在在新树中重复,则需要从该树中删除更多内容。所以:
$ git replace # List replace objects.
bb81a5af7e9203f36c3201f2736fca77ab7c8f29
$ git replace -d bb81a5af7e9203f36c3201f2736fca77ab7c8f29 # Remove previously replaced object.
现在让我们尝试从该树中删除所有提交和 blob,并再次替换:
$ git ls-tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29 | grep -ve commit -e blob | git mktree
4b825dc642cb6eb9a060e54bf8d69288fbee4904
$ git replace bb81a5af7e9203f36c3201f2736fca77ab7c8f29 4b825dc642cb6eb9a060e54bf8d69288fbee4904
现在你有那个无效条目的空树。
$ git status # Check if everything is fine.
$ git show 4b825dc642cb6eb9a060e54bf8d69288fbee4904 # Re-check
$ git ls-tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904 --full-tree # Re-check
如果您对阶段有一些奇怪的更改,请通过以下方式重置您的存储库:
$ git reset HEAD --hard
如果您将遇到以下错误:
HEAD is now at 5a4ed8e Some message at bb81a5af7e9203f36c3201f2736fca77ab7c8f29
执行变基并删除该提交(通过更改pick
为edit
):
$ git rebase -i
$ git commit -m'Fixed invalid commit.' -a
rebase in progress; onto 691f725
You are currently editing a commit while rebasing branch 'dev' on '691f725'.
$ git rebase --continue
$ git reset --hard
$ git reset HEAD --hard
$ git reset origin/master --hard
方法5。
尝试删除和压缩包含无效对象的无效提交。
$ git rebase -i HEAD~100 # 100 commits behind HEAD, increase if required.
阅读更多:Git 工具 - 重写历史以及如何在跳过特定提交时重新设置基准?
方法6。
通过以下方法识别无效的 git 对象进行手动删除:
对于未压缩的对象(*请删除前两个字符,因为 git 使用它作为目录名称):
$ find . -name 81a5af7e9203f36c3201f2736fca77ab7c8f29
对于压缩对象
$ find . -name \*.idx -exec cat {} \; | git show-index | grep bb81a5af7e9203f36c3201f2736fca77ab7c8f29
# Then you need to find the file manually.
$ git unpack-objects $FILE # Expand the particular file.
$ git unpack-objects < .git/objects/pack/pack-*.pack # Expand all.
请参阅:如何解压缩 git 存储库的所有对象?
有关的: