如何将 refs 拆分为跨多个命令推送的块?

How to split refs into chunks that are pushed accross several commands?

假设我有一个包含大量版本(标签)的存储库。存储库有效并且 git fsck 没有报告任何内容。 但是当我通过 ssh 推送存储库时,我得到了 remote: Internal Server Error.

经过调查,似乎这是大量 refs 的问题。我尝试设置一个包含 4100 个分支的回购协议,但消息更加冗长 (manyfailed to lock).

重现步骤:将具有超过 5000 个引用的存储库推送到 GitHub 或 GitHub 企业上的新空存储库。 或者只是 fork this repo.

有没有办法解决这个问题,而不必将回购分成几个部分来推送它?

很难复现,估计是服务器端的资源问题。可能是内存不足。

要验证这一点,您可以一个接一个地推送参考。从 'oldest' 参考开始。这是被引用的历史上最早的提交。

只需使用 refspec 推送一个 ref。例如。如果最旧的 ref 是一个名为 v1.0.0 的标签 do

git push <REMOTE_REPO> refs/tags/v1.0.0:refs/tags/v1.0.0

如果可行,您可以继续编写一个小脚本。

git for-each-ref --format="%(refname)" --sort='authordate' refs/heads refs/tags | \
while read ref; 
do git push <REMOTE_REPO> $ref:$ref
done

我 运行 在尝试推送具有大约 50,000 个引用的 repo 时遇到了同样的问题。 Github 支持指出我唯一的选择是一次推送一小块 refs。

这是我使用的命令行(如果您的引用位于不同的命名空间下,即 refs/replace,请使用它而不是 refs/heads)。

git for-each-ref --format="%(refname)" --sort='authordate' refs/heads | xargs git push origin

Shell 对命令行字符串的大小有限制,xargs 会智能地拆分命令以保持在该限制内。我发现 Github 能够处理 xargs 一次推送的数量,但 YMMV。如果您仍然达到 Github 限制,请使用 max-args 选项(可能需要反复试验)。

git for-each-ref --format="%(refname)" --sort='authordate' refs/heads | xargs --max-args=<1000> git push origin