自安装 Big Sur 后,无法再 git 通过 HTTPS 克隆大型存储库

Can no longer git clone large repos via HTTPS since installing Big Sur

每当我尝试克隆大型存储库时,都会发生以下情况:

$ git clone https://github.com/yarnpkg/berry.git
Cloning into 'berry'...
remote: Enumerating objects: 60762, done.
remote: Counting objects: 100% (1155/1155), done.
remote: Compressing objects: 100% (588/588), done.
Receiving objects:   5% (3454/60762), 13.86 MiB | 4.60 MiB/ (etc etc)
fatal: fetch-pack: invalid index-pack output

我没有安装防病毒软件,也没有使用 VPN。我尝试连接到另一个网络,但没有解决问题,所以一定是 Big Sur 造成了这个问题。我不确定还能尝试什么。

macOS 11.4,APFS+ 文件系统,git2.31.1

我已经尝试过更改压缩设置,搞乱包大小设置,this post 也没有帮助。我发布这个是因为到目前为止我已经尝试了我在 Internet 上看到的所有其他方法,但没有任何效果。

这应该是评论(因为它不是答案)但我需要一些格式和 lot of space 在这里。简短的版本是您需要找出 git index-pack 行为不当或失败的原因。 (通过智能协议获取通常会检索到所谓的 thin 包,git fetch 需要使用 git index-pack --fix-thin 来“增肥”。)

如果 git index-pack 的输出与 git fetch-pack 的预期不匹配,则会出现“无效索引包输出”错误。 Here's the code involved:

char *index_pack_lockfile(int ip_out, int *is_well_formed)
{
    char packname[GIT_MAX_HEXSZ + 6];
    const int len = the_hash_algo->hexsz + 6;

    /*
     * The first thing we expect from index-pack's output
     * is "pack\t%40s\n" or "keep\t%40s\n" (46 bytes) where
     * %40s is the newly created pack SHA1 name.  In the "keep"
     * case, we need it to remove the corresponding .keep file
     * later on.  If we don't get that then tough luck with it.
     */
    if (read_in_full(ip_out, packname, len) == len && packname[len-1] == '\n') {
        const char *name;

        if (is_well_formed)
            *is_well_formed = 1;
        packname[len-1] = 0;
        if (skip_prefix(packname, "keep\t", &name))
            return xstrfmt("%s/pack/pack-%s.keep",
                       get_object_directory(), name);
        return NULL;
    }
    if (is_well_formed)
        *is_well_formed = 0;
    return NULL;
}

这是 fetch-pack.cget_pack function 中的 运行,其中 运行 和 git index-pack 的参数基于很多变量。如果你 运行 你的 git clone 环境变量 GIT_TRACE 设置为 1,你可以观察 Git 运行ning git index-pack。此处对 index_pack_lockfile 的调用仅在设置了 do_keep 时发生,它最初基于 args->keep_pack,但如果包头的 hdr_entries 值等于或超过 unpack_limit(参见第 859 行)。

您可以使用 fetch.unpackLimit and/or transfer.unpackLimit 控制 unpack_limit 值。默认值为 100。您也许可以使用它们来解决 index-pack 的一些问题,也许——但是 index-pack 不应该以任何方式失败 失败。请注意,如果您想强制 git fetch 使用 git unpack-objects,您还必须禁用对象检查 (fsck_objects)。

运行 git index-pack 直接在 git fetch 检索到的数据上也可能很有趣。 (考虑安装 shell 脚本代替正常的 git index-pack,脚本打印其参数,然后在其自己的进程组上使用 kill -STOP,以便您可以检查临时文件。 )

已解决!

TL;DR: ulimit 限制了我文件系统上的最大文件大小。为什么这在 Catalina 从来都不是问题,谁知道呢。

我的 shell 启动脚本中有这个:

ulimit -n 65536 65536

第二个参数是错误的。它将最大文件大小限制为 32MB。 St运行gely,我在 Catalina 上有完全相同的设置,它没有施加任何限制。一定是有人提供了这个设置,我没看明白就照搬了。

我运行ulimit -n unlimited unlimited现在一切都好!

关于从 Catalina 到 Big Sur 的 ulimit 变化的有趣说明:

我 运行 在我的 Catalina 安装上安装了这个:

$ ulimit -a                                                   
-t: cpu time (seconds)              unlimited
-f: file size (blocks)              65536
-d: data seg size (kbytes)          unlimited
-s: stack size (kbytes)             8192
-c: core file size (blocks)         0
-v: address space (kbytes)          unlimited
-l: locked-in-memory size (kbytes)  unlimited
-u: processes                       11136
-n: file descriptors                65536
$ mkfile 500m whoa                                             
$ 

看那个!创建 500MB 文件没问题,显然忽略了 ulimit 的 65536 块文件大小限制。

但在 Big Sur 上,具有相同的 ulimit 设置:

$ mkfile 500m whoa                                                                                                                               
[1]    22267 file size limit exceeded  mkfile 500m whoa