10

Bitbucket 令人担忧的是我的 Git 存储库超过 1 GB。实际上,在存储库详细信息页面中它说它是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-cleanerjava -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 的源代码浏览器中,我查看了包含大型数据文件但不包含这些文件的文件夹(成功忽略)。

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

4

3 回答 3

7

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

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

但是遥控器不会删除旧提交或该提交中的旧文件。它只会将其与图表断开连接,并且该大文件将不再“可访问”。实际上,它是符合“垃圾收集”条件的“垃圾”。这将删除大文件,并且服务器上的存储库大小会缩小。

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

您需要寻找我们来触发 gc。我想最好的方法是如果真的很紧急,就“升级”它,我们应该能够立即解决。— Bitbucket 支持(2016 年 12 月)

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

于 2015-02-28T13:19:00.507 回答
4

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

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

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

git fsck --unreachable --no-reflog

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

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

但是,我们无法在 Bitbucket 上远程运行任何这些命令。但是,他们在关于减少存储库大小的页面上说(删除存储库限制部分),他们运行git gc自己以响应做git reset --hard HEAD~1丢弃最后一次提交),然后是git push -f. 此外,他们在垃圾收集死数据一节中说,可以尝试以下顺序:  git reflog expire --expire=now --allgit gc --prune=nowgit push --all --force. 鉴于这一切,我决定在本地尝试以下操作,希望它会切断 reflog 并在本地进行修剪,然后将它们推送到远程 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。:)

请注意,过期/过期不可达/修剪的时间参数设置从现在开始测量的过期截止点。因此,例如“现在”意味着过期/修剪所有内容,而“30m”意味着除了过去 30 分钟内的变化。


编辑:

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

因此,以下内容可能对我产生相同的效果:

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

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

于 2016-05-16T11:45:45.527 回答
0

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

我最终在Atlassian 社区上发布了我的问题, Atlassian 人为我跑git gc了,问题解决了。他们的反应不晚(~3h)所以我推荐这种方式。

于 2018-07-04T10:00:50.810 回答