repo-setup · git:20260628.382fcc4 · 2026-06-28 · sha256 5b09e19ce6a449fd
repo-setup git:20260628.382fcc4A
Immutable. This exact content is served forever at /api/v1/blob/5b09e19ce6a449fd.
--- name: repo-setup description: Use at the start of /implement's repo path to land in a clean working state — fetch, fast-forward main, prune merged branches/worktrees/plan-files, then create the feature branch + worktree off fresh main. Repo-only; project-overridable for deep provisioning. --- # Repo Setup First step of `/implement`'s repo path. Takes the repo from whatever state it's in to a fresh feature branch + worktree cut off an up-to-date `main`, clearing the debris of previously-merged work on the way. Assumes a git repo — the recipe's repo-vs-vault context branch runs before this. ## Input - **branch** — the feature branch to create, as `<type>/<desc>` (`feat/`, `fix/`, `chore/`, `story/S-<id>-<desc>`). The recipe derives it from the ticket. A bare description is acceptable — default the type to `feat/`. - (implicit) the current repo and its `origin` remote. ## Steps 1. **Guard a dirty tree.** If `git status --porcelain` is non-empty, stop and surface the changes — don't fetch/prune over dirty state. (A project override may stash-and-restore instead.) 2. **Fetch.** `git fetch --prune origin` — updates remote-tracking refs and drops refs for branches deleted on the remote. 3. **Fast-forward `main`.** Bring local `main` to `origin/main`, never a merge commit: - on `main` → `git merge --ff-only origin/main` - not on `main` → `git fetch origin main:main` (fast-forward-only update of the local ref; refuses if it would diverge). 4. **Prune merged work.** Enumerate merged branches with `git branch --merged origin/main`, add the squash-merged ones (see caveat), and for each — excluding `main` and the current branch: - Remove its worktree if present: `git worktree remove .worktrees/<branch>` (`--force` only if an override opts in). - Delete its plan file: `rm -f .claude/plans/<branch>.md` (gitignored, per-branch, safe). - Delete the branch: `git branch -d <branch>` for merge-commit / fast-forward merges; `git branch -D <branch>` for squash-merged branches (`-d` refuses them — `-D` is safe because the caveat's check already confirmed the content landed). Then `git worktree prune` to clear stale administrative entries. **Squash-merge caveat.** `git branch --merged origin/main` catches merge-commit and fast-forward merges but **not squash-merges** — and `/implement` squashes by default, so a just-merged branch won't show as merged (and `git branch -d` would refuse to delete it). Detect those separately, in order of reliability: - `gh pr list --state merged --head <branch>` reports it merged — robust, but needs network + auth. - `git diff origin/main..<branch>` (two-dot — compares the tip *trees*) is empty when the branch's change already landed and `main` hasn't moved since. Network-free fallback; a `main` that has advanced since the squash defeats it. Delete the matches with `git branch -D`. Without `gh` auth and with an advanced `main`, a squash-merged branch may survive the prune — acceptable; the next clean run catches it. 5. **Create the feature branch + worktree off fresh main.** `git worktree add .worktrees/<branch> -b <branch> origin/main` — one step: branch cut from up-to-date `main`, checked out in an isolated worktree. ## Output / contract - **In:** repo state + a branch name. - **Out:** the created branch name and its worktree path (`.worktrees/<branch>`), surfaced so `plan-file` and the later primitives operate inside the worktree. - **Side effects:** local `main` fast-forwarded; previously-merged branches + their worktrees + their plan files removed; new branch + worktree created. No pushes or other network *writes*; the optional squash-merge `gh pr list` check is a network *read* and needs auth. ## Project overrides This primitive stops at "branch + worktree exist." Deep, stack-specific provisioning is project-override territory, layered *after* the generic steps: - **Port / secret / compose setup** — e.g. domainator's `setup-feature.sh` (slot-based ports, `.env` secret-gen, `compose up`). - **Worktree policy** — a repo that doesn't want worktrees overrides step 5 with a plain `git switch -c <branch> origin/main`. - **Dirty-tree handling** — stash-and-restore instead of stop. Overrides must honor the contract (same name, same "fresh branch + worktree off updated main" outcome) so the rest of `/implement` keeps working. Add `.worktrees/` to the repo's `.gitignore` if it isn't already. ## Future scope - Vault / non-repo path (deferred out of v1 — `/implement` is repo-shaped for now). - Branch-name derivation from the ticket (currently the recipe's job, passed in).