返回
创建于
状态公开

解决 fatal: early EOF fatal: index-pack failed

https://stackoverflow.com/questions/21277806/fatal-early-eof-fatal-index-pack-failed

First, turn off compression:

js
1git config --global core.compression 0

Next, let's do a partial clone to truncate the amount of info coming down:

js
1git clone --depth 1 <repo_URI>

When that works, go into the new directory and retrieve the rest of the clone:

js
1git fetch --unshallow

or, alternately,

js
1git fetch --depth=2147483647

Now, do a regular pull:

js
1git pull --all

I think there is a glitch with msysgit in the 1.8.x versions that exacerbates these symptoms, so another option is to try with an earlier version of git (<= 1.8.3, I think).

实际体验,因为我是已经 clone 的项目,因为一个大文件导致 git pull 报错

bash
1fetch-pack: unexpected disconnect while reading sideband packet
2fatal: early EOF
3fatal: fetch-pack: invalid index-pack output

已存在的项目,直接设置下面的配置就好了。

bash
1git config --global core.compression 0

core.compression 设置为 0 的影响

core.compression 设置为 0 会导致磁盘空间使用网络传输相关的操作变慢,原因如下:

1. Git 存储相关操作

  • 影响的操作
    • git add
    • git commit
    • git gc
    • git repack
  • 原因
    • core.compression 0 表示完全不进行压缩,Git 对文件对象(如 blob、tree 和 commit)直接以原始数据形式存储,而不是以压缩后的形式存储到 .pack 文件中。
    • 结果是 .git/objects 文件夹中生成的对象会非常大,占用更多磁盘空间。
  • 变慢的地方
    • 磁盘 I/O:存储未压缩的对象会增加写入数据的量,尤其是对于大文件,磁盘 I/O 时间会显著增加。
    • 清理和打包操作:git gcgit repack 时需要处理未压缩的数据,操作耗时更长。

2. 网络传输相关操作

  • 影响的操作
    • git clone
    • git fetch
    • git pull
    • git push
  • 原因
    • 未压缩的 .pack 文件在传输时体积较大,会显著增加网络带宽的使用。
    • 对于远程仓库的操作,Git 默认会将对象打包并压缩后传输(即使 core.compression 设置为 0,传输时也可能会重新压缩,但效果较差)。
  • 变慢的地方
    • 网络瓶颈:传输未压缩数据需要更多的时间,尤其在网络速度较慢或延迟较高的情况下。

3. 备份与迁移相关操作

  • 影响的操作
    • 仓库的拷贝或迁移(如 scprsync
  • 原因
    • 仓库体积更大,备份时间和迁移时间也会更长。

适用场景

  • 在性能敏感的环境下,不建议设置 core.compression 0,除非你明确知道这对性能有益。例如:
    • 临时禁用压缩以加速初始化大型仓库(如 git clone)。
    • 在后续操作中,结合 git repack -a -d --depth=250 --window=250 手动优化。

总结

core.compression 0 的主要问题在于:

  • 增加了 I/O 负载:磁盘操作效率下降。
  • 消耗了更多网络带宽:传输效率下降。

因此,在大多数情况下,建议保持默认值(2)或根据需要调整为合适的压缩级别(1-9)。

相关说明

Git 配置中的 core.compression 参数用于指定 Git 在压缩对象(如存储到 .pack 文件中)时使用的压缩级别。以下是关于 git config --global core.compression 的详细说明:

  1. 默认值: 如果未手动设置 core.compression,其默认值通常是 2

    • 值为 2 表示使用适度的压缩级别,以在压缩速度和压缩效率之间取得平衡。
    • Git 使用的压缩算法是基于 zlib 的 deflate 算法。
  2. 用户设置 core.compression 0 的影响

    • 设置为 0 表示不进行压缩
    • 这可能会加快某些操作(如 git clonegit push 等)的速度,但会显著增加存储和传输的大小。
  3. 其他可能的值

    • 1 到 9:值越高,压缩率越高,但压缩速度越慢。
    • -1:使用 zlib 的默认压缩级别(通常是 6)。
  4. 配置示例

    • 查看当前设置:

      bash
      1git config --global core.compression
    • 设置为不压缩:

      bash
      1git config --global core.compression 0
    • 恢复到默认压缩级别:

      bash
      1git config --global --unset core.compression

总结git config --global core.compression 0 将关闭压缩,默认值为 2(中等压缩)。一般来说,默认值已经是性能和存储的合理折中,除非在网络或硬件受限的情况下,一般无需修改该参数。

git gc

git gc 是 Git 提供的一个命令,用于清理和优化本地仓库的存储空间。gc 是 “garbage collect”(垃圾收集)的缩写,它会对 Git 仓库执行一系列清理操作,以提升性能和节省磁盘空间。

主要作用

  1. 压缩对象文件

    • Git 会将松散的对象(loose objects)打包成一个或多个包文件(packfile),减少文件数量,从而提升读取性能和节省磁盘空间。
  2. 删除冗余数据

    • 移除已经被标记为不可达的对象(如被删除的分支或回滚的提交),释放磁盘空间。
  3. 优化引用(refs)

    • 将引用(refs)压缩到单个文件中,提高效率。
  4. 合并日志文件

    • 将多个日志文件(如 reflog)合并,减少文件碎片。
  5. 清理临时文件

    • 删除不再需要的临时文件,如中断操作遗留下来的文件。

常用选项

  • --prune=<time>:删除比指定时间更早的不可达对象(默认值为两周前)。
  • --aggressive:执行更彻底的优化,会消耗更多时间和资源。
  • --auto:只有在需要时才运行垃圾收集(根据仓库的大小和状态自动判断是否需要运行)。

示例

  1. 基本用法

    bash
    1git gc

    运行默认的垃圾收集操作。

  2. 删除旧的不可达对象

    bash
    1git gc --prune=now

    删除所有当前不可达的对象(无需等待默认的两周时间)。

  3. 强制优化

    bash
    1git gc --aggressive

    使用更激进的策略进行压缩和优化。

注意事项

  • 安全性git gc 不会删除当前引用(如分支、标签)可达的对象,因此对当前工作没有影响。
  • 性能:在大型仓库中,git gc 可能耗时较长,特别是使用 --aggressive 参数时。
  • 自动触发:Git 会根据仓库状态自动运行垃圾收集(例如在提交时达到一定的对象数量阈值时),所以手动运行通常不是必须的。

通过运行 git gc,可以保持仓库的高效运行,尤其是在频繁操作(如合并、删除分支)后。