如何从远程Git仓库(如VSTS)中删除悬空提交?

7
我一直在尝试通过将一些文件移动到Git LFS来减小我的Git存储库的大小。经过几百个命令,现在我的文件已经在git LFS中,并且在我的git提交中不再有这些文件的历史记录。
然而,每当我克隆存储库时,仍会下载约3GB的对象。我通过在Visual Studio Team Services中创建一个新存储库解决了这个问题,在本地修剪和垃圾回收我的存储库后,将其推送到那里,它被缩小到300MB。 (在此帖子中找到在本地执行此操作的命令:Git:什么是悬空提交/ blob以及它们从哪里来?
然而,我无法想象您总是必须删除/重新创建完整的存储库才能删除悬空提交。
我还尝试过进行git init,然后将其推送到现有存储库,但它只会进一步增加对象计数。
对于任何遇到类似问题的人,以下是我执行的命令,用于创建没有悬空提交的新存储库。但是,我仍然希望找出如何在现有存储库中执行此操作而无需删除它:
git clone https://avavedse.visualstudio.com/Test/_git/TestRepository
cd blahblah
git reflog expire --expire=now --all
git gc --prune=now
git remote add newrepo https://avavedse.visualstudio.com/Test/_git/TestRepositoryNewEdition
git push newrepo

LFS 重写是对仓库的非常重要的修改;你为什么“无法想象”它需要完全替换远程存储库呢?顺便说一下,如果远程主机服务提供了对 git gc 的控制,则您可能能够通过清理它而不是替换它来解决问题,但我通常不指望这一点。 - Mark Adelsberger
因为这意味着必须对存储库进行实际的功能更改以解决技术限制。 - Devedse
怎么样?你有一个带有一组引用的远程仓库;你删除它并用一个新的仓库替换它,这个新仓库具有相同的引用(甚至指向相同的提交),但是没有那么多的冗余。这会产生什么功能性的变化呢?相比之下,当你运行LFS迁移时,它会改变所有引用以指向新的提交,这已经是一个需要用户执行恢复操作的功能性变化(最简单的方法是丢弃和替换所有克隆)。由于LFS迁移是可能发生的最激烈的功能性变化,我不理解为什么会有担忧。 - Mark Adelsberger
你似乎在为这个产品的限制辩护,但我真的不知道为什么?为什么人们要删除并完全重新创建一个存储库,只是为了达到减小该存储库大小的目标。他们的要求并不包括新存储库,这只是一个功能的变通方法/黑客,从你的故事中可以看出,该功能似乎没有在产品中实现。此外,我不确定删除/重新创建存储库会产生什么其他影响,PR、问题等是否会被保存? - Devedse
你认为一切都必须是价值判断的事实是你的问题,而不是我的问题。我告诉你它是如何工作的,并请你解释为什么这会给你带来实际问题。如果问题是“我认为应该有所不同”,那就不是一个实际问题;但是,随意与服务提供商联系或更改服务提供商。如果你选择的git托管服务提供商没有公开gc接口 - 我相信VSTS没有 - 那么你必须替换存储库。 时期。 - Mark Adelsberger
2个回答

6

这可能是如何从GitHub中删除悬挂提交?的重复内容。

GitHub会定期回收无法从顶层引用访问的对象。因此,它们会随着时间的推移而消失。但这并不保证。这是我在这方面找到的最好信息。

您可以手动更正reflogs到现在的过期日期并运行垃圾收集器:

git reflog expire --expire=now --all
git gc --prune=now

但这只会影响本地仓库。

显然,垃圾回收器远非理想,以至于除非您不介意删除并创建新的仓库,并失去所有问题、拉取请求等,否则您必须联系Github Support

您可以通过联系 GitHub Support 或 GitHub Premium Support 永久删除 GitHub 上拉取请求中缓存的视图和对敏感数据的引用。[docs.github.com]


1
实际上,当您执行git reflog expire --expire=now --allgit gc --prune=now时,悬空的提交将被删除。您可以通过git fsck --full进行双重检查。如果输出不显示提交,则表示没有悬空提交。

另一个导致存储库大小似乎没有减少的原因是您没有删除git历史中的LFS文件。您可以通过以下方式重写历史记录:

git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch filename --prune-empty --tag-name-filter cat -- --all
git push -f

关于将文件从git移动到git-lfs的更多详细信息,您可以参考将存储库中的文件移动到git-lfs


3
但是这个命令似乎只会在本地修剪存储库,而不是远程存储库。 - Devedse
请注意,无论是 "git fsck --full" 还是 "git fsck --dangling" 都不会显示 .git/lost-found 中的悬空提交,您需要运行 "git fsck --lost-found" 来确保没有任何地方有悬空提交。 - xuancong84

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