【问题标题】:Github remote push pack size exceeded超过 Github 远程推送包大小
【发布时间】:2021-09-06 20:14:00
【问题描述】:

我是 Git 新手,并且有一个相当大的项目,我想将其推送到 Github 上的远程仓库 (Repo B)。最初的项目也在 Github 上,但来自不同的 repo (Repo A)。我必须先对 Repo A 中的文件进行一些更改,然后才能在 Repo B 上设置项目。我已经设置了遥控器、ssh 密钥等,并且在将代码库推送到 Repo B 时遇到了问题。

我一直收到以下错误:

$ git push <remote_repo_name> master
Enter passphrase for key '/c/ssh/.ssh/id_rsa':
Counting objects: 146106, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (35519/35519), done.
fatal: pack exceeds maximum allowed size00 GiB | 154 KiB/s
fatal: sha1 file '<stdout>' write error: Invalid arguments
error: failed to push some refs to 'git@github.com:<repo>.git

我在本地 gitconfig 中更改了以下设置

git config pack.packSizeLimit 1g
git config pack.windowMemory 1g

... 并运行 git gc (我看到它重新组织了包,使每个包都保持在 1GB 的包大小内)。这不起作用,我得到了上面看到的错误。

我也尝试减小每个包装的大小....

git config pack.packSizeLimit 500m
git config pack.windowMemory 500m

... 并运行 git gc (我看到它重新组织了包,使每个包都保持在 500MB 的包大小内)。这也不起作用,我遇到了同样的错误。

我不确定 Github 的默认包大小限制是多少(如果有的话)。如果重要的话,该帐户是一个微型帐户。

【问题讨论】:

  • 你在 Unix/Linux 机器上吗?如果是,请在您的工作存储库中输入 du -sk . 并将其添加到您的问题中。 GitHub doesn't have a limit,但我很好奇你的二进制文件有多大。
  • 考虑this answer,它讨论了http.postBuffer等的使用。

标签: git github git-push


【解决方案1】:

嗯,在大多数情况下,限制每次推送中的提交计数(例如 500)是有帮助的。但它无法解决单个大提交导致的错误。

如果单个大提交超过了 git 服务器的限制大小,则限制提交计数(甚至为 1)将无济于事。

修复单个大提交:

  1. 如果此提交包含多个文件,可以通过创建子提交和合并提交来解决。
  2. 如果是单个大文件,那就没有好的解决方案了。

修复包含多个文件的单个大型提交(例如 file1、file2、...、file10)

git checkout -b tmp SINGLE_LARGE_COMMIT^
git add file1 file2 file3 file4  # add a sub-class of files inside SINGLE_LARGE_COMMIT
git commit -m 'sub-commit'
git push origin tmp
git merge master  # or any other branch which contains SINGLE_LARGE_COMMIT
git push origin tmp
git checkout master
git push origin master # success

【讨论】:

    【解决方案2】:

    正如 onionjake 在他的回答中指出的那样,pack.packSizeLimit 设置 does not affect pushes。正如他所建议的,这通常可以通过使用每次提交较少的多次推送来解决。 rurban 发表了关于如何自动推送 500 次提交的评论。以下是他评论的修改版本,无论远程分支是否存在或是否存在并且已经包含一些提交,都可以正常工作。我还在git log 调用中添加了--first-parent 参数,以防止在存储库包含多个根提交时出错。我还进行了一些调整以提高效率,并添加了对git push 的额外调用以推送最终(部分)批次的提交:

    # Adjust the following variables as necessary
    REMOTE=origin
    BRANCH=$(git rev-parse --abbrev-ref HEAD)
    BATCH_SIZE=500
    
    # check if the branch exists on the remote
    if git show-ref --quiet --verify refs/remotes/$REMOTE/$BRANCH; then
        # if so, only push the commits that are not on the remote already
        range=$REMOTE/$BRANCH..HEAD
    else
        # else push all the commits
        range=HEAD
    fi
    # count the number of commits to push
    n=$(git log --first-parent --format=format:x $range | wc -l)
    
    # push each batch
    for i in $(seq $n -$BATCH_SIZE 1); do
        # get the hash of the commit to push
        h=$(git log --first-parent --reverse --format=format:%H --skip $i -n1)
        echo "Pushing $h..."
        git push $REMOTE ${h}:refs/heads/$BRANCH
    done
    # push the final partial batch
    git push $REMOTE HEAD:refs/heads/$BRANCH
    

    【讨论】:

    • seq:需要正增量
    • 0x11901 - 介意解释一下吗?代码使用 seq 负增量,因为我们希望 git log 跳过越来越少的提交,以便推送每个批次。
    • @0x11901 您可能正在使用 macOS,对吧? seq 与 macOS 捆绑在一起略有不同。您可以使用 Homebrew 从 GNU 核心实用程序安装 seqbrew install coreutils。然后将脚本中的seq 替换为gseq
    • 我认为这不适用于使用“--mirror”创建的裸存储库? (尝试在服务器之间迁移,使用 git filter-repo 删除了旧文件和大文件)。现在看stackoverflow.com/questions/40652831/…
    • @EdRandall 它很可能不适用于裸存储库。我只是回顾了一下命令,没有看到任何需要工作树的命令,但我从未在裸仓库上测试过它。
    【解决方案3】:

    packsize 限制不影响 git 协议命令(您的推送)。

    来自git-configpack.packSizeLimit:

    一包的最大尺寸。此设置仅在重新打包时影响打包到文件,即git:// 协议不受影响

    执行推送时,无论大小,git 总是会创建一个包!

    要解决此问题,请使用两次(或更多)推送:

    git push remoteB <some previous commit on master>:master
    ...
    git push remoteB <some previous commit after the last one>:master
    git push remoteB master
    

    这些推送都会有更小的包并且会成功。

    【讨论】:

    • 很好的答案 - 但我遇到了stackoverflow.com/q/28417845/1304104 中描述的问题。基本上由于遥控器是干净的并且没有任何分支设置,我必须更具体,第一次推送是以下形式:git push remoteB &lt;some previous commit on master&gt;:refs/heads/master
    • 每 500 次提交推送一次(反向不与跳过混合):max=$(git log --oneline|wc -l); for i in $(seq $max -500 1); do echo $i; g=$(git log --reverse --oneline --skip $i -n1|perl -alne'print $F[0]'); git push gh $g:refs/heads/master; done
    • 如果我的初始提交导致了这个问题怎么办?我的仓库总大小为 30GB。
    • 我有@MartinBraun 相同的问题。这是从我的本地服务器初次提交/上传 repo 吗?
    • @PavelŠimerda 我知道这毕竟不是最好的解决方案,但有时您需要为您一开始没有创建的问题找到快速解决方案。一切都需要金钱和时间,而且我的客户知道这是他现在需要处理的不便。谢谢,尽管如此。为了澄清事情,我的仓库中没有“大”文件,它只是大量的小文件。我说的是 300 多个难以拆分的子项目,因为它们由与这些子项目完全集成的软件包装器结合在一起。拆分成本太高
    猜你喜欢
    • 2022-07-12
    • 1970-01-01
    • 2018-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-25
    相关资源
    最近更新 更多