Git 远程切换推送的旧对象

Git remote switching pushed old objects

以下是一种情况。

项目源代码托管在一些 git 服务提供商(例如 Bitbucket)上。 - 大小超过 1GB 我们将所有工作迁移到新的 git 服务提供商,并进行了一些修剪以删除旧的大文件和对象(例如 Github)- 大小 500MB。

过渡已经几周了。突然之间,repo 大小超过了 1.8GB,我们有一些旧对象作为旧 repo 的一部分被删除了。

现在如何找到导致此问题的 commit/push?我知道它是什么时候发生的,但无法查明可能导致这种情况的提交或分支。还有更简单的方法来恢复推送以使回购大小恢复正常吗?

另一个问题是,如何防止这些对象被意外推回?

我的搜索让我找到了相关的答案,但空手而归。

参考文献:

How to find/identify large files/commits in Git history?

Which commit has this blob?

Git 非常倾向于将新事物(提交及其底层对象)添加到数据库的想法,而不删除任何旧事物。

当你设法删除一些旧东西时,如果Git再次遇到它们,它会将它们视为 的东西,然后把它们加回去。如果你愿意,你可以把这想象成得到 "re-infected"。 具有 "infection" 的存储库的每个 副本是 "contagious",并且触摸其中任何一个(通过 git fetchgit push)可以把你认为已经扔掉的东西拿回来。

Now how do I find the commit/push that caused this?

很难找到导致它的特定提取或推送。找到包含大对象的提交是可能的;查看您链接的答案以及其中的其他链接。

Also is there an easier way to revert the push to get the repo size back to normal?

您必须放弃包含大对象的提交,并且如果您希望保留依赖于那些较早提交的后续提交,请将后续提交复制到不再依赖的新的不同提交在较早的提交上。这就是 git filter-branch 所做的。一旦你没有分支提示指向或在他们的提交祖先链中,有大对象的提交,你可以重新打包和缩小存储库。

The BFG Cleaner 更容易使用(它为您完成所有这些),但我从未使用过它。

... how can I prevent these object being pushed back again by accident?

这比较棘手。有多种方法在不同程度上起作用:

  • 每个推的人都要自律。在推送之前,每个推送的人都必须确保他们不会重新引入不需要的大对象。显然,这仅在人们行使它的范围内有效。
  • 限制允许推送的人数。这将上述问题减少到少数人。
  • 使用 Git 挂钩来验证请求的更新不会引入 任何 大对象,或任何特定的(通过哈希 ID 已知)以前的大对象。这要求您能够在 Git 服务提供商上安装和维护挂钩。如果该提供商是 GitHub,则您无法执行此操作,但它们已经包含一个 "reject large objects" 挂钩,因此您 没有 无论如何。