一般来说,删除分支是正确的答案。但是这里有很多繁琐的小旋钮可以转动。其中一些,您可以等待(大约一个月)并避免处理。但是,如果您不想等待存储库的各种副本自行缩小:
在这种情况下,我们已经删除了分支并在新分支上重新提交了工作,但大小还没有改变......
首先,请记住 Git 是自然分布的。每个存储库(至少在原则上)是完全独立的,并且独立于其他所有存储库。因此,当您说存储库尚未精简时,显而易见的第一个问题是:哪个?
您对任何一个存储库所做的任何更改都不会影响任何其他存储库,至少在您交叉连接它们两个并告诉一个从另一个获取新工作或将新工作推送到另一个之前不会影响任何其他存储库。如果您在测试克隆中执行所有这些操作,那很好,只需记住测试克隆的结果将特定于该克隆。
紧接着的下一个问题是,Git 就其本质而言,“想要”为所有内容制作更多副本。提交就像一些病毒或疾病:将一个 Git 连接到另一个 Git,而没有提交的 Git 现在有了它们。确实有提交的 Git仍然有它们。当您最终从(例如)16 个克隆中删除提交时,对于任何地方的任何人来说,在他们的克隆中确实有提交的人都会很容易意外地将它们重新引入固定的克隆,然后它们将从那里传播回来对所有其他人。这并不意味着你不能摆脱提交——以及这种方式的“只能从一个分支访问”的性质你现在拥有它们将大大简化事情,因为你只需要确保没有其他人从他们的克隆中恢复或合并该分支。
对于许多有用的背景知识,我建议阅读并通过网站Think Like (a) Git工作。一旦你消化了那里的东西,缩小存储库的方法是:
确保具有大文件的提交是不可访问的。在您的特定情况下,删除分支名称可以让您大部分时间到达那里:它们可以从该分支名称以及通过该分支的 reflogs 访问。删除分支也会删除其 reflog,因此该路径现在已被清除。
仍然可以(可能)到达这些提交的位置在您的HEAD
reflog 中。运行git reflog
将向您显示所有HEAD
reflog 条目(默认操作是show
,而要显示的默认 reflog 是 for HEAD
)。您可以选择性地删除每个这样的reflog 条目,例如,但是使用以下命令删除所有git reflog delete
reflog 条目会更容易:HEAD
git reflog expire --expire=now --expire-unreachable=now
请注意,这会消除您恢复其他意外丢失提交的所有能力HEAD
,因此在执行此操作之前请确保您对此表示满意。您可以省略,--expire=now
因为从您当前的分支中无法访问特定于已删除分支的提交——我在这里展示了命令的“从轨道上核对它”变体。
然后,运行git gc --prune=now
。这是文档中“缩小存储库的清单”的最后一步git filter-branch
。
这将处理重建包文件和/或丢弃包含无法从任何外部名称访问的大文件的松散对象所需的所有各种项目。也就是说,没有外部名称直接或间接指向通过其树或其子树之一指向保存文件的 blob 对象的任何提交。因此,该gc
命令将协调将删除不需要的对象的其他命令(git repack
和)。git prune
(注意:如果您使用.keep
文件来保留旧包,则必须删除这些.keep
文件并允许销毁这些包。但是,如果您这样做,您可能一开始就没有问这个问题。)