First worktree
August 4, 2026 · View on GitHub
This page walks through what gwm create does end-to-end on a fresh repo: where the worktree lands on disk, how the branch is named, and what the bootstrap pipeline runs (if any).

the one-line version
cd /path/to/your/repo
gwm create feat 42 user-authentication
This creates:
- A worktree at
~/cc-worktree/<repo>/feat-42-user-authentication - A branch named
feat/#42-user-authentication - A
branch.feat/#42-user-authentication.gwm-basegit config entry, anchoring the review-base resolution chain at the trunk you branched from
The gwm create form is gwm create <type> <issue> <description>. Supported <type> values are documented in Configuration → .gwm.toml schema: feat, fix, hotfix, docs, test, refactor, chore, perf, ci, build by default.
branch and path conventions
The defaults and their overrides are TOML-driven:
[worktree]
base = "{home}/cc-worktree/{repo}"
path_pattern = "{type}-{issue}-{desc}"
branch_pattern = "{type}/#{issue}-{desc}"
Available placeholders: {home}, {repo} (the repo name), {repo_path} (the main repo's absolute working directory), {repo_parent} (its parent directory), {type}, {issue}, {desc}. Tilde (~/…) is also expanded. {repo_path} / {repo_parent} let base be expressed relative to the repo on disk. For example, base = "{repo_parent}/worktrees" keeps worktrees in a sibling directory next to the main checkout. Override anything in your .gwm.toml to match your team's branch convention. See Configuration → .gwm.toml schema.
The {desc} slot is kebab-case normalised by gwm: "User Authentication", "user authentication", and "User_Authentication" all become user-authentication on disk and in the branch name. This keeps shell completion and fuzzy lookup deterministic.
the trust prompt (first run only)
If the repo has a .gwm.toml declaring a bootstrap surface (copies, guards, no-symlinks, or commands), the first gwm create on that repo opens a one-shot trust prompt before touching anything:
gwm: this repo's .gwm.toml has not been trusted yet.
path : /path/to/repo/.gwm.toml
origin : git@github.com:foo/bar.git
hash : 3a4f9c2bdeadbeef...
bootstrap surface:
- copy .env.testing → .env.testing
- run composer install (composer install --no-interaction)
Trust this .gwm.toml? [y/N/show]:
y records the approval in ~/.config/gwm/trust.toml and proceeds, N aborts (the worktree is not created, so no orphaned state), show re-prints the raw .gwm.toml for inspection. Subsequent runs on the same repo pass silently until .gwm.toml changes (any byte edit re-prompts).
For CI runners and other non-interactive contexts, bypass with --allow-bootstrap or GWM_ALLOW_BOOTSTRAP=1. The bypass does not record an entry, so an interactive run on the same machine later still prompts. See Configuration → TOFU trust ledger for the full threat model and ledger management commands (gwm trust list / revoke / show).
the bootstrap pipeline
If a .gwm.toml is present at the repo root, gwm create runs a bootstrap body immediately after the git worktree add. That body is a fixed sequence of file-level steps:
- Copies:
[[bootstrap.copy]]rules duplicate files from the main checkout into the new worktree (e.g..env.testing,.envrc, vendored secrets). - Guards:
[[bootstrap.guard]]rules vet each copied file against regex deny-lists. A match triggers either anabort(refuse to create the worktree) orseed-from-example(substitute a known-good fallback). The original use case was refusing to inherit a.envpointing at AWS RDS. - No-symlink check:
[[bootstrap.no_symlink]]rules verify that listed paths (typicallyvendor/,node_modules/) are not symlinks back into the main checkout, since a stray symlink would silently pollute the main repo's build output. - Fallback files:
[bootstrap.fallback.*]blocks materialise inline contents when a required source file is missing (theseed-from-examplepath).
The bootstrap report prints inline with ✓ (success), ! (warning, non-blocking), or ✗ (failure, blocks the worktree) sigils per step, the same convention as gwm doctor. A ✗ aborts and the worktree is rolled back.
lifecycle hooks ([hooks.*])
Shell commands run via the [hooks.*] lifecycle, which brackets the file-level body above. gwm create fires these phases in order:
pre_create: beforegit worktree add(the worktree does not exist yet).pre_bootstrap→ file-level body →post_bootstrap: wrapping the copies/guards/no-symlink/fallback steps.post_create: last, after the worktree and its bootstrap are in place.
(gwm remove runs the remaining two phases, pre_remove and post_remove.) Each entry is a [[hooks.<phase>]] table with name, run, an optional when: predicate (file_exists:, cmd_exists:, env_set:, …), an optional env map, and an on_fail policy, one of abort (default, blocks and rolls back), warn (report and continue), or ignore (silently continue):
[[hooks.post_create]]
name = "install deps"
run = "bun install"
when = "file_exists:package.json"
on_fail = "warn"
The legacy [[bootstrap.command]] mechanism still works (its steps are folded into post_create), but it is marked legacy; prefer [[hooks.post_create]], which gives you the full phase set and per-step on_fail control.
Skip the bootstrap body (copies/guards/no-symlink/fallback and the legacy [[bootstrap.command]] steps) with --no-bootstrap. Note this does not skip the native pre_create / post_create lifecycle hooks. Those still fire:
gwm create feat 42 foo --no-bootstrap
To skip lifecycle hooks, pass --skip-hooks with a comma-separated list of phases:
gwm create feat 42 foo --skip-hooks pre_create,post_create
To attach the new worktree to an existing local branch of the same name (instead of erroring on the stale tip), pass --reuse-branch:
gwm create feat 42 foo --reuse-branch
Re-run it later (e.g. after editing .gwm.toml) without recreating the worktree:
gwm bootstrap # on the CWD worktree
gwm bootstrap auth # ...or on a fuzzy-matched name
what's stored where
- The worktree lives at
<base>/<path_pattern>, outside the main checkout by default, so it survivesgit clean -fdxand IDE reindex storms on the main tree. - The branch is a normal local branch: visible in
git branch, ignored by no special config. branch.<name>.gwm-baserecords the trunk this branch was cut from. It's used by the review launcher to computegit diff base..headeven after the branch's upstream is gone.- If you used the auto-link convention (
<type>/#<N>-<slug>), the GitHub issue link is derived on the fly, with no extra config needed. See Integrations → GitHub issue / PR linking.
next
- Wire up
gcdso you cancdinto the new worktree in one keystroke - Tour the TUI: bare
gwmnow opens onto your fresh worktree