跳到正文
FunCoding

worktree

Create, reuse, and clean up git worktrees under $VIBE_HOME/worktrees. Use when the user wants to work in an isolated git worktree, create a worktree for a task, or list/remove existing worktrees.

Star
5,116
许可证
Apache-2.0
最近提交
2026年10月9日

vibe/plugins/builtins/vibe/skills/worktree/SKILL.md

在 GitHub 上查看

Worktree Management

Git worktrees live under $VIBE_HOME/worktrees/ (default ~/.vibe/worktrees/), each in a per-repository bucket named <repo_root.name>-<sha256(common_git_dir)[:12]> so worktrees from different repos never collide.

$VIBE_HOME/worktrees/
  .claims/<bucket>/<name>/          # claim records and holder markers
    record.json                     # metadata: branch, base_commit, branch_created, claimed_at
    recovery.json                   # snapshot metadata for a retained chat
    holders/                        # one empty file per live session
  <bucket>/<name>/                  # the actual git worktree checkout

Creating a worktree

  1. Compute the bucket from the repo root and common git dir.
  2. Validate the name (single portable path segment; no <>:"/\|?*, no trailing space or dot, no Windows reserved names like CON/PRN/NUL/ COM1-COM9/LPT1-LPT9, not . or ..).
  3. Reserve the directory with mkdir (atomic claim — fails if taken).
  4. For a new branch, start from the remote's default branch (fetch first, best-effort). For an existing branch, check it out into the worktree.
  5. git worktree add -b <name> <path> <start_point> (or without -b for reuse).
  6. Record the worktree's own HEAD as base_commit — this is the baseline for cleanup, not the invoking checkout's HEAD.
  7. Write record.json under .claims/<bucket>/<name>/.

When no name is given, derive one by slugifying the prompt: NFKD-normalize, lowercase, replace non-[a-z0-9]+ with -, take the first 6 words, trim to 40 chars, drop trailing stop words. Branch gets a vibe/ prefix. Append -2, -3, etc. on collision (up to 100). Fall back to a random slug if empty.

Reuse an existing worktree only after validating: no symlinks in the path, .git is a file (not a directory), same common git dir, matching branch.

Holding

A session using a worktree must register as a holder to prevent the background cleanup from removing it. Holder files are locked for the lifetime of the session; an unlocked marker left by a crashed process is stale and may be removed. A temporary holder protects a worktree while a session attaches.

Cleaning up

Before removal, inspect the worktree state:

  • Uncommitted changes or untracked files: git -c core.fsmonitor= status --porcelain --untracked-files=all
  • New commits since start: git rev-list --count <base_commit>..HEAD

The worktree is clean only if all three are absent. If dirty, confirm with the user before proceeding — removal discards uncommitted work, untracked files, and new commits.

If the branch pre-existed (not created by this session), confirm separately before deleting it. Re-check holders — if another session still holds the worktree, keep it. cd out of the worktree before removing (Windows refuses to delete a process's cwd).

Remove: git worktree remove --force <path>, then git branch -D <name> if the branch was created this session or the user confirmed. Delete the claim record and rmdir empty directories (never rmtree — a surviving holder must not be lost).

Snapshotting

Before retention removes an inactive worktree, save its state to a ref: stage all files (including untracked, excluding ignored) and commit to refs/vibe/reaped/<name>. Use a separate index file so the worktree's own index is untouched. Keep recovery.json after removing the active claim so reopening a chat can recreate the checkout automatically.

Retention

Keep the newest configured number of managed worktrees across repositories. Skip active worktrees. Snapshot each inactive excess worktree before removal; if snapshotting fails, keep it. Reservations without a base_commit are discarded only if empty and no creation process still holds their marker.

Creation, attachment, and retention transitions use a cross-process lock so a worktree cannot be removed while another process is claiming or attaching it.

Gotchas

  • Disable core.fsmonitor when reading someone else's working tree: git -c core.fsmonitor= status.
  • New branches start from the remote default branch, not the current checkout's HEAD.
  • Symlink paths are rejected — not a stable worktree path.
  • git worktree add cannot distinguish a taken path from an invalid ref (both exit 128), so mkdir reserves the path first.
  • Worktrees are implicitly trusted for the session only, not persisted.

相似的 Skill

verification-before-completion

OBobra/superpowers299k近 7 天新增 2,675 个 star

finishing-a-development-branch

OBobra/superpowers299k近 7 天新增 2,675 个 star

using-git-worktrees

OBobra/superpowers299k近 7 天新增 2,675 个 star

pr

MAmattpocock/skills290k近 7 天新增 10,235 个 star

triage

MAmattpocock/skills290k近 7 天新增 10,235 个 star

wizard

MAmattpocock/skills290k近 7 天新增 10,235 个 star