First worktree
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
Section titled “The one-line version”cd /path/to/your/repogwm create feat 42 user-authenticationThis 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
Section titled “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)
Section titled “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
Section titled “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.*])
Section titled “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-bootstrapTo skip lifecycle hooks, pass --skip-hooks with a comma-separated list of phases:
gwm create feat 42 foo --skip-hooks pre_create,post_createTo 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-branchRe-run it later (e.g. after editing .gwm.toml) without recreating the worktree:
gwm bootstrap # on the CWD worktreegwm bootstrap auth # ...or on a fuzzy-matched nameWhat’s stored where
Section titled “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.
- Wire up
gcdso you cancdinto the new worktree in one keystroke - Tour the TUI: bare
gwmnow opens onto your fresh worktree