Skip to content

/c-worktree

Source of truth: skills/c-worktree/SKILL.md. /c-worktree is a utility command, not a pipeline stage. For the worktree model it shares with /c-execute, read Parallelism & worktrees.

Drives the interactive git-worktree lifecycle by hand: create an isolated worktree on its own branch, optionally run its dev server, send the work home through one of two exits (a lock-guarded local merge, or a pushed branch and a pull request), and clean everything up. It needs no design, no plan, and no other /c-* command to be useful.

Use /c-worktree whenever you want isolated feature work in its own working directory: a side experiment, parallel sessions on one repo, or any branch you’d rather not develop in your main checkout. It works in any git repo. With no worktree: config at all it still runs the full generic lifecycle (plain git worktree add, a lock-guarded local merge or a push-and-PR, cleanup); a repo’s config hooks add the repo-specific parts (provisioning, a dev port, a dev server, a deploy guard).

  • /c-worktree or /c-worktree create [<branch>]: create a new worktree. The base branch is chosen by an explicit question, never assumed; a base you name is honored.
  • /c-worktree merge [<feature>]: the local-merge exit. From inside a feature worktree, merges the current branch into its recorded parent (fallback: the branch checked out in the main worktree); from the main/target worktree, <feature> merges into the current branch. When the branch’s base is the repo’s PR target, this first asks which exit you want.
  • /c-worktree pr [<feature>]: the PR-flow exit. Pushes the branch and opens a PR against its recorded parent. The worktree stays alive for review fixes; cleanup runs after the PR merges.
  • /c-worktree cleanup [<feature>]: stop the dev server, remove the worktree, delete the branch, and release the port.

The dev-server and deploy phases have no invocation of their own: the dev server starts only when the worktree.hooks.dev_server hook is configured, and the deploy guard fires only when a deploy is requested from a worktree context.

Any git repo. It refuses to nest: creating a worktree from inside another worktree is detected (by comparing git-dir with git-common-dir) and rejected. The worktree: config section is optional; every hook is null by default, and a null hook means that lifecycle phase simply does not exist. Worktrees are created under worktree.dir (default .cadence/worktrees, the same directory /c-execute’s lanes use), which is added to .gitignore if absent.

  • Create: a worktree at <worktree.dir>/<branch> on a new branch cut from the base you chose, with the base recorded as git config branch.<branch>.parent. When a port_assign hook is configured, the assigned dev port persists as git config branch.<branch>.devPort so a later session can find it without repo-specific files.
  • Local merge: the feature branch integrated into its target per the merge type you pick (squash, merge commit, or fast-forward; the default policy comes from worktree.integrate), performed under the shared merge lock.
  • PR flow: the branch pushed to origin and a PR opened against its base; integration happens on the remote, and your local base is untouched until cleanup pulls the merged result down.
  • Cleanup: the dev server stopped (killed by the recorded devPort, never an assumed port), the worktree removed, the branch deleted, the parent / devPort git-config entries unset, and (after a PR-shipped branch) the base branch synced fast-forward-only so your main checkout picks up the merged PR.
  • Base selection asks, never assumes: if you didn’t name a base, it gathers candidates and asks, with a reasoned recommendation.
  • Which exit you take is a question, not an assumption: when the branch’s base is the repo’s PR-receiving integration branch, even “merge my branch back” gets the exit question, with PR flow recommended. A branch based on an epic branch still takes the local merge without asking.
  • All local-merge interaction happens before the lock: source/target resolution, the what-will-move review, and the merge-type menu come first, so the lock is held only for the git operations.
  • The shared merge lock (worktree.merge_lock, on by default) serializes concurrent local merges, including against /c-execute’s lane landings. The PR exit never takes it: it performs no local integration, so there is nothing to serialize.
  • A lock held past worktree.lock_stale_threshold is never stolen automatically: it shows you the holder’s branch, worktree path, and age, and asks whether to steal.
  • Merge conflicts are never auto-resolved.
  • It never approves or merges its own PR. PR integration belongs to your review flow; the command pushes, opens the PR, and cleans up after it merges.
  • Cleanup on a PR-shipped branch verifies the PR actually merged before it removes anything. An open PR stops cleanup, since the worktree is where review fixes happen.
  • It never deploys. The deploy_guard hook can only refuse a deploy and explain the flow: get the work home first (a local merge, or a merged PR plus cleanup’s base sync), then deploy from the main worktree.
  • A failed provision hook never leaves a silently broken worktree: the failure is surfaced with an offer to remove the half-created worktree.
  • /c-execute uses the same worktree.dir, the same worktree.integrate policy, and the same merge lock for its autonomous lanes.
  • Configuration: the worktree section of the config reference documents dir, integrate, merge_lock, lock_stale_threshold, and the six hooks with their execution contract.
  • Concept: Parallelism & worktrees for the worktree model.
Built by Sentasity MIT licensed