跳至主要内容

排查 2 GiB 推送限制问题

了解如何规避 2 GiB 推送限制。

本文内容

关于推送限制

GitHub 对单次推送设有最高 2 GiB 的限制。当您首次上传非常大的仓库、从其他平台导入大型仓库,或尝试重写大型现有仓库的历史时,可能会遇到此限制。

如果触及此限制,您可能会看到以下错误信息之一

  • fatal: the remote end hung up unexpectedly
  • remote: fatal: pack exceeds maximum allowed size

您可以将推送拆分为更小的部分,或删除 Git 历史记录并重新开始。如果您已经提交了一个超过 2 GiB 的单次提交且无法删除 Git 历史并重新开始,则需要执行交互式 rebase,将大提交拆分为多个更小的提交。

拆分大推送

通过将推送分割成更小的部分(每个均应小于 2 GiB),您可以避免触及此限制。如果某分支在该大小限制内,您可以一次性全部推送。然而,如果分支大于 2 GiB,您需要将推送拆分为更小的块,并一次只推送少量提交。

  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,请执行最后一次镜像推送,以确保所有剩余引用均已推送。

    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 GiB 且您不介意重置 Git 历史,也可以从头开始。

  1. 在本地副本中,删除隐藏的 .git 文件夹,以移除所有先前的 Git 历史记录,并将其恢复为普通文件夹。

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

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

  4. 如果您已经在使用 Git 大文件存储(Git LFS),并且在旧文件夹的 .gitattributes 文件中已列出所有计划使用的 Git LFS 跟踪规则,则该文件应首先复制到新文件夹。在添加其他文件之前,请确保已设置好跟踪规则,这样才能避免本应由 Git LFS 管理的文件被提交到普通 Git 存储中。

    如果您尚未使用 Git LFS,可以跳过此步骤;或者在复制其他文件之前,在新文件夹的 .gitattributes 文件中设置您计划使用的跟踪规则。欲了解更多信息,请参阅配置 Git 大文件存储

  5. 将小于 2 GiB 的文件批次从旧文件夹移动到新文件夹。每移动完一批后,创建一次提交并推送,然后再移动下一批。您可以采用保守做法,保持每批约 2 GiB。或者,如果您有专用于 Git LFS 的文件夹,在计算每批 2 GiB 限制时可以忽略这些文件。

当旧文件夹清空后,GitHub 仓库应包含所有内容。如果您使用 Git LFS,所有应由 Git LFS 管理的文件都应已推送至 Git LFS 存储。

© . This site is unofficial and not affiliated with GitHub, Inc.