Bitbucket 警告我的 git 存储库太大但我无法确认大文件

Bitbucket is alarming that my git repo is too large but I cannot confirm large files

Bitbucket 警告我的 Git 存储库超过 1 GB。实际上,在 Repository details 页面中它说它是 1.7 GB。太疯狂了。我一定是在版本控制中包含了大数据文件。我的本地存储库实际上是 10 GB,这意味着至少我一直在使用 .gitignore 在某种程度上成功地从版本控制中排除大文件。

接下来,我按照这里的教程https://confluence.atlassian.com/display/BITBUCKET/Reduce+repository+size尝试删除不用的大数据。我的仓库顶层文件夹中的命令 files.git count-objects -v 返回以下内容:

count: 5149
size: 1339824
in-pack: 11352
packs: 2
size-pack: 183607
prune-packable: 0
garbage: 0
size-garbage: 0

大小包 183607 KB 比 1.7 GB 小得多。我有点困惑。

接下来我下载了 BFG Repo Cleaner https://rtyley.github.io/bfg-repo-cleaner 和 运行 命令 java -jar bfg-1.12.3.jar --strip-blobs-bigger-than 100M 在顶级目录删除大于的文件来自所有非最新提交的 100 MB。但是,BFG 返回了以下消息:

Warning : no large blobs matching criteria found in packfiles 
- does the repo need to be packed?

对 50M 重复相同的结果。

这是否意味着所有大于 50 MB 的文件都在最新提交中?在 Bitbucket 的源代码浏览器中,我查看了包含大数据文件的文件夹,但这些文件不包括在内(成功忽略)。

谁能简要解释一下存储库大小和存储库中存在大文件的混乱根源是什么?

此时您需要查看服务器上的存储库才能确定问题出在哪里,并且您可能需要与 BitBucket 技术支持联系。但是您的描述听起来好像您的存储库中有一些可以清理的垃圾。

考虑一下您是否已将大约 500 MB 的文件推送到您的 BitBucket 存储库。现在您意识到了您的错误,并以某种方式(例如 BFG)将其从您的存储库中删除并推送更新后的参考。您远程上的 ref 将更新为指向新的提交,并且您的存储库将不会包含大文件(如果您克隆存储库,则不会获得大文件)。

但远程不会删除旧提交或该提交中的旧文件。它只会将它与图表断开连接,并且那个大文件将不再是 "reachable"。事实上,"garbage" 符合 "garbage collection" 的条件。这会删除大文件,并且服务器上的存储库大小会缩小。

无法请求服务器进行 GC(通过 git 协议)。 BitBucket 的支持应该 能够为您执行此操作:

You'll need to look for us to trigger the gc instead. I guess the best way is to "escalate" it if it is really urgent, and we should be able to get to it immediately. — Bitbucket Support (Dec. 2016)

请注意,这假设您实际上在本地拥有完整的存储库,请务必执行 fetch --all 以确保您在本地没有(可访问的)历史记录的子集。如果是 BFG,请确保您已使用 --mirror 选项克隆存储库。

我们认为我们今天遇到了同样的问题,并且能够在不联系 Bitbucket 支持的情况下解决它,如下所示。请注意,该方法会丢弃 repo 中的最后一次提交 - 因此您可能希望对其进行备份。

Bitbucket 报告说我们的 repo 大约是 2.1GB,而克隆时,它在本地只占用了大约 250MB。由此,我们得出结论,它很可能来自无法访问的提交中的大文件(感谢爱德华上面的回答)。

这是在本地查看无法访问的提交的方法,我们不考虑通过 reflog 的可达性:

git fsck --unreachable --no-reflog

在本地,无法访问的提交可以通过以下方式清除:

git reflog expire --expire-unreachable="now" --all
git prune --expire="now" -v
git gc --aggressive --prune="now"

但是,我们不能 运行 在 Bitbucket 上远程执行任何这些命令。但是,他们在 the page about reducing repo size(第 删除存储库限制 部分)上说,他们 运行 git gc 自己响应 git reset --hard HEAD~1(其中 丢弃最后一次提交 ),然后是 git push -f。此外,他们在 垃圾收集死数据 一节中说,可以尝试以下序列:git reflog expire --expire=now --allgit gc --prune=nowgit push --all --force。考虑到这一切,我决定在本地尝试以下操作,希望它能删除 reflog 并在本地执行 p运行e,然后将它们推送到远程 Bitbucket 存储库,在该存储库上启动 gc:

git reflog expire --expire-unreachable="30m" --all
git prune --expire="30m" -v
git gc --prune="30m"
git reset --hard HEAD~1
git push -f

这成功了,repo 大小立即从 2.1GB 变成了 ca。 250MB。 :)

请注意,时间参数到期/到期无法访问/p运行e 设置从现在开始测量的到期截止点。所以例如"now" 表示过期/p运行e 一切,“30m”表示除了最近 30 分钟内的变化。


编辑:

反思时想到的一件事是,由于 git 默认情况下会在 30 天后过期无法访问的 reflog 条目,因此我的命令序列可能起作用不是因为我 运行 git reflog expire, git prunegit gc 在本地(可能没有被推送到远程仓库),但是因为 git reset 触发的远程 git gc 删除了所有早于30 天。

所以,以下可能对我有同样的效果:

git reset --hard HEAD~1
git push -f

对于过去 30 天内所做的无法访问的更改,我仍然需要联系 Bitbucket 支持。

我尝试了 Jan 的回答,但在我的情况下 git reset --hard HEAD~1 后跟 git push -f 没有触发 git gc

我最终在 Atlassian community 和 Atlassian 人 运行 git gc 上发布了我的问题,问题解决了。 他们的回复没有迟到(~3h)所以我推荐这种方式。