跳至主要内容

解决 2 GB 推送限制问题

了解如何解决 2 GB 推送限制问题。

关于推送限制

GitHub 对单次推送设置了 2 GB 的最大限制。首次尝试上传非常大的存储库、从其他平台导入大型存储库,或尝试重写大型现有存储库的历史记录时,你可能会遇到此限制。

如果你遇到此限制,你可能会看到以下错误消息之一

  • fatal: 远程端意外挂起
  • remote: fatal: 数据包超过允许的最大大小

你可以将推送拆分为较小的部分,或删除 Git 历史记录并从头开始。如果你已提交的单个提交大于 2 GB,并且无法删除 Git 历史记录并从头开始,那么你需要执行交互式变基,将大型提交拆分为多个较小的提交。

拆分大型推送

您可以通过将推送分解成更小的部分来避免达到限制,每个部分的大小应小于 2 GB。如果分支在此大小限制内,您可以一次性推送所有内容。但是,如果分支大于 2 GB,您需要将推送分解成更小的部分,一次只推送几个提交。

  1. 如果您尚未配置远程,请将存储库添加为新的远程。有关详细信息,请参阅“管理远程存储库”。

  2. 要在本地存储库的主分支历史记录中找到合适的提交,请运行以下命令

    git log --oneline --reverse refs/heads/BRANCH-NAME | awk 'NR % 1000 == 0'
    

    此命令显示每 1000 个提交。您可以增加或减少数字以调整步长。

  3. 将这些提交中的每一个一次性推送到您的 GitHub 托管存储库。

    git push REMOTE-NAME <YOUR_COMMIT_SHA_NUMBER>:refs/heads/BRANCH-NAME
    

    如果您看到消息 remote: fatal: pack exceeds maximum allowed size,请减小步骤 2 中的步长,然后重试。

  4. 对步骤 2 中历史记录中识别的每个提交执行相同过程。

  5. 如果这是第一次将此存储库推送到 GitHub,请执行最终镜像推送以确保推送所有剩余的 ref。

    git push REMOTE-NAME  --mirror
    

    如果仍然太大,您需要使用相同的步骤分阶段推送其他分支。

一旦您熟悉了该过程,您可以自动执行步骤 2 到 4 以简化过程。例如

step_commits=$(git log --oneline --reverse refs/heads/BRANCH-NAME | awk 'NR % 1000 == 0')
echo "$step_commits" | while read commit message; do git push REMOTE-NAME  $commit:refs/heads/BRANCH-NAME; done

从头开始

如果存储库没有任何历史记录,或者您的初始提交本身就超过 2 GB,并且您不介意重置 Git 历史记录,您也可以从头开始。

  1. 在您的本地副本中,删除隐藏的 .git 文件夹以删除所有以前的 Git 历史记录,并将其转换回一个装满文件的普通文件夹。

  2. 创建一个新的空文件夹。

  3. 在新文件夹上运行 git initgit lfs install,并将新的空 GitHub 存储库添加为远程。

  4. 如果您已经使用 Git 大型文件存储,并且在旧文件夹的 .gitattributes 文件中已经列出了您打算使用的所有 Git LFS 跟踪规则,那么这应该是您复制到新文件夹的第一个文件。您应该确保在添加任何其他文件之前就已制定跟踪规则,这样就不会有机会将打算用于 Git LFS 的内容提交到常规 Git 存储中。

    如果您尚未使用 Git LFS,您可以跳过此步骤,或者您可以在复制任何其他文件之前在新文件夹的 .gitattributes 文件中设置您打算使用的跟踪规则。有关详细信息,请参阅“配置 Git 大型文件存储”。

  5. 将小于 2 GB 的文件批次从旧文件夹移动到新文件夹。在每个批次移动后,在移动下一个批次之前创建提交并推送它。你可以采取谨慎的方法,并坚持大约 2 GB。或者,如果你有一个包含用于 Git LFS 的文件的文件夹,则在考虑每个批次的 2 GB 限制时可以忽略这些文件。

旧文件夹清空后,GitHub 存储库应包含所有内容。如果你正在使用 Git LFS,则所有用于 Git LFS 的文件都应推送到 Git LFS 存储。