macOS 清理 Codex / Claude Code / OpenCode Worktree 指南

macOS 清理 Codex / Claude Code / OpenCode Worktree 指南

長期使用 Codex、Claude Code、OpenCode,尤其搭配 Git Worktree / Subagent 後,很容易累積大量:

最後吃掉數十 GB。

1. 先找出誰最佔空間

du -sh \
  ~/.codex/worktrees \
  ~/.codex/sessions \
  ~/.claude \
  ~/.local/share/opencode \
  ~/.cache/opencode \
  2>/dev/null

通常真正的大戶是 Worktree,而不是 Session / Log

2. 找出所有 Worktree 容量

find "$HOME" \
  \( -path "$HOME/Library" \
     -o -path '*/node_modules' \
     -o -path '*/.venv' \) -prune \
  -o -type f -name .git -print0 2>/dev/null |
while IFS= read -r -d '' gitfile; do
  wt="${gitfile%/.git}"
  du -sh "$wt" 2>/dev/null
done |
sort -hr

常見的大戶:

<project>/.worktrees/*
<project>/.claude/worktrees/*
每個 Worktree 都有一份 dependencies

每個 Worktree 都可能各自有一份 dependencies / build artifacts,這是磁碟爆掉的主因。

3. 設定 Project 變數

後續指令統一使用:

PROJECT_NAME="your-project"
PROJECT_ROOT="$HOME/Projects/$PROJECT_NAME"

cd "$PROJECT_ROOT"

只要修改 PROJECT_NAME 即可套用到不同 Repo。

4. 查看 Worktree 狀態

git worktree list --porcelain |
awk '/^worktree / {print substr($0, 10)}' |
while IFS= read -r wt; do
  size=$(du -sh "$wt" 2>/dev/null | cut -f1)
  branch=$(git -C "$wt" branch --show-current 2>/dev/null)
  changes=$(git -C "$wt" status --porcelain 2>/dev/null | wc -l | tr -d ' ')
  last=$(git -C "$wt" log -1 --format='%cr' 2>/dev/null)

  printf "%-8s changes=%-3s %-45s %s\n" \
    "$size" "$changes" "${branch:-DETACHED}" "$last"
done

例如:

1.3G  changes=0  fix/price-health      12 days ago
1.3G  changes=0  fix/timezone          12 days ago
1.7G  changes=0  feature/public-demo   32 minutes ago
changes=0 不代表已 Merge

changes=0 代表沒有未提交變更,但不代表已 Merge

5. 清除自建 Worktrees

假設自建 Worktree 位於:

<project>/.worktrees/

執行:

PROJECT_NAME="your-project"
PROJECT_ROOT="$HOME/Projects/$PROJECT_NAME"
WORKTREE_ROOT="$PROJECT_ROOT/.worktrees"

cd "$PROJECT_ROOT"

git worktree list --porcelain |
awk '/^worktree / {sub(/^worktree /, ""); print}' |
while IFS= read -r wt; do
  case "$wt" in
    "$WORKTREE_ROOT"/*)
      echo "Removing: $wt"
      git worktree remove "$wt"
      ;;
  esac
done

git worktree prune

建議使用:

git worktree remove

而不是:

rm -rf .worktrees

這樣 Git 也會同步清除 Worktree metadata,而且沒有 --force 時,有未提交變更的 Worktree 會被保護。

6. 清除 Claude Code Agent Worktrees

Claude Code / Subagent 可能留下:

<project>/.claude/worktrees/agent-*

批次清除:

PROJECT_NAME="your-project"
PROJECT_ROOT="$HOME/Projects/$PROJECT_NAME"
WORKTREE_ROOT="$PROJECT_ROOT/.claude/worktrees"

cd "$PROJECT_ROOT"

git worktree list --porcelain |
awk '/^worktree / {sub(/^worktree /, ""); print}' |
while IFS= read -r wt; do
  case "$wt" in
    "$WORKTREE_ROOT"/*)
      echo "Removing: $wt"
      git worktree remove "$wt"
      ;;
  esac
done

git worktree prune

7. 一次清除自建 + Claude Worktrees

PROJECT_NAME="your-project"
PROJECT_ROOT="$HOME/Projects/$PROJECT_NAME"

cd "$PROJECT_ROOT"

git worktree list --porcelain |
awk '/^worktree / {sub(/^worktree /, ""); print}' |
while IFS= read -r wt; do
  case "$wt" in
    "$PROJECT_ROOT/.worktrees/"*|\
    "$PROJECT_ROOT/.claude/worktrees/"*)
      echo "Removing: $wt"
      git worktree remove "$wt"
      ;;
  esac
done

git worktree prune
Branch 會保留

Worktree 被移除後,對應的 Git Branch 仍然保留

8. 注意 du 重複計算

如果 Worktree 放在 Repo 裡面:

project/
├── .worktrees/
└── .claude/worktrees/

那麼:

du -sh "$PROJECT_ROOT"

會把所有子 Worktree 一起算進去。

因此看到:

43G project

不代表主 Repo 本身真的有 43 GB。

建議

大量使用 Coding Agent 時:

Codex
→ Worktree Automatic Cleanup
→ 保留約 3~5 個

Claude Code
→ 定期清 .claude/worktrees

Git
→ 任務完成後 git worktree remove
→ 不要長期累積 fix / verify / agent worktree

真正容易把磁碟塞爆的通常不是 Agent Session,而是:

每個 Worktree 各自產生的 dependencies + build artifacts。

定期清理 Worktree,通常比清 Session / Log 有效得多。


相關筆記