git 克隆失败并出现 "fatal: Out of memory, malloc failed" 错误

git clone fails with "fatal: Out of memory, malloc failed" error

当我在本地服务器上从项目的 裸存储库 执行 git 克隆 时,我得到以下错误消息:

fatal: Out of memory, malloc failed (tried to allocate 2251896833 bytes) warning: Clone succeeded, but checkout failed. You can inspect what was checked out with 'git status' and retry the checkout with 'git checkout -f HEAD'

我尝试更新我的 ~/.gitconfig 文件,如 this question 下的回答所述,关闭 git bash,重新启动并重试,但没有任何结果。

我最终尝试了以下配置,但结果仍然相同:

$ cat .gitconfig
[core]
        packedGitLimit = 1024m
        packedGitWindowSize = 1024m
[pack]
        deltaCacheSize = 1024m
        packSizeLimit = 1024m
        windowMemory = 1024m
[http]
        postBuffer = 157286400

我什至在另一台机器上尝试过 git gc,但不确定如何让裸存储库也进行垃圾收集。

我在 32 bits 机器上使用 git version 2.14.2.windows.1 Windows 7 和 4GB 内存。

如何解决 git 克隆上的这个致命错误?

利用 Git 存储库是独立的并且可以复制的事实,我们只需要一些方法来制作副本并将我们的前几次尝试从裸转换为非裸。

如果可能的话,克隆仍然是初始复制的最佳形式(参见解决方法 1 和 2)。如果没有,我们可以直接从服务器复制,如果访问可用,然后手动转换(参见#3)。如果做不到这一点,也许 copying/cloning 一小部分回购协议会起作用?

解决方法 1 - 从服务器克隆到 USB

进入服务器(如果你有访问权限),克隆到一个 USB 驱动器文件夹(作为非裸仓库),将 USB 插入目标机器,然后 move/copy 它到你的最终位置想要回购协议。 Git 命令应该是:

git clone /path/to/bare/repo /local/repo/folder

认为这不会复制任何孤儿提交(那些最终将被垃圾收集的提交)。

解决方法 2 - 克隆到另一台 PC,然后复制

将存储库克隆到另一台 PC,copy/move 文件夹以某种方式指向目标 PC(USB、网络连接等)。类似于#1

解决方法 3 - 从服务器复制,从裸机转换

这假设可以访问服务器,可能是通过网络共享而不是直接访问(否则使用#1)。将裸仓库复制到本地,然后执行一些操作 like this 将其转换为非裸仓库。

解决方法 4a - 一次只克隆一个分支

It appears you can clone only a single branch at a time,这可能会导致内存问题:

git clone [url/folder] -b master --single-branch [local repo folder]

请注意,您可以在服务器上创建历史稍早的新分支,以一次性减少拉取次数,但根据上述 link 中的答案,您可能需要跳过一些箍删除新回购的 "single-branchedness"。

解决方法 4b - 浅层回购

使用--depth <depth> and/or 其他浅层标记来创建具有有限提交历史深度的本地仓库。来自 git clone --help 手册页:

--depth Create a shallow clone with a history truncated to the specified number of commits. Implies --single-branch unless --no-single-branch is given to fetch the histories near the tips of all branches. If you want to clone submodules shallowly, also pass --shallow-submodules.

--shallow-since= Create a shallow clone with a history after the specified time.

--shallow-exclude= Create a shallow clone with a history, excluding commits reachable from a specified remote branch or tag. This option can be specified multiple times.

--[no-]single-branch Clone only the history leading to the tip of a single branch, either specified by the --branch option or the primary branch remote’s HEAD points at. Further fetches into the resulting repository will only update the remote-tracking branch for the branch this option was used for the initial cloning. If the HEAD at the remote did not point at any branch when --single-branch clone was made, no remote-tracking branch is created.

解决方法 4c - Clone/Checkout 一次只有一些文件

请参阅 this answer 并在 link 中了解有关如何一次只提取一部分存储库的说明。丑陋,但可以一次克隆一部分。

如果您使用的是 Linux 并且具有 root 访问权限,添加虚拟内存 的简单解决方法可能是最简单的解决方案。在大多数 Linux 系统上,您可以执行以下操作(以 root 身份)来添加 4GiB 的虚拟内存,然后在之后再次尝试 git 克隆:

dd if=/dev/zero of=/var/swap.img bs=1M count=4096
chmod 0600 /var/swap.img
mkswap /var/swap.img
swapon /var/swap.img

当我 运行 解决这个问题时,这对我来说是最简单可行的解决方案。

同时检查 ulimit。在 AIX 上,我有(没有 malloc 失败的问题):

> ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) unlimited
pipe size            (512 bytes, -p) 64
stack size              (kbytes, -s) unlimited
cpu time               (seconds, -t) unlimited
max user processes              (-u) unlimited
virtual memory          (kbytes, -v) unlimited

遇到此 malloc 失败问题的用户有:

> ulimit -a
core file size          (blocks, -c) 1048575
data seg size           (kbytes, -d) 131072
file size               (blocks, -f) 1048575
max memory size         (kbytes, -m) 32768
open files                      (-n) 2000
pipe size            (512 bytes, -p) 64
stack size              (kbytes, -s) 32768
cpu time               (seconds, -t) unlimited
max user processes              (-u) unlimited
virtual memory          (kbytes, -v) unlimited