在我们的git仓库中,其中一个分支包含已提交并推送到远程仓库进行测试的二进制文件,但是,这导致填满仓库规模的意外结果。经过here和here的研究,然后再进行一些研究,提供了许多方案的解决方案差异很大的方案。我想知道我们是否有一个更简单的方案可以避免利用“ git push --all --force”(需要更大的协调性)。
在我们的情况下,我们不在乎该分支是否已存在,并且可以很好地删除该分支(连同其历史记录等)。我们可以承担相关工作,然后将其重新提交到另一个分支。由于分支尚未合并到其主节点,因此我们可以完全删除该分支。假设引用在包含提交的二进制文件的分支中是自包含的,有没有更简单的解决方案?
根据研究,已提出以下解决方案:
但是,他们假定读者希望保留历史记录,并因此删除有问题的二进制文件,重写历史记录,并且/或者问题仍然局限于本地存储库。如果问题是远程的,则需要修复本地问题,然后将--all推送到远程。
在这种情况下,我们已经删除了分支,并在新分支上重新提交了工作,但是大小尚未更改,我们还需要做什么?因为数据被本地化到已删除的分支并且允许删除该分支,有没有更简单的解决方案?我们也不确定git是否会以某种方式保留二进制文件以便在历史的其他部分中保留对二进制文件的引用。在远程服务器上是否需要垃圾回收?修剪引用?
答案 0 :(得分:1)
通常,删除分支是正确的答案。但是这里有很多有趣的小旋钮。其中一些,您可以等待(大约一个月)并避免处理。但是,如果您不想等待存储库的各个副本单独收缩,则可以:
在这种情况下,我们已经删除了分支,并重新提交了新分支上的工作,但是大小尚未更改...
首先,请记住,Git是自然分布的。每个存储库(至少原则上)是完全独立的,并且独立于其他所有存储库。因此,当您说 the 存储库尚未精简时,显而易见的第一个问题是:哪个?
您对任何一个存储库所做的任何更改至少不会影响任何其他存储库,至少要等到您将两个存储库交叉连接并告诉一个存储库从另一个存储库获取新工作,或将新工作推送到另一个存储库后, 。如果您在测试克隆中完成所有这些操作,那很好,请记住测试克隆的结果将特定于该克隆。
下一个直接的问题是,Git本质上会“想”制作更多的副本。提交就像某些病毒或疾病:将一个Git连接到另一个Git,没有拥有提交的Git现在有了它们。 did 具有提交的Git, still 具有提交。当您最终从(例如)16个克隆中删除提交时,确实在其克隆中拥有提交以意外地重新引入它们的任何人都将非常容易到固定的克隆,它们将从中传播回所有其他克隆。这并不意味着您不能删除提交-现在您拥有它们的 way 的“只能从一个分支访问”性质事情很多,因为您只需要确保没有其他人可以恢复或合并其克隆中的分支。
对于许多有用的背景,我建议阅读并浏览网站Think Like (a) Git。消化完其中的内容后,缩小存储库的方法是:
确保具有大文件的提交无法访问。在您的特定情况下,删除分支名称可以帮助您到达目的地:从该分支名称以及该分支的reflog可以访问它们。删除分支也会删除其引用日志,因此该路径现在已清除。
(可能)仍然可以到达这些提交的位置在您的HEAD
引用日志中。运行git reflog
将为您显示所有HEAD
的引用日志条目(默认操作为show
,而要显示的默认引用日志为HEAD
)。您可以使用git reflog delete
选择性地删除每个此类reflog条目,但是使用以下命令删除{em> all HEAD
reflog条目会更容易:
git reflog expire --expire=now --expire-unreachable=now
请注意,这将删除您恢复所有否则丢失的HEAD
提交的能力,因此在执行此操作之前,请务必确保对此没有问题。您可以省去--expire=now
,因为无法从当前分支访问特定于已删除分支的提交-我在这里显示命令的“从轨道上删除它”变体。
然后,运行git gc --prune=now
。这是the git filter-branch
documentation中“缩小存储库的清单”的最后一步。
这将处理重建打包文件和/或丢弃散乱的对象所需的所有所有项目,这些散乱的对象包含不再可用任何外部名称访问的大文件。也就是说,没有任何外部名称直接或间接指向通过其树或其树的子树之一指向保存该文件的Blob对象的任何提交。因此,gc
命令将编排其他命令(git repack
和git prune
),这些命令将删除不需要的对象。
(注意:如果您使用.keep
文件保留旧包,则必须删除这些.keep
文件并销毁这些包。但是,如果这样做,您可能根本不是在问这个问题。)