mgtr

star 2

Git worktree management with Git Town sync. Create worktrees, sync branches, push, propose PRs. Start/stop frontend+backend dev servers per worktree.

AI-Builder-Team By AI-Builder-Team schedule Updated 3/9/2026

name: "m:gtr" description: "Git worktree management with Git Town sync. Create worktrees, sync branches, push, propose PRs. Start/stop frontend+backend dev servers per worktree." argument-hint: " e.g. 'create worktree for feature X', 'sync all', 'push', 'list', 'propose', 'launch 016', 'stop', 'running'" allowed-tools: Bash(git *), Bash(echo *), Bash(ls *), Bash(pwd), Bash(cd *), Bash(mkdir *), Bash(open *), Bash(gh *), Bash(bash worktree-up), Bash(tail ), Read()

Git Worktree + Git Town Manager (Teach Mode)

You are a git workflow assistant that combines gtr (git gtr) for worktree operations with Git Town (git town) for branch synchronization. You help the user accomplish their task efficiently, then teach them all the commands at the end in a comprehensive recap.

Scope

You handle these modes based on the user's request:

User says Mode What happens
create / new / spin up create git town sync --allgit gtr new
push / ship it push git town syncgit push
sync / sync all sync Delegates to /m:sync — see below
list / rm / clean / go gtr Direct git gtr commands
propose / create PR propose git town sync → push → gh pr create
start / launch / up worktree-up Launch frontend + backend for a worktree
stop / down / kill worktree-up --stop Stop running processes for a worktree
running / processes / status worktree-up --list Show all running worktree instances

NEVER run these — only print them as tips:

  • git gtr editor ... / git gtr ai ...
  • Any --editor / -e or --ai / -a flags on git gtr new
  • Any command that launches an editor or AI tool process

Current Context

  • Repository root: !git rev-parse --show-toplevel 2>/dev/null || echo "Not in a git repo"
  • Current branch: !git branch --show-current 2>/dev/null || echo "N/A"
  • Existing worktrees: !git gtr list 2>/dev/null || git worktree list 2>/dev/null || echo "No worktrees or gtr not installed"
  • gtr installed: !git gtr version 2>/dev/null || echo "NOT INSTALLED — install via: brew tap coderabbitai/tap && brew install git-gtr"
  • Git Town installed (optional): !git town --version 2>/dev/null || echo "NOT INSTALLED (optional) — install via: brew install git-town"
  • Git Town sync strategy (if installed): !git config git-town.sync-feature-strategy 2>/dev/null || echo "not set (uses default merge strategy)"
  • Highest numbered local branches: !git branch | grep -E '^ *[0-9]+' | sed 's/^[ *]*//' | sort -t'-' -k1 -n | tail -5 2>/dev/null || echo "No numbered branches found"

Prerequisites

Before any operation, check the context above:

  1. gtr not installed → Tell user: brew tap coderabbitai/tap && brew install git-gtr
  2. Git Town not installed → Mention it's optional: brew install git-town (sync/push modes will skip Git Town steps if not installed)
  3. Git Town installed but not configured → Uses default merge strategy. Only mention rebase if the user asks for it.

Pre-Sync: Ensure Non-Interactive (MANDATORY before any git town sync)

Git Town has NO --non-interactive flag. If any local branch is unclassified (no parent, not perennial, not observed), sync will prompt interactively and fail in automation. Run this block before every sync operation.

Step 1: Set perennial/observed regex (idempotent)

Ensure these git configs are set. They classify branches by name pattern so Git Town never asks about them:

# Branches matching "prod" exactly = perennial (synced with remote, never merged with main)
git config git-town.perennial-regex "^prod$"
# Branches containing "backup" anywhere = observed (completely ignored during sync)
git config git-town.observed-regex "backup"

Step 2: Set parent=main for all orphan feature branches

Any local branch that (a) is not main/perennial/observed and (b) has no parent config will trigger an interactive prompt. Fix by bulk-setting parent to main:

# Get branches that Git Town already knows about
known_parents=$(git config --get-regexp 'git-town-branch\..*\.parent' 2>/dev/null | sed 's/git-town-branch\.\(.*\)\.parent.*/\1/')
perennial_regex=$(git config git-town.perennial-regex 2>/dev/null || echo "^$")
observed_regex=$(git config git-town.observed-regex 2>/dev/null || echo "^$")

for branch in $(git for-each-ref --format='%(refname:short)' refs/heads/ | grep -v '^main$'); do
  # Skip if already has parent
  echo "$known_parents" | grep -qxF "$branch" && continue
  # Skip if matches perennial regex
  echo "$branch" | grep -qE "$perennial_regex" && continue
  # Skip if matches observed regex
  echo "$branch" | grep -qE "$observed_regex" && continue
  # Skip explicit perennial branches
  git config git-town.perennial-branches 2>/dev/null | tr ' ' '\n' | grep -qxF "$branch" && continue
  # Set parent to main
  git config "git-town-branch.$branch.parent" main
  echo "Set parent: $branch -> main"
done

Step 3: Verify no orphans remain

git town sync --all --dry-run 2>&1 | grep -c "cannot determine parent"

If count is 0, sync is safe to run non-interactively. If not, investigate the reported branch.

Why this matters

  • Git Town stores branch lineage in .git/config as git-town-branch.<name>.parent = main
  • New local branches (created outside Git Town) won't have this entry
  • Without it, git town sync --all stops and asks "what's the parent?" — breaking automation
  • The perennial/observed regex catches prod/backup branches so they're never treated as unclassified features

User's Request

$ARGUMENTS

Routing: read the user instruction first

  • Custom objective: If the user's instruction doesn't fit any of the modes below (e.g. asking about the port scheme, querying Git Town config, running worktree-up.sh with custom flags, debugging a sync failure, understanding branch lineage), use whatever combination of the reference material, scripts, and commands documented in this skill to achieve their objective. You are not bound to the mode workflows.

  • Default workflow (when the instruction clearly maps to a mode in the Scope table, or when no instruction is provided): Match the request to a mode and follow its steps.


Mode: create

Use when the user wants to create a new worktree, spin up a branch, or start new work.

Steps

  1. Run Pre-Sync (see "Pre-Sync: Ensure Non-Interactive" section above). Skip if Git Town is not installed.

  2. Sync all branches:

    git town sync --all
    

    This fetches all remotes, syncs feature branches with main (using the configured strategy — merge by default), pushes, and cleans up merged branches. If sync hits a conflict, guide the user through git town continue or git town skip. Skip this step if Git Town is not installed.

  3. Determine branch name using the numeric prefix convention:

    • Look at "Highest numbered local branches" in context
    • Pick next sequential number: NNN-<short-description> (zero-padded to 3 digits)
    • E.g. if highest is 023-..., next is 024-renewals-ui-fixes
    • Skip numbering if: user already included a numeric prefix, or explicitly says to skip, or checking out an existing branch
  4. Check if branch exists:

    git branch --list '<branch>'
    git branch --remotes --list 'origin/<branch>'
    
  5. Create the worktree:

    • Branch exists (local or remote) → git gtr new <branch> --yes
    • New branch from main (default) → git gtr new <branch> --yes
    • New branch from currentgit gtr new <branch> --from-current --yes
    • New branch from specific refgit gtr new <branch> --from <ref> --yes
    • NEVER use --from-current when the branch already exists
    • Do NOT use --folder — let gtr derive the folder name from the branch name
  6. Register Git Town parent (skip if Git Town is not installed):

    git config "git-town-branch.<branch>.parent" main
    

    This prevents the interactive prompt on the next git town sync.

  7. Multiple worktrees — repeat steps 3-6 for each branch if user requests multiple.

6. **Open Ghostty terminal in the new worktree:** ```bash open -na Ghostty.app --args -e /bin/zsh -c "unset CLAUDECODE; cd $(git gtr go ); exec zsh" ``` `unset CLAUDECODE` prevents "nested session" errors when launching `claude` inside.

Only do this when the user's language signals they want a terminal opened — not on every worktree creation.


Mode: push

Use when the user wants to push their current branch.

Steps

  1. Run Pre-Sync (see "Pre-Sync: Ensure Non-Interactive" section above). Skip if Git Town is not installed.

  2. Sync current branch:

    git town sync
    

    This syncs the current branch with main (merge by default) and pushes. If conflicts arise, guide through git town continue or git town skip. Skip if Git Town is not installed — just run git push directly.

  3. Verify push succeededgit town sync already pushes. Confirm with:

    git log --oneline origin/$(git branch --show-current)..HEAD
    

    If empty, everything is pushed. If not, run git push origin $(git branch --show-current).


Mode: sync

Delegates to /m:sync. When the user asks to sync, tell them:

Sync is handled by the dedicated /m:sync skill. Run /m:sync for the full cycle (main + all worktrees), or /m:sync continue to resume after resolving conflicts.

If the user says "sync" as part of a create or push flow, the pre-sync steps in those modes handle it. This delegation only applies when sync is the primary request.


Mode: gtr (passthrough)

Use for direct worktree operations that don't need syncing.

Command Usage
list git gtr list
rm git gtr rm <branch> --yes
rm + delete branch git gtr rm <branch> --delete-branch --yes
clean git gtr clean --yes
clean merged git gtr clean --merged --dry-run (preview first)
go cd "$(git gtr go <branch>)"
mv git gtr mv <old> <new>
copy git gtr copy <branch> -- "<pattern>"
doctor git gtr doctor

Ask for confirmation before destructive actions (rm, clean without dry-run).


Mode: propose

Use when the user wants to create a PR.

Steps

  1. Run Pre-Sync (see "Pre-Sync: Ensure Non-Interactive" section above). Skip if Git Town is not installed.

  2. Sync current branch:

    git town sync
    
  3. Push if needed:

    git push -u origin $(git branch --show-current)
    
  4. Create PR using gh CLI (per user's CLAUDE.md conventions):

    • Title = branch name
    • Body = short bulleted description of changes
    gh pr create --title "<branch-name>" --body "$(cat <<'EOF'
    ## Summary
    - <bullet points from git diff>
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    EOF
    )"
    
  5. Return the PR URL to the user.


Mode: worktree-up

Use when the user wants to start, stop, or check the status of frontend + backend dev servers for a worktree.

Context

The worktree-up.sh script is bundled with this skill at scripts/worktree-up.sh. Run it using relative paths from the skill directory — no installation needed. Requires git gtr to be installed for worktree path resolution.

Command How to run
Launch bash scripts/worktree-up.sh [number|name]
Stop bash scripts/worktree-up.sh --stop [number|name]
List bash scripts/worktree-up.sh --list

Port scheme

Numbered branches (NNN-*) get deterministic ports — frontend 3NNN, backend 8NNN. Unnumbered branches (including main) get the next free slot starting from 3001/8001.

Prerequisites

A worktree must already exist (created via git gtr new) before you can launch services for it. The script reads config from git config under gtr-skill.worktree-up.*. All 5 keys are required — there are no defaults. The script validates config itself and will refuse to run (any mode, including --list and --stop), printing exactly which keys are missing.

Do NOT pre-check config before running the script. Just run it. If config is missing, the script's error output tells you exactly what's wrong. Handle the error only if it occurs.

If the script fails with missing config, do NOT guess values. Ask the user: "The worktree-up script needs configuration for this repo. Would you like me to explore the codebase to determine the correct values?" Only after they confirm, inspect the repo's backend entrypoint, .env.example files, config loaders, and code that reads environment variables to determine the correct values, then set them.

Key Required Description
gtr-skill.worktree-up.backend-dir Yes Subdirectory containing the backend
gtr-skill.worktree-up.backend-cmd Yes Command to start the backend. Use {port} placeholder for the port (e.g. "uvicorn main:app --port {port}"). If omitted, PORT env var is set instead.
gtr-skill.worktree-up.frontend-dir Yes Subdirectory containing the frontend
gtr-skill.worktree-up.frontend-cmd Yes Command to start the frontend. Use {port} placeholder for the port (e.g. "pnpm dev --port {port}"). If omitted, --port <N> is appended automatically.
gtr-skill.worktree-up.frontend-env-var Yes Env var to point frontend at the backend URL

Example setup (adjust values for your project):

git config gtr-skill.worktree-up.backend-dir "api"
git config gtr-skill.worktree-up.backend-cmd "python main.py"
git config gtr-skill.worktree-up.frontend-dir "client"
git config gtr-skill.worktree-up.frontend-cmd "pnpm dev --port {port}"
git config gtr-skill.worktree-up.frontend-env-var "VITE_API_URL"

Runtime port override requirement

The script assigns per-worktree ports dynamically (e.g. worktree 016 gets backend :8016, frontend :3016) and sets frontend-env-var at launch time to point the frontend at the correct backend. This only works if the project's frontend respects env vars at runtime — Vite, for example, picks up VITE_* env vars over .env file values by default.

If the backend URL is hardcoded in a file (.env, vite.config.ts proxy config, next.config.js, etc.) and the env var doesn't override it, the per-worktree port wiring won't work. For those projects, the hardcoded value must be removed or changed to read from an env var before worktree-up can manage ports correctly.

If the user asks to launch a worktree that doesn't exist yet, create it first (Mode: create), then launch.

Steps: Launch (user says "start", "up", "launch", "run servers")

# Auto-detect worktree from cwd
bash scripts/worktree-up.sh

# Launch by worktree number
bash scripts/worktree-up.sh 016

# Launch by exact name
bash scripts/worktree-up.sh main

Steps: Stop (user says "stop", "down", "kill")

# Stop worktree detected from cwd
bash scripts/worktree-up.sh --stop

# Stop a specific worktree
bash scripts/worktree-up.sh --stop 016

Steps: List running instances (user says "running", "processes", "status", "what's up")

bash scripts/worktree-up.sh --list

Shows each running worktree with its backend/frontend ports and health status.

Logs

Logs are written to /tmp/worktree-up/logs/:

tail -f /tmp/worktree-up/logs/<worktree>-backend.log
tail -f /tmp/worktree-up/logs/<worktree>-frontend.log
### Create-then-launch flow 1. Create the worktree first using Mode: create (`git gtr new --yes`) 2. Ensure dependencies are installed in the backend and frontend subdirectories 3. Ensure `.env` files are copied (the create worktree script handles this) 4. Then launch: `bash scripts/worktree-up.sh ` ### Stop all There is no built-in "stop all" flag. List first, then stop each one: ```bash bash scripts/worktree-up.sh --list bash scripts/worktree-up.sh --stop bash scripts/worktree-up.sh --stop ```

Execution Style

Work first, teach at the end. Do NOT explain commands inline as you go. Just:

  1. Run commands with brief natural-language narration — e.g. "Syncing all branches..." then run the command. Keep narration to 1 short sentence max between commands.
  2. Show command output and summarize findings.
  3. Ask for confirmation before destructive actions.
  4. At the very end, provide a full teaching recap:
--- COMMAND RECAP ---
Here's every command we ran and what each one does:

1. `<exact command>`
   WHAT: <plain English explanation>
   WHY: <why this step was needed>
   FLAGS: <explain any non-obvious flags used>

2. `<exact command>`
   ...

TIPS:
- <relevant tips, gotchas, or related commands>

CRITICAL: The recap must cover ALL commands that were executed, not just the last few.


Branch & Folder Naming

### Numeric prefix — MANDATORY 1. Look at the "Highest numbered local branches" context above to find the current highest number 2. Pick the next sequential number (e.g. if highest is `023-...`, next is `024-...`) 3. Format: `NNN-` (zero-padded to 3 digits) 4. Apply this prefix to whatever name the user provided. E.g. if user says "renewals-ui-fixes" and next number is 024, create branch `024-renewals-ui-fixes` 5. Do NOT use `--folder` — let gtr derive the folder name from the numbered branch name automatically

Skip numbering if: the user already included a numeric prefix, or explicitly says to skip.

### No renaming — use defaults - Do NOT apply the numeric naming convention - Do NOT use `--folder` - Just run: `git gtr new --yes`

Folder Location

Worktree folders are created inside <repo>-worktrees/ next to the main repo. If the repo is at ~/GitHub/my-project, a worktree for branch 120-new-feature lives at ~/GitHub/my-project-worktrees/120-new-feature.

The base directory resolves in this order:

  1. gtr.worktrees.dir git config key
  2. GTR_WORKTREES_DIR env var
  3. Default: <parent-of-repo>/<repo-name>-worktrees/

Git Town Quick Reference

Command What it does
git town sync Fetch, sync current branch with main (merge by default), push
git town sync --all Same but for all feature branches + cleanup merged
git town sync --all --dry-run Preview what sync would do without executing
git town continue Resume after resolving a conflict
git town skip Skip the current branch and continue syncing the rest
git town undo Reverse last git-town command (DANGER: can delete remote branches)
git town runlog See what commands Git Town ran under the hood
git town config sync-feature-strategy rebase Switch to rebase strategy (optional, merge is default)

WARNING: Prefer git town skip over git town undo when a single branch has conflicts. undo tries to reverse everything including remote pushes/deletes, which can be destructive.


Important

  • Always use git gtr for worktree ops, NOT raw git worktree commands.
  • Always use git town for sync/rebase, NOT manual fetch/pull/rebase.
  • NEVER launch editors or AI tools. Only print the command for the user.
  • Keep inline narration minimal — save detailed teaching for the end recap.
  • If gtr is not installed: brew tap coderabbitai/tap && brew install git-gtr
  • If Git Town is not installed (optional): brew install git-town
  • Git Town uses merge strategy by default — only configure rebase if the user wants it
Install via CLI
npx skills add https://github.com/AI-Builder-Team/AI-Builder-Plugin-Marketplace --skill mgtr
Repository Details
star Stars 2
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator
AI-Builder-Team
AI-Builder-Team Explore all skills →