git gc / git gui: 文件<内部打包文件名称>的取消链接失败

23

在命令行或通过git gui运行git gc时,使用1.9.4.msysgit.0版本的git,我几乎每次都会遇到下面提到的错误,提示我“压缩松散对象”:

Counting objects: 1110956, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (269562/269562), done.
Writing objects: 100% (1110956/1110956), done.
Total 1110956 (delta 636114), reused 1110956 (delta 636114)
Unlink of file '.git/objects/pack/pack-207f1feb5376880778637c ... 8371cea62.pack'
    failed. Should I try again? (y/n) n
Checking connectivity: 1110956, done.

唯一的解决方法似乎是,按下每个被锁定文件的 n 键 - 正如这个帖子所建议的:

简短的回答:按 'n' 来通过所有这些,然后手动运行 "git gc"。

该线程还建议...

问题在于,这些文件被一个正在尝试进行垃圾回收操作的 git.exe 的父进程占用。

...当查看进程树时,这是完全可能的:

git process tree

我的问题是,有没有什么我可以做来防止这种情况?每天多次这样做真的很烦人...而且为什么会发生?这是一个仅限于 git/w32 的 bug 吗?


更新1:澄清一下 - 按照描述多次按下 n 键后,git gc 完成,本地存储库已经 "干净",即重新运行 git gc 将不会再次导致所述文件锁定问题 - 但这只是一段时间。在存储库上工作一段时间后 - 有时是几分钟,有时是几个小时 - 存储库又变 "脏" 了,描述的问题仍然存在。像CodeWizard建议的那样,在git-bash而不是在cmd中运行git gc并没有帮助。他进一步指出,可能是其他非 git 软件持有了相关的锁。我对此持怀疑态度,不仅因为链接上面的线程中的评论 - 我认为父 git 进程正在持有锁 - 但我仍然需要验证该说法。

更新2: 原来CodeWizard一直是正确的 - 至少在我的情况下确实是 IDE 锁定了那些文件...所以这是一个Eclipse 的 EGit Team Provider问题,而不是 git 本身的问题。

enter image description here

更新3: 您可以使用以下其中一种免费工具来查找锁定的文件:

在这两个工具中,使用CTRLF来打开“查找句柄”对话框。


1
找到开放句柄的好方法 - 我使用了Process Explorer,终止了有问题的进程并重新运行了 "git gc"。 - Mark Larson
好的,我已经添加了一个链接! - zb226
至少在Win7上,尝试从资源管理器中删除文件本身会显示哪个进程锁定了文件(大多数情况下)。这让我发现Eclipse一直在占用它。 - Jeff Mercado
可能是文件取消链接后应该再次尝试吗?的重复问题。 - Jim Fell
1
注意:Git 2.19应该会改善这种情况:https://dev59.com/L4nca4cB1Zd3GeqP80qf#51755262 - VonC
2个回答

1
我建议您使用git-bash(即%GIT_HOME%\bin\bash.exe)而不是cmd来使用git。一旦切换到git-bash,您不应该期望出现此问题,因为cmd是Windows命令,可能会锁定您的文件,而git-bash就像一个UNIX仿真器,不会锁定您的文件(即使它实际上正在查看您的Windows文件夹)。

11
但是当我使用Git Bash时,我得到的结果是一样的。 - Musa Haidari
1
执行 git fsck 命令并告诉我你得到了什么。 - CodeWizard
1
$ git fsck **** 正在检查对象目录:100%(256/256),完成。 **** 正在检查对象:100%(9818/9818),完成。 **** 悬空的 blob d6d88f16abdcb567c46f4d38174a5d9ce136530d - Musa Haidari
3
这是损坏的数据:d6d88f16abdcb567c46f4d38174a5d9ce136530d,它是一个未提交的“僵尸”文件,尝试执行"git gc --aggressive" 命令来看是否有帮助。如果没有作用,请尝试删除此 blob 并再次执行 "fsck + gc" 命令。 - CodeWizard
1
很好,你指示git删除所有比昨天更早的悬空文件。 :-) - CodeWizard
显示剩余8条评论

0

检查是否有其他进程锁定了文件。在我的情况下,我只需要关闭一个打开了从git仓库中获取的项目的Eclipse实例,然后运行“git gc”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接