Github远程推包尺寸超出

see*_*ers 24 git github git-push

我是Git的新手,有一个相当大的项目,我想推送到Github上的远程仓库(Repo B).最初的项目也在Github上,但来自不同的回购(Repo A).在我可以在Repo B上设置项目之前,我必须对Repo A中的文件进行一些更改.我已经设置了遥控器,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
Run Code Online (Sandbox Code Playgroud)

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

git config pack.packSizeLimit 1g
git config pack.windowMemory 1g
Run Code Online (Sandbox Code Playgroud)

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

我试图降低每包的尺寸....

git config pack.packSizeLimit 500m
git config pack.windowMemory 500m
Run Code Online (Sandbox Code Playgroud)

...并运行git gc(我看到重组了包,以便每个包保持在500MB的包装内).这也没用,我遇到了同样的错误.

我不确定Github的默认包装限制是什么(如果有的话).如果重要,该帐户是微型帐户.

oni*_*ake 26

packize限制不会影响git协议命令(推送).

git-configpack.packSizeLimit:

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

执行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
Run Code Online (Sandbox Code Playgroud)

这些推动都将有更小的包,并将成功.

  • 很好的答案 - 但我遇到了http://stackoverflow.com/q/28417845/1304104中描述的问题.基本上由于遥控器是干净的并且没有任何分支设置,我必须更具体,并且第一次推送具有以下形式:`git push remoteB <一些先前在master上的提交>:refs/heads/master` (9认同)
  • 推送每500次提交(反向不与skip混合):`max = $(git log --oneline | wc -l); for $ in $(seq $ max -500 1); 回声$ i; g = $(git log --reverse --oneline --skip $ i -n1 | perl -alne'print $ F [0]'); git push gh $ g:refs/heads/master; done` (4认同)
  • 如果我的初始提交导致此问题怎么办?我的仓库总大小为 30GB。 (3认同)
  • @PavelŠimerda 我知道这毕竟不是最好的解决方案,但有时您需要为最初没有创建的问题找到快速解决方案。一切都需要花费金钱和时间,而且我的客户意识到这是他现在需要处理的不便。不过还是谢谢。澄清一下,我的存储库中没有“大”文件,它只是大量的小文件。我说的是超过 300 个子项目,这些子项目很难拆分,因为它们是由与这些子项目完全集成的软件包装器结合在一起的。分拆成本太大 (3认同)
  • 如果我想使用 --mirror 推送裸存储库怎么办? (2认同)

Dan*_*ing 14

正如洋葱在他的回答中指出的那样,这个pack.packSizeLimit设置不会影响推动力.正如他所建议的那样,通常可以通过使用每次提交较少的多次推送来解决这个问题.rurban发布了关于如何自动推送500个提交块的评论.以下是他的评论的修改版本,无论远程分支是否存在或存在并且已经包含一些提交,一般都能正常工作.我还在调用库中添加了--first-parent参数,git log以便在存储库包含多个root提交时防止错误.我还进行了一些调整以提高效率,并添加了额外的调用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
Run Code Online (Sandbox Code Playgroud)

  • @0x11901 你可能使用的是 macOS,对吧?与 macOS 捆绑的“seq”略有不同。您可以使用 Homebrew 从 GNU core utils 安装 `seq`:`brew install coreutils`。然后将脚本中的“seq”替换为“gseq”。 (4认同)
  • 我认为这不适用于使用“--mirror”创建的裸存储库?(尝试在服务器之间迁移,使用 git filter-repo 删除旧的和大的文件)。现在看看 /sf/ask/2845698201/ (2认同)

Crt*_*ori 8

这是来自 @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'"
Run Code Online (Sandbox Code Playgroud)

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

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

[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'
    "
Run Code Online (Sandbox Code Playgroud)


ban*_*udu 7

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

Run Code Online (Sandbox Code Playgroud)