近期发现磁盘少了几十G,经过排查,发现是opencode快照机制导致的,这里给出删除快照示例(以删除最新会话和global为例)和禁用快照的方法
1.删除无用快照目录文件
到Linux或Mac系统的用户级数据目录/Users/用户名/.local/share/(win系统一般是C:\Users\用户名\AppData\Local\)的opencode可以看见已经达到近13g了,其中最新会话达到近2.5g,global达到近10g



终端执行opencode打开界面,执行/sessions查看会话,按下按键CTRL+d两次删除最新会话


按esc按键退出会话管理,再执行/exit退出


在opencode界面删除会话后,可以发现那个会话目录占用空间没有减少反而增加

确保所有的opencode关闭后,有两种方法处理
方法1
如果磁盘空间只剩8g以下,建议先用手动删除或执行rm -rf目录路径(注意一定要确认文件夹无用才执行,手动删除需去垃圾桶再删除一次,下同)
Mac可参考复用排查命令,你可以把它能改成sh脚本
#!/bin/bash
# 清理 OpenCode 已删除会话的快照
SNAPSHOT_DIR="$HOME/.local/share/opencode/snapshot"
echo "当前快照占用:"
du -sh "$SNAPSHOT_DIR"/*/ 2>/dev/null | sort -hr
echo -e "\n建议:删除已确认删除的对话快照,保留 global 目录"
echo "手动删除命令示例:"
echo " rm -rf $SNAPSHOT_DIR/<session-id>/"

可以在/Users/Zhuanz/.local/share/opencode/snapshot/global/objects/pack看到global占用磁盘的罪魁祸首是无用的tmp_pack文件

手动删除或执行rm -rf目录路径手动删除无用的tmp_pack文件
方法2
如果磁盘空间在10g以上,建议执行命令(仅供参考,要根据系统和路径修改)
# 定义变量 G,指向 OpenCode 的全局快照 Git 仓库目录
G=/Users/Zhuanz/.local/share/opencode/snapshot/global
# 1. 立即过期所有 reflog 条目,清除操作历史引用
git --git-dir="$G" reflog expire --expire=now --all
# 2. 重新打包 Git 对象,合并松散对象并删除冗余包文件
git --git-dir="$G" repack -Ad
# 3. 立即删除所有不可达的松散 Git 对象
git --git-dir="$G" prune --expire=now
# 4. 执行 Git 垃圾回收,立即修剪不可达对象
git --git-dir="$G" gc --prune=now
# 5. 查看该目录的磁盘占用大小(人类可读格式)
du -sh "$G"
作用:
-
清掉不可达对象
-
重打包
-
把“已经删除会话不再引用”的内容真正回收掉
重打包的过程会增长占用磁盘空间,快照目录的global/objects在重打包过程会生成很多文件夹,导致占用几g(我执行的情况是达到3g左右),但执行完能删除无用内容

执行后减少7g左右的磁盘占用空间

如果还想进一步删除无用文件,可选删除log文件夹的文件

2.禁用项目快照
为了避免扫描到项目的无用文件生成大量快照,可以在你的项目根目录放config.json或config.jsonc(可写注释)文件,内容参考如下
{
"$schema": "https://opencode.ai/config.json",
"snapshot": false
}

如果不需要任何项目的快照,将内容放在以下参考位置
macOS/Linux: ~/.config/opencode/opencode.jsonc(或 ~/.config/opencode/opencode.json)
macOS/Linux(旧版安装): ~/.local/share/opencode/opencode.jsonc
Windows: 按 WIN+R 并粘贴 %USERPROFILE%\.config\opencode\opencode.jsonc
3.发现与总结
1)OpenCode snapshot 使用 Git 风格对象库
~/.local/share/opencode/snapshot/ 目录本质是 Git-style object store:
典型结构:
snapshot/
├─ global/
│ ├─ objects/
│ │ └─ pack/
│ ├─ refs/
│ ├─ HEAD
│ └─ packed-refs
└─ <session-hash>/
└─ objects/
└─ ...
特点:
-
对象使用 SHA1(40 hex)命名
-
objects/xx/yyyy... 是 loose objects
-
objects/pack/*.pack 是 packfile
这和 Git 内部存储完全一致。
可参考架构图
2) global 是共享对象池(object pool)
global 目录用于保存 跨会话共享对象。
作用:
-
减少重复存储
-
加速 snapshot
-
允许不同会话引用同一 blob/tree
也就是说:session snapshot -> shared objects -> snapshot/global
3)每个 session 也有自己的对象库
每个 session hash 目录:
snapshot/<session-hash>/
包含:
-
session 独有对象
-
session commit / tree
-
session metadata
这些对象会:
-
部分写入 session
-
部分写入 global
4)为什么会占用大量磁盘空间
主要原因有三个:
a)snapshot 会记录整个项目文件状态
如果目录很大(node_modules、build、缓存等):
snapshot 会生成大量 blob。
即使对话很短:snapshot size ≠ conversation size
b) loose objects 没被打包
Git 默认写入 loose object:objects/aa/bbbbb...
数量多时:
-
inode 爆炸
-
体积膨胀
-
性能下降
c)packfile / tmp_pack 泄漏
出现了tmp_pack_xxx这类 repack 中间文件。
OpenCode 的 snapshot 确实有人报告:
-
tmp_pack 没清理
-
packfile 膨胀
5)为什么 gc/repack 会先涨空间
这是 Git 正常行为。
repack -Ad 的流程:
1️⃣ 读取旧 pack
2️⃣ 生成新 pack
3️⃣ 写入磁盘
4️⃣ 删除旧 pack
因此在中间阶段:磁盘占用 ≈ old pack + new pack
所以可以看到objects 目录突然增长,这是正常的。
6)长期解决方案
在项目配置文件关闭 snapshot,并定期清理快照文件夹
创作不易,禁止抄袭,转载请附上原文链接及标题


363

被折叠的 条评论
为什么被折叠?



