worktree
Use this plugin whenever an agent needs an isolated Git checkout, hands work to another session, or audits old linked worktrees.
| skill | for |
|---|---|
worktree:init | install the worktree CLI, activate a workspace, check it |
worktree:managing-worktrees | create, lease, finish, inspect and clean worktrees |
worktree:cleanup | command: /worktree:cleanup, or an agent acting on your request, reviews the managed trees, garbage-collects the eligible ids by exact id, and reports what it kept and why; without a request it stops after the dry-run |
worktree:upgrade | check the plugin and CLI, offer the upgrade |
More columns: swipe horizontally, or focus the table and use the arrow keys.
/plugin install worktree@b10x
Codex: codex plugin add worktree@b10x. Then /worktree:init installs the CLI — the prebuilt,
checksummed archive from the worktree release, or with cargo on request —
and runs:
worktree activate --profile <profile.toml> --workspace <workspace-root>
worktree doctor --check
The skill teaches agents to create trees outside the primary repository collection, maintain live
session leases, and publish wanted commits before finishing. Cleanup is review-bound: inspect
worktree gc --repo <primary> --dry-run, then pass only ids from that review to
worktree gc --repo <primary> --apply --id <reviewed-id>. Locked, live, offline, unmanaged, and
out-of-policy trees are retained, and so are dirty and local-only trees unless worktree archive
holds their exact current state. Work merged as rebased or cherry-picked copies is recoverable when
an advertised ref carries every unique commit's exact patch.
Agents end their work with worktree finish --discard-cache --archive <tree> (worktree 0.9.0 or
later). Since worktree 0.18.0 it deletes every ignored entry, file or directory, unless the
repository's .worktreekeep keeps it, archives everything else the tree holds that no remote ref
recovers, and finishes. .worktreekeep sits at the tree root and holds Git exclude patterns; a path
is kept when a pattern matches it or one of its ancestors, and an invalid keep file (a symbolic
link, a directory, an unreadable file) refuses as keep-file-invalid and deletes nothing. Nested
repositories, mount points and unreadable entries are always kept. Since worktree 0.19.0 a
.worktreekeep in a subdirectory adds keeps for paths at and below it, matched relative to it.
Records written into target/
or any other ignored directory are deleted unless .worktreekeep names them; worktree 0.17.1 and
older kept every ignored entry it did not recognise as cache. Each deleted entry is named by its
rule: Cargo profiles in a tagged target and its tmp/ test scratch, node_modules below a tracked
lockfile, a virtual environment beside a tracked Python manifest, a Flutter app's build/ and
.dart_tool/ (since 0.17.0), tagged tool caches, and ignored-output for everything else.
worktree discard-cache --dry-run shows the classification without deleting anything.
Since worktree 0.12.0 an archive also images each nested Git repository in the tree, such as a
test fixture in an ignored directory, as nested-<n>.tar (manifest worktree.archive/2), restored
with tar -xpf. Submodules, linked worktrees and nested repositories that share state with another
repository are still refused as archive-unsupported-entry. Plain worktree finish refuses a
dirty tree unless its archive holds exactly the current state.
worktree sweep --all-profiles (worktree 0.10.0 or later) does the same for trees nobody
finished. Run daily from a timer, it discards the ignored entries .worktreekeep does not keep of every tree idle for a
day or more without a live lease, and archives what an expired or finished tree still holds. It
never changes lifecycle, removes a tree or applies GC: a swept tree shows as eligible in
worktree gc --dry-run, and removal stays an exact-id apply. --dry-run shows what it would do.
Since worktree 0.13.0, worktree gc without --id assesses only the current repository's trees;
--scope profile assesses every repository in the profile. finish, discard-cache, archive,
gc --id and reconcile --id all accept a tree's id, its path or its unique directory name, and
finish prints finished <id> <path>, either of which gc --id takes.
Since worktree 0.14.0, worktree prune-archives --repo <primary> --dry-run lists each archive
with its bytes and verdict (--scope profile for every archive). Only a Removable archive is
deleted, with worktree prune-archives --repo <primary> --apply --id <reviewed-directory>: its
tree is gone, it holds no dirty.patch and no nested image, and HEAD and every unique commit it
records are ancestors of a ref a remote freshly advertises. Every other verdict is kept and no flag
forces a removal; deleting such an archive by hand loses the only copy of its work.
Since worktree 0.15.0, worktree archive (and finish --archive, and sweep) leaves cargo's
build layout below a recognised target out of dirty.patch and records it as build_output in a
worktree.archive/3 manifest; other files under target/ stay archived. An older archive kept as
UncommittedState only because its patch holds build output shrinks with
worktree prune-archives --strip-build-output --repo <primary> --dry-run, then --apply --id <reviewed-directory>; it rewrites the patch, verifies it over HEAD and never deletes an archive.
Since worktree 0.17.0 a Flutter app's build/ and .dart_tool/ beside a pubspec.yaml count as
build layout too. Since worktree 0.18.0 archive keeps every path .worktreekeep keeps in
dirty.patch, and the strip also removes ignored output (an untracked file both HEAD's and the
archived tree's .gitignore files ignore), never what .worktreekeep keeps.
/worktree:cleanup [--repo <primary>] [--id <id>…] starts that review by name. It is a command:
you start it, or an agent starts it when you ask, and it hands off to worktree:managing-worktrees
for every step — inspect, archive for work that must not be published, finish,
gc --dry-run --id, then gc --apply --id for the eligible ids. Your request authorizes that
apply; without one it stops after the dry-run. It never forces a removal.
worktree inspect --repo <primary> reports actual Git state, storage, ignored files, leases and
retention blockers. It defaults to one repository; use --workspace to inspect the wider profile.
Add --refresh for current remote recovery evidence. Inspection does not infer story completion
or authorize removal.
Use worktree reconcile --repo <primary> --dry-run for interrupted provisioning, adopted legacy
paths, finished external trees, and already-missing records. Apply only exact reviewed ids.
External retirement additionally requires the explicit --allow-external-retirement
acknowledgement. A missing record whose recorded commit is gone for good, including one whose
repository was deleted (repository-missing), is retired only with
--acknowledge-unrecoverable <recorded-commit>, which the command refuses while any ref still
contains that commit.
The plugin contains no cleanup script and no independent policy copy; agentplugins-check tools
checks every command it spells against the newest worktree release.