我想认为我对git的工作原理有很好的了解,但是这个问题让我挠头了。
我们有一个很久以前(在我到达之前)“重新创建”的存储库,在这一点上,他们似乎已经创建了一个没有父级的提交,并删除了所有分支引用,并指向refs/heads/master
到新提交。
他们忘记的是,一堆标记仍然指向那些先前的提交,因此git仍将它们视为“可访问”的,因此没有随着时间的流逝而被清除。问题是那些旧提交中仍然有大文件(LFS无法跟踪),而没有这些预先存在的提交的回购仅为30Mb,而整个回购(包括那些旧提交)仍为〜800Mb,所以我想摆脱多余的数据。
在本地这很容易,我只需在所有过时的标签上运行git tag -d <tagname>
,然后运行git reflog expire --expire=now --all && git gc --prune=now --aggressive
并繁荣,存储库约为30Mb。
问题是试图清理位桶云上的存储库,我尝试为每个过时的标签运行git push origin :<tagname>
,将它们从位桶中删除,然后要求Atlassian支持在服务器上运行git reflog expire --expire=now --all && git gc --prune=now --aggressive
,他们为我高兴地做到了,但是,在bitbucket上回购的大小保持在〜800Mb。
Atlassian的支持人员随后要求我为该存储库(git clone --mirror <url>
)制作一个裸露的副本,然后将其删除。我没有看到会有什么不同,但决定尝试一下。幸运的是,我设置了一个新的存储库以将裸克隆推送到first,以便拥有一个单独的测试环境,因为当我在测试存储库中第一个过时的标签运行git push origin :<tagname>
时,令我惊讶的是git删除了所有标签,甚至所有分支引用:
$ git push origin :v1.01
remote: error: refusing to delete the current branch: refs/heads/master
To bitbucket.org:user/repo.git
- [deleted] dev
- [deleted] prd
- [deleted] staging
- [deleted] uat
- [deleted] new-repo
- [deleted] v1.01
.... more tags
- [deleted] v6.0.0
! [remote rejected] master (deletion of the current branch prohibited)
error: failed to push some refs to 'git@bitbucket.org:user/repo.git'
出于可读性考虑,我从输出中删除了一些已删除的标签,但是如您所见,我仅尝试删除v1.01
分支,而git删除了所有其他标签以及分支引用(dev
,prd
,staging
和uat
),它甚至试图删除母版,但被远程拒绝。下面的命令在本地仓库(仍然存在标签/分支)上显示分支引用和标签引用之间的区别。
$ git show-ref
2cb2f87610d69d829c6800fef52751ff31d94377 refs/heads/dev
0ba963daa35dd312469eed6dddb5f4767edf792b refs/heads/master
a1ad1ec65060de4f28615beffafc42fd36dd7bea refs/heads/prd
9e910758162fae9bac595ff4bd418d52b1d2ed63 refs/heads/staging
f499abeab57af1871aa957fca69fcd0554c84ac9 refs/heads/uat
65c0509a6bb3702e46c6a908d5f1429622e53af3 refs/tags/v1.01
52368fdaa3a84ee2e5e7620abf5ddddc038e8989 refs/tags/v6.0.0
0ba963daa35dd312469eed6dddb5f4767edf792b refs/tags/new-repo
为清楚起见:如果我在普通(非git push -d :v1.01
裸仓库)克隆上运行相同的命令(--mirror
),它们将按预期工作,并仅删除指定的标签。
我真的很想知道为什么git在裸仓库上表现得如此。