# Git Worktree Workflow

> Manage isolated development sessions using git worktrees. Use when the user wants to work on a feature branch with isolated Cursor/IDE sessions, create a worktree for a ticket (e.g., "create worktree for PROJ-1234"), switch between features without stashing, preserve session history per feature, or manage multiple branches simultaneously. Triggers on "create worktree", "new worktree", "worktree for ticket", "isolated session", "feature branch session".

- Skill: `shmulc8/git-worktree-workflow` (Agent Skill)
- Install (CLI): `npx skillmds@latest add shmulc8/git-worktree-workflow`
- Raw SKILL.md: https://api.skillmd.com/api/skills/shmulc8/git-worktree-workflow/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: shmulc8 (https://skillmd.com/u/shmulc8)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/shmulc8/git-worktree-workflow

---


# Git Worktree Workflow

Manage multiple feature branches with isolated IDE sessions using git worktrees. Each worktree gets its own Cursor window with preserved session history.

## Why Worktrees

Instead of switching branches in one directory, worktrees let you have **multiple branches checked out simultaneously** in separate folders:

- No stashing or context switching
- Session history preserved per feature
- Return to old sessions days/weeks later
- Each window shows only that feature's changes

## Configuration

Config file: `config.json` (in this skill folder)

```json
{
  "repos": {
    "<repo-name>": {
      "main": "~/path/to/repo",
      "suffix": "RepoSuffix",
      "copy_dirs": [".cursor/rules", ".cursor/skills"]
    }
  },
  "worktrees_base": "~/path/to/worktrees",
  "username": "<your-username>",
  "default_branch": "dev"
}
```

| Field                    | Description                          |
| ------------------------ | ------------------------------------ |
| `repos.<name>.main`      | Path to main repo checkout           |
| `repos.<name>.suffix`    | Suffix for worktree folder names     |
| `repos.<name>.copy_dirs` | Directories to copy to new worktrees |
| `worktrees_base`         | Base folder for all worktrees        |
| `username`               | Git branch prefix                    |
| `default_branch`         | Base branch for new worktrees        |

## Creating a Worktree

### New branch

```bash
cd <repo-main-path>
git fetch origin
git worktree add <worktrees_base>/<TICKET>-<Suffix> -b <username>/<TICKET> origin/<default_branch>
```

### From existing branch

```bash
git worktree add <worktrees_base>/<TICKET>-<Suffix> <existing-branch>
```

### Copy Cursor config

```bash
cp -r .cursor/rules <worktrees_base>/<TICKET>-<Suffix>/.cursor/
cp -r .cursor/skills <worktrees_base>/<TICKET>-<Suffix>/.cursor/
```

### Open in Cursor

```bash
cursor <worktrees_base>/<TICKET>-<Suffix>
```

## Managing Worktrees

```bash
# List all worktrees
git worktree list

# Remove a worktree
git worktree remove <worktree-path>

# Prune stale worktree references
git worktree prune
```

## Directory Structure

```
<worktrees_base>/               # All worktrees (any repo)
├── PROJ-1234-RepoA/            # RepoA worktree
├── PROJ-5678-RepoA/            # Another RepoA worktree
└── OTHER-123-RepoB/            # RepoB worktree
```

## Naming Conventions

| Item   | Pattern               | Example              |
| ------ | --------------------- | -------------------- |
| Folder | `<TICKET>-<Suffix>`   | `PROJ-1234-RepoName` |
| Branch | `<username>/<TICKET>` | `john/PROJ-1234`     |

## Disk Space

Worktrees share `.git` objects with main repo (lightweight).

| State       | Size       |
| ----------- | ---------- |
| Source only | ~300-500MB |
| After build | ~1.5-2GB   |

### Clean build artifacts

```bash
rm -rf <worktree-path>/node_modules
rm -rf <worktree-path>/**/bin
rm -rf <worktree-path>/**/obj
```

## AI Agent Instructions

When user asks to create a worktree for a ticket:

1. Read `config.json` from this skill folder for user settings
2. **If config.json doesn't exist**, help the user create it (see "First-Time Setup" below)
3. Identify which repo based on ticket prefix or current workspace
4. Check if branch already exists: `git branch -a | grep <TICKET>`
5. **CRITICAL**: All git and copy commands MUST use `required_permissions: ["all"]` because:
   - Worktrees are created outside the workspace directory
   - Git config files need to be modified
   - The sandbox will block these operations otherwise
6. Create worktree using the appropriate command:
   - **New branch**: `git fetch origin && git worktree add <path> -b <branch> origin/<default_branch>`
   - **Existing branch**: `git worktree add <path> <existing-branch>`
7. Copy directories listed in `copy_dirs` (also requires `["all"]` permissions)
8. Output the path for user to open

### First-Time Setup (config.json missing)

If `config.json` doesn't exist in this skill folder, help the user create it:

1. **Detect current workspace info:**
   ```bash
   # Get repo name from git remote
   git remote get-url origin | sed 's/.*\/\([^\/]*\)\.git/\1/' | sed 's/.*\/\([^\/]*\)$/\1/'
   
   # Get current workspace path
   pwd
   
   # Get git username
   git config user.name | tr ' ' '-' | tr '[:upper:]' '[:lower:]'
   
   # Get default branch
   git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'
   ```

2. **Ask user to confirm/adjust these values:**
   - Worktrees base directory (suggest: `~/worktrees` or `~/Stuff/worktrees`)
   - Username for branch prefix (from git config or ask)
   - Default branch (detected or ask)

3. **Generate and save config.json:**
   ```json
   {
     "repos": {
       "<detected-repo-name>": {
         "main": "<current-workspace-path>",
         "suffix": "<RepoName-capitalized>",
         "copy_dirs": [".cursor/rules", ".cursor/skills"]
       }
     },
     "worktrees_base": "<user-chosen-path>",
     "username": "<detected-or-provided>",
     "default_branch": "<detected-or-provided>"
   }
   ```

4. **Save to skill folder** (requires `["all"]` permissions):
   ```bash
   # Skill folder location (check both global and local)
   # Global: ~/.cursor/skills/git-worktree-workflow/config.json
   # Local: .cursor/skills/git-worktree-workflow/config.json
   ```

5. **Then proceed** with the original worktree creation request

### Permission Requirements

```python
# All worktree operations need full permissions
Shell(
    command="git worktree add ...",
    required_permissions=["all"]
)

# Copying to worktree also needs full permissions
Shell(
    command="cp -r .cursor/rules <worktree-path>/.cursor/",
    required_permissions=["all"]
)
```

### Example Response

```
Worktree created for PROJ-1234

| Property | Value |
|----------|-------|
| Path | <worktrees_base>/PROJ-1234-<Suffix> |
| Branch | <username>/PROJ-1234 |

To open: cursor <full-path>
```

## Troubleshooting

**"fatal: branch already exists"**

- Branch exists, use `git worktree add <path> <existing-branch>` instead

**"fatal: '<path>' is already checked out"**

- Branch checked out elsewhere. Remove existing worktree or use different branch.

