# /grid:branch - Branch Management

---
name: grid:branch
description: Manage git branches for Grid sessions
disable-model-invocation: true
argument-hint: "[branch name | create | switch | pr | cleanup | list]"
allowed-tools:
  - Bash
  - Read
  - Write
  - Task
  - AskUserQuestion
---

Manage feature branches for Grid work sessions. Handles branch creation, switching, PR creation, and cleanup.

## USAGE

```
/grid:branch                    # Show current branch status
/grid:branch create {name}      # Create new feature branch
/grid:branch switch {name}      # Switch to existing branch
/grid:branch pr                 # Create PR for current branch
/grid:branch cleanup            # Delete merged branches
/grid:branch list               # List all grid branches
```

## SUBCOMMANDS

### status (default)

Show current git branch state:

```bash
# Get branch info
BRANCH=$(git branch --show-current)
COMMITS_AHEAD=$(git rev-list --count main..HEAD 2>/dev/null || echo "0")
COMMITS_BEHIND=$(git rev-list --count HEAD..main 2>/dev/null || echo "0")
UNCOMMITTED=$(git status --porcelain | wc -l | tr -d ' ')

# Check remote tracking
REMOTE=$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null || echo "none")
```

**Output:**

```
BRANCH STATUS
=============

Current: grid/react-todo-app
Remote:  origin/grid/react-todo-app

         main
          |
    +--- 5 commits behind
    |
    +--- 12 commits ahead ---> [grid/react-todo-app]
                                    |
                               (3 uncommitted changes)

Actions available:
  /grid:branch pr       Create pull request
  /grid:branch sync     Pull latest from main

End of Line.
```

### create

Create a new feature branch:

```
/grid:branch create {name}
```

**Process:**

```bash
# Validate name
NAME=$1
if [[ ! "$NAME" =~ ^[a-z0-9-]+$ ]]; then
  echo "ERROR: Branch name must be lowercase alphanumeric with hyphens only"
  exit 1
fi

# Add prefix if not present
if [[ ! "$NAME" =~ ^grid/ ]]; then
  NAME="grid/$NAME"
fi

# Check if exists
if git show-ref --verify --quiet "refs/heads/$NAME"; then
  echo "ERROR: Branch '$NAME' already exists"
  exit 1
fi

# Ensure we're on latest main
git fetch origin main
git checkout main
git pull origin main

# Create branch
git checkout -b "$NAME"

echo "Created and switched to: $NAME"
```

**Output:**

```
BRANCH CREATED
==============

Branch: grid/add-dark-mode
From:   main (commit abc1234)

Ready for work. Commits will be tracked.

Start building with /grid or /grid:quick.

End of Line.
```

### switch

Switch to an existing branch:

```
/grid:branch switch {name}
```

**Process:**

```bash
NAME=$1

# Add prefix if searching
if [[ ! "$NAME" =~ ^grid/ ]] && ! git show-ref --verify --quiet "refs/heads/$NAME"; then
  NAME="grid/$NAME"
fi

# Check uncommitted changes
if [[ -n $(git status --porcelain) ]]; then
  echo "WARNING: Uncommitted changes detected"
  echo "Options:"
  echo "  1. Stash changes and switch"
  echo "  2. Commit changes first"
  echo "  3. Cancel"
  # Prompt user
fi

git checkout "$NAME"
```

**Output:**

```
BRANCH SWITCHED
===============

Now on: grid/fix-login-bug
Commits: 3 ahead of main
Status:  Clean working tree

Resume work or view with /grid:status.

End of Line.
```

### pr

Create a pull request for the current branch:

```
/grid:branch pr
/grid:branch pr --title "Custom title"
/grid:branch pr --draft
```

**Pre-flight checks:**

```bash
# Must be on feature branch
BRANCH=$(git branch --show-current)
if [[ "$BRANCH" =~ ^(main|master|production)$ ]]; then
  echo "ERROR: Cannot create PR from protected branch"
  exit 1
fi

# Must have commits
COMMITS=$(git rev-list --count main..HEAD)
if [ "$COMMITS" -eq 0 ]; then
  echo "ERROR: No commits to create PR from"
  exit 1
fi

# Must be pushed
if ! git rev-parse --abbrev-ref --symbolic-full-name @{u} &>/dev/null; then
  echo "Pushing branch to origin..."
  git push -u origin "$BRANCH"
fi

# Check for existing PR
EXISTING=$(gh pr view --json number 2>/dev/null | jq -r '.number // empty')
if [ -n "$EXISTING" ]; then
  echo "PR #$EXISTING already exists for this branch"
  echo "View at: $(gh pr view --json url -q '.url')"
  exit 0
fi
```

**Generate PR content:**

```bash
# Gather commit info
COMMITS=$(git log main..HEAD --pretty=format:"- %s" | head -20)
FILES_CHANGED=$(git diff --stat main..HEAD | tail -1)

# Check for Grid metadata
CLUSTER=""
if [ -f ".grid/STATE.md" ]; then
  CLUSTER=$(grep "^## CLUSTER:" .grid/STATE.md | cut -d: -f2 | xargs)
fi

# Check for summaries
SUMMARIES=""
for f in .grid/phases/**/SUMMARY.md .grid/quick/*/SUMMARY.md; do
  if [ -f "$f" ]; then
    SUMMARIES="$SUMMARIES\n$(cat $f)"
  fi
done 2>/dev/null
```

**Create PR:**

```bash
gh pr create \
  --title "$TITLE" \
  --body "$(cat <<EOF
## Summary
$DESCRIPTION

## Changes
$COMMITS

## Stats
$FILES_CHANGED

## Grid Session
- **Cluster:** $CLUSTER
- **Commits:** $(git rev-list --count main..HEAD)

## Test Plan
- [ ] Code review
- [ ] Functionality verified
- [ ] No regressions

---
*Created via /grid:branch pr*
EOF
)" \
  --base main
```

**Output:**

```
PULL REQUEST CREATED
====================

PR #42: feat: add user authentication
URL: https://github.com/user/repo/pull/42

Branch: grid/add-auth -> main
Commits: 8
Files changed: 12

Status: Open (ready for review)

View PR: gh pr view 42
Check status: gh pr checks 42

End of Line.
```

### cleanup

Delete branches that have been merged:

```
/grid:branch cleanup
/grid:branch cleanup --dry-run
/grid:branch cleanup --force
```

**Process:**

```bash
# Get merged branches
MERGED=$(git branch --merged main | grep "grid/" | grep -v "^\*")

if [ -z "$MERGED" ]; then
  echo "No merged grid branches to clean up."
  exit 0
fi

echo "Merged branches to delete:"
echo "$MERGED"

if [ "$1" == "--dry-run" ]; then
  echo "(Dry run - no changes made)"
  exit 0
fi

# Confirm
read -p "Delete these branches? [y/N] " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
  echo "Cancelled."
  exit 0
fi

# Delete local
echo "$MERGED" | xargs git branch -d

# Delete remote
for branch in $MERGED; do
  git push origin --delete "$branch" 2>/dev/null || true
done
```

**Output:**

```
BRANCH CLEANUP
==============

Deleted local branches:
  - grid/add-auth (was abc1234)
  - grid/fix-login (was def5678)

Deleted remote branches:
  - origin/grid/add-auth
  - origin/grid/fix-login

Remaining grid branches: 2
  - grid/react-todo-app (current)
  - grid/feature-x

End of Line.
```

### list

List all Grid-managed branches:

```
/grid:branch list
/grid:branch list --all        # Include remote
/grid:branch list --stale      # Only stale (>30 days)
```

**Output:**

```
GRID BRANCHES
=============

Local:
  * grid/react-todo-app     (current, 12 commits ahead)
    grid/feature-x          (3 commits ahead)
    grid/old-experiment     (stale: 45 days)

Remote only:
    origin/grid/abandoned   (stale: 60 days)

Legend:
  * = current
  (stale) = no commits in 30+ days

Actions:
  /grid:branch switch {name}
  /grid:branch cleanup --stale

End of Line.
```

### sync

Sync current branch with main:

```
/grid:branch sync
/grid:branch sync --rebase    # Rebase instead of merge
```

**Process:**

```bash
# Fetch latest
git fetch origin main

# Check for conflicts
CONFLICTS=$(git merge-tree $(git merge-base HEAD origin/main) HEAD origin/main | grep -c "^<<<<<<<" || echo "0")

if [ "$CONFLICTS" -gt 0 ]; then
  echo "WARNING: Merge will have conflicts"
  echo "Files with conflicts: $CONFLICTS"
  read -p "Continue? [y/N] " confirm
fi

# Merge or rebase
if [ "$1" == "--rebase" ]; then
  git rebase origin/main
else
  git merge origin/main --no-edit
fi
```

**Output:**

```
BRANCH SYNCED
=============

Merged main into grid/react-todo-app

Before: 5 commits behind main
After:  Up to date with main

Merge commit: ghi7890

Ready to continue work.

End of Line.
```

## AUTONOMOUS MODE

When Grid is in AUTOPILOT mode, branch operations happen automatically:

### Session Start
1. Check if on protected branch
2. If yes, create `grid/{cluster-slug}` branch
3. If existing grid branch matches cluster, switch to it

### After Each Wave
1. Check for uncommitted changes (shouldn't be any with atomic commits)
2. Push to remote if auto_push enabled

### Session Complete
1. Push final state
2. Offer PR creation
3. Report branch status

## CONFIGURATION

Set preferences in `.grid/config.json`:

```json
{
  "git": {
    "auto_branch": true,
    "branch_prefix": "grid/",
    "auto_push": "wave",
    "auto_pr": false,
    "protected_branches": ["main", "master", "production"],
    "default_base": "main",
    "sync_strategy": "merge"
  }
}
```

## ERROR HANDLING

### No Git Repository

```
ERROR: Not a git repository

Initialize with:
  git init
  git remote add origin {url}

Then retry /grid:branch.
```

### No Remote

```
WARNING: No remote configured

Branch operations will be local only.
Add remote with:
  git remote add origin {url}
```

### Uncommitted Changes

```
WARNING: Uncommitted changes detected

Options:
  1. Stash: git stash
  2. Commit: /grid:quick "commit message"
  3. Discard: git checkout -- . (DANGER)

Choose action before switching branches.
```

### Merge Conflicts

```
CONFLICT: Merge conflicts detected

Conflicting files:
  - src/components/Chat.tsx
  - src/lib/api.ts

Options:
  1. Resolve manually and continue
  2. Abort merge: git merge --abort
  3. Accept ours: git checkout --ours {file}
  4. Accept theirs: git checkout --theirs {file}

After resolving: git add {files} && git commit
```

## INTEGRATION

### With /grid

```
/grid "build a chat app"
-> Auto-creates grid/chat-app branch
-> All commits go to this branch
-> On completion, offers PR
```

### With /grid:quick

```
/grid:quick "fix login bug"
-> Checks current branch
-> If on main, creates grid/fix-login-bug
-> Commits to feature branch
```

### With /grid:status

```
/grid:status
-> Shows branch info in status output
-> Includes commits ahead/behind
-> Shows remote tracking status
```

## RULES

1. **Never commit to protected branches** - Always create feature branch
2. **Atomic commits** - One logical change per commit
3. **Descriptive names** - Branch names describe the work
4. **Clean before switch** - Handle uncommitted changes
5. **Push after waves** - Keep remote in sync
6. **Clean up merged** - Delete branches after PR merge
7. **Sync regularly** - Keep branches up to date with main

End of Line.
