Github 远程推送包大小超出

我是 Git 的新手,有一个相当大的项目,我想推到一个远程回购(回购 B)在 Github 上。最初的项目也在 Github 上,但是来自不同的回购(Repo 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 '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 (我看到它重新组织了包,使每个包保持在500 MB 的包大小内)。这也不起作用,我也遇到了同样的错误。

我不确定 Github 默认的包大小限制是什么(如果有的话)。如果有必要的话,这个账户是一个微型账户。

60701 次浏览

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

Git-config下 返回文章页面

包的最大大小。此设置仅影响重新包装时对文件的包装,即 git://protocol 不受影响

当执行一个 push 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

这些推进都会有更小的群体,并且会成功。

洋葱杰克在他的回答中指出,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

在大多数情况下,限制每次推送的提交次数(例如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


这里有一个来自@DanielHarding 的解决方案,您可以将其放入 .gitconfig中,然后使用 git partial-push origin branchname调用它(其中原点是所需的远程)

[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'
"