Github远程推送包大小超出

问题描述 投票:0回答:4

我是 Git 新手,有一个相当大的项目,我想将其推送到 Github 上的远程存储库(存储库 B)。原始项目也在 Github 上,但来自不同的存储库(存储库 A)。我必须对存储库 A 中的文件进行一些更改,然后才能在存储库 B 上设置项目。我已经设置了遥控器、ssh 密钥等,并且在将代码库推送到存储库 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 '[email protected]:<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 的默认包大小限制是多少(如果有)。如果重要的话,该帐户是微型帐户。

git github git-push
4个回答
58
投票

包大小限制不会影响 git 协议命令(您的推送)。

来自 git-config

pack.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

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


50
投票

正如 onionjake 在他的回答中指出的那样,

pack.packSizeLimit
设置不会影响推送。正如他所建议的,这通常可以通过使用多次推送(每次提交较少)来解决。 rurban 发表了关于如何自动推送 500 次提交的评论。以下是他的评论的修改版本,无论远程分支是否不存在或存在并且已经包含一些提交,都可以正常工作。我还在
--first-parent
调用中添加了
git log
参数,以防止存储库包含多个根提交时出现错误。我还做了一些调整来提高效率,并添加了对
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

7
投票

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

如果单个大提交超过了 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


4
投票

这是 @DanielHarding 的解决方案,您可以将其放入

.gitconfig
中,然后使用
git partial-push origin branchname
调用它(其中 origin 是您想要的遥控器)

[alias]
    partial-push = "!sh -c 'REMOTE=$0;BRANCH=$1;BATCH_SIZE=100; if git show-ref --quiet --verify refs/remotes/$REMOTE/$BRANCH; then range=$REMOTE/$BRANCH..HEAD; else range=HEAD; fi; n=$(git log --first-parent --format=format:x $range | wc -l); echo "Have to push $n packages in range of $range"; for i in $(seq $n -$BATCH_SIZE 1); do h=$(git log --first-parent --reverse --format=format:%H --skip $i -n1);  echo "Pushing $h..."; git push $REMOTE ${h}:refs/heads/$BRANCH; done; git push $REMOTE HEAD:refs/heads/$BRANCH'"

它基本上所做的就是获取需要推送的提交范围,然后一一推送。这可能需要相当长的时间,但最终它会自动完成这项工作。

这是上面的一行行,有一些间距,以便于阅读:

[alias]
    partial-push = "!sh -c 
        'REMOTE=$0;BRANCH=$1;BATCH_SIZE=100;
        if git show-ref --quiet --verify refs/remotes/$REMOTE/$BRANCH; then
            range=$REMOTE/$BRANCH..HEAD;
        else
            range=HEAD;
        fi;
        n=$(git log --first-parent --format=format:x $range | wc -l);
        echo "Have to push $n packages in range of $range";
        for i in $(seq $n -$BATCH_SIZE 1); do
            h=$(git log --first-parent --reverse --format=format:%H --skip $i -n1);
            echo "Pushing $h...";
            git push $REMOTE ${h}:refs/heads/$BRANCH;
        done;
        git push $REMOTE HEAD:refs/heads/$BRANCH'
    "
© www.soinside.com 2019 - 2024. All rights reserved.