Back to skills
SkillHub ClubShip Full StackFull Stack

version-control

This skill should be used when working with GitButler, virtual branches, `but` commands, or when `--gitbutler` or `--but` flags are mentioned.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
25
Hot score
88
Updated
March 19, 2026
Overall rating
C2.4
Composite score
2.4
Best-practice grade
N/A

Install command

npx @skill-hub/cli install outfitter-dev-agents-version-control
gitversion-controlparallel-developmentcliworkflow

Repository

outfitter-dev/agents

Skill path: gitbutler/skills/version-control

This skill should be used when working with GitButler, virtual branches, `but` commands, or when `--gitbutler` or `--but` flags are mentioned.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: outfitter-dev.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install version-control into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/outfitter-dev/agents before adding version-control to shared team environments
  • Use version-control for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: version-control
version: 2.0.0
description: This skill should be used when working with GitButler, virtual branches, `but` commands, or when `--gitbutler` or `--but` flags are mentioned.
---

# GitButler Version Control

Virtual branches → parallel development → post-hoc organization.

<when_to_use>

- Multiple unrelated features in same workspace simultaneously
- Multi-agent concurrent development (agents in same repo)
- Exploratory coding where organization comes after writing
- Post-hoc commit reorganization needed
- Visual organization preferred (GUI + CLI)

NOT for: projects using Graphite (incompatible models), simple linear workflows (use plain git), when PR submission automation required end-to-end (use Graphite instead)

</when_to_use>

<core_concepts>

| Concept | Description |
|---------|-------------|
| Virtual branches | Multiple branches applied simultaneously to working directory |
| Integration branch | `gitbutler/workspace` tracks virtual branch state — never touch directly |
| Target branch | Base branch (e.g., `origin/main`) all work diverges from |
| File assignment | Assign file hunks to branches with `but rub` |
| Stacks | Dependent branches via `--anchor` flag |
| Oplog | Operations log for undo/restore — your safety net |

**Key difference from Git**: All branches visible at once. Organize files to branches after editing. No checkout.

</core_concepts>

<workflow>

## Quick Start

```bash
# Initialize (one time)
but init

# Create branch
but branch new feature-auth

# Make changes, check status for file IDs
but status
# ╭┄00 [Unassigned Changes]
# │   m6 A src/auth.ts

# Assign file to branch using ID
but rub m6 feature-auth

# Commit
but commit feature-auth -m "feat: add authentication"
```

## Core Loop

1. **Create**: `but branch new <name>`
2. **Edit**: Make changes in working directory
3. **Check**: `but status` to see file IDs
4. **Assign**: `but rub <file-id> <branch-name>`
5. **Commit**: `but commit <branch> -m "message"`
6. **Repeat**: Continue with other features in parallel

## The Power of `but rub`

Swiss Army knife — combines entities to perform operations:

| Source | Target | Operation |
|--------|--------|-----------|
| File ID | Branch | Assign file to branch |
| File ID | Commit | Amend commit with file |
| Commit SHA | Branch | Move commit between branches |
| Commit SHA | Commit SHA | Squash (newer into older) |

</workflow>

<parallel_development>

## Parallel Feature Development

```bash
# Create two independent features
but branch new feature-a
but branch new feature-b

# Edit files for both (same workspace!)
echo "Feature A" > feature-a.ts
echo "Feature B" > feature-b.ts

# Assign to respective branches
but rub <id-a> feature-a
but rub <id-b> feature-b

# Commit independently
but commit feature-a -m "feat: implement feature A"
but commit feature-b -m "feat: implement feature B"

# Both branches exist, zero conflicts, same directory
```

## Multi-Agent Workflows

Multiple AI agents working concurrently in same repo:

```bash
# Agent 1
but branch new agent-1-feature
# ... make changes ...
but commit agent-1-feature -m "feat: add feature X"

# Agent 2 (simultaneously, same workspace)
but branch new agent-2-bugfix
# ... make changes ...
but commit agent-2-bugfix -m "fix: resolve issue Y"
```

**See [multi-agent skill](../multi-agent/SKILL.md) for advanced patterns**

</parallel_development>

<completion>

## Completing Work

**CRITICAL**: GitButler CLI lacks native commands for merging to main or creating PRs. Use git for integration.

```bash
# 1. Snapshot for safety
but snapshot --message "Before integrating feature-auth"

# 2. Switch to main
git checkout main

# 3. Update main
git pull origin main

# 4. Merge virtual branch
git merge --no-ff refs/gitbutler/feature-auth -m "feat: add auth"

# 5. Push
git push origin main

# 6. Clean up and return
but branch rm feature-auth
git checkout gitbutler/workspace
```

**See [complete-branch skill](../complete-branch/SKILL.md) for full guided workflow**

</completion>

<commands>

## Essential Commands

| Command | Purpose |
|---------|---------|
| `but init` | Initialize GitButler in repository |
| `but status` | View changes and file IDs |
| `but log` | View commits on active branches |
| `but branch new <name>` | Create virtual branch |
| `but branch new <name> --anchor <parent>` | Create stacked branch |
| `but rub <source> <target>` | Assign/move/squash/amend |
| `but commit <branch> -m "msg"` | Commit to branch |
| `but commit <branch> -o -m "msg"` | Commit only assigned files |
| `but publish` | Publish branches to forge (GitHub) |
| `but forge auth` | Authenticate with GitHub |
| `but absorb` | Amend uncommitted changes |
| `but oplog` | Show operation history |
| `but undo` | Undo last operation |
| `but snapshot --message "msg"` | Create manual snapshot |
| `but base update` | Update workspace with latest base |
| `but .` | Open GitButler GUI for current repo |

**Global flags come first**: `but --json status` ✓ | `but status --json` ✗

</commands>

<ai_integration>

## AI Agent Integration

Three integration methods:

**1. Agents Tab** (Claude Code, recommended)
- GUI-based launcher tied to branches
- Automatic commit management per session
- Parallel agent execution with branch isolation

**2. Lifecycle Hooks**

```json
{
  "hooks": {
    "PreToolUse": [{"matcher": "Edit|MultiEdit|Write", "hooks": [{"type": "command", "command": "but claude pre-tool"}]}],
    "PostToolUse": [{"matcher": "Edit|MultiEdit|Write", "hooks": [{"type": "command", "command": "but claude post-tool"}]}],
    "Stop": [{"matcher": "", "hooks": [{"type": "command", "command": "but claude stop"}]}]
  }
}
```

**3. MCP Server**

```bash
but mcp  # Start MCP server for agent integration
```

</ai_integration>

<rules>

ALWAYS:
- Use `but` for all work within virtual branches
- Use `git` only for integrating completed work into main
- Return to `gitbutler/workspace` after git operations: `git checkout gitbutler/workspace`
- Snapshot before risky operations: `but snapshot --message "..."`
- Assign files immediately after creating: `but rub <id> <branch>`
- Check file IDs with `but status` before using `but rub`

NEVER:
- Use `git commit` on virtual branches — breaks GitButler state
- Use `git add` — GitButler manages index
- Use `git checkout` on virtual branches — no checkout needed
- Push `gitbutler/integration` to remote — it's local-only
- Mix Graphite and GitButler in same repo — incompatible models
- Pipe `but status` directly — causes panic; capture output first:

  ```bash
  status_output=$(but status)
  echo "$status_output" | head -5
  ```

</rules>

<troubleshooting>

## Quick Troubleshooting

| Symptom | Cause | Solution |
|---------|-------|----------|
| Branch not showing in `but log` | Not tracked | `but track --parent <parent>` |
| Files not committing | Not assigned | `but rub <file-id> <branch>` |
| Conflicts in workspace | All branches applied | Resolve in files or reassign hunks |
| Mixed git/but broke state | Used git commands | `but base update` or reinit |
| Broken pipe panic | Output consumed partially | Capture output to variable first |
| Filename with dash fails | Interpreted as range | Use file ID from `but status` |
| Lost work | Need recovery | Use `but oplog` and `but undo` |

## Recovery Pattern

```bash
# View recent operations
but oplog

# Undo last operation
but undo

# Or restore to specific snapshot
but restore <snapshot-id>

# If workspace corrupted
but base update
# Last resort: but init
```

**See [references/reference.md](references/reference.md#troubleshooting-guide) for comprehensive troubleshooting**

</troubleshooting>

<comparison>

## GitButler vs Graphite

| Aspect | Graphite | GitButler |
|--------|----------|-----------|
| Model | Linear stacks of physical branches | Virtual branches, optional stacking |
| Branch switching | Required (`gt up`/`gt down`) | Never needed (all applied) |
| PR submission | ✓ `gt submit --stack` | ✗ CLI only (use `gh` or GUI) |
| Multi-agent | Serial (checkout required) | Parallel (virtual branches) |
| Post-hoc organization | Difficult | `but rub` trivial |
| CLI completeness | Full automation | Partial (missing PR/push) |

**Choose GitButler for**: Exploratory work, multi-agent, post-hoc organization
**Choose Graphite for**: Production automation, PR submission, terminal-first

</comparison>

<references>

- [references/reference.md](references/reference.md) — complete CLI reference and troubleshooting
- [references/examples.md](references/examples.md) — real-world workflow patterns
- [multi-agent skill](../multi-agent/SKILL.md) — multi-agent coordination
- [stack-workflows skill](../stack-workflows/SKILL.md) — stacked branches
- [complete-branch skill](../complete-branch/SKILL.md) — merging to main
- [GitButler Docs](https://docs.gitbutler.com/) — official documentation

</references>


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### ../multi-agent/SKILL.md

```markdown
---
name: multi-agent
version: 2.0.0
description: This skill should be used when coordinating multiple agents, parallel development, agent handoffs, or when multi-agent, concurrent agents, or parallel agents are mentioned.
---

# GitButler Multi-Agent Coordination

Multiple agents → virtual branches → parallel execution → zero coordination overhead.

<when_to_use>

- Multiple agents working on different features simultaneously
- Sequential agent handoffs (Agent A → Agent B)
- Commit ownership transfer between agents
- Parallel execution with early conflict detection
- Post-hoc reorganization of multi-agent work

NOT for: single-agent workflows (use standard GitButler), projects needing PR automation (Graphite better)

</when_to_use>

<core_advantage>

**Traditional Git Problem:**
- Agents must work in separate worktrees (directory coordination)
- Constant branch switching (context loss, file churn)
- Late conflict detection (only at merge time)

**GitButler Solution:**
- Multiple branches stay applied simultaneously
- Single shared workspace, zero checkout operations
- Immediate conflict detection (shared working tree)
- Each agent manipulates their own lane

</core_advantage>

<patterns>

## Pattern 1: Parallel Feature Development

```bash
# Agent 1
but branch new agent-1-auth
echo "auth code" > auth.ts
but rub auth.ts agent-1-auth
but commit agent-1-auth -m "feat: add authentication"

# Agent 2 (simultaneously, same workspace!)
but branch new agent-2-api
echo "api code" > api.ts
but rub api.ts agent-2-api
but commit agent-2-api -m "feat: add API endpoints"

# Result: Two independent features, zero conflicts
```

## Pattern 2: Sequential Handoff

```bash
# Agent A: Initial implementation
but branch new initial-impl
# ... code ...
but commit initial-impl -m "feat: initial implementation"

# Agent B: Takes ownership and refines
but rub <agent-a-commit> refinement-branch
# ... improve code ...
but commit refinement-branch -m "refactor: optimize implementation"
```

## Pattern 3: Cross-Agent Commit Transfer

```bash
# Instant ownership transfer
but rub <commit-sha> agent-b-branch  # Agent A → Agent B
but rub <commit-sha> agent-a-branch  # Agent B → Agent A
```

</patterns>

<naming>

## Branch Naming Convention

```
<agent-name>-<task-type>-<brief-description>

Examples:
- claude-feat-user-auth
- droid-fix-api-timeout
- codex-refactor-database-layer
```

Makes ownership immediately visible in `but status` and `but log`.

</naming>

<ai_integration>

## AI Integration Methods

**1. Agents Tab (Claude Code)**
- GUI-based launcher tied to branches
- Each virtual branch = independent session
- Automatic commit management per session
- Parallel agent execution with branch isolation

**2. Lifecycle Hooks**

```json
{
  "hooks": {
    "PreToolUse": [{"matcher": "Edit|MultiEdit|Write", "hooks": [{"type": "command", "command": "but claude pre-tool"}]}],
    "PostToolUse": [{"matcher": "Edit|MultiEdit|Write", "hooks": [{"type": "command", "command": "but claude post-tool"}]}],
    "Stop": [{"matcher": "", "hooks": [{"type": "command", "command": "but claude stop"}]}]
  }
}
```

**3. MCP Server**

```bash
but mcp  # Enables programmatic agent integration
```

**Key Instruction for Agents:**
> "Never use the git commit command after a task is finished"

Let GitButler manage commits via hooks or MCP.

</ai_integration>

<coordination>

## Coordination Protocols

**Status Broadcasting:**

```bash
# File-based coordination
but status > /tmp/agent-$(whoami)-status.txt

# Or use Linear/GitHub comments
# "[AGENT-A] Completed auth module, committed to claude-auth-feature"
```

**Snapshot Cadence:**

```bash
# Before risky operations
but snapshot --message "Before merging conflicting branches"

# If it breaks
but undo
```

**Concurrent Safety:**
1. Snapshot before risky operations
2. Broadcast status regularly to other agents
3. Respect 🔒 locks — files assigned to other branches
4. Use `but --json` for programmatic state inspection

</coordination>

<rub_power>

## The `but rub` Power Tool

Single command handles four critical multi-agent operations:

| Operation | Example | Use Case |
|-----------|---------|----------|
| **Assign** | `but rub m6 claude-branch` | Organize files to branches post-hoc |
| **Move** | `but rub abc1234 other-branch` | Transfer work between agents |
| **Squash** | `but rub newer older` | Clean up history |
| **Amend** | `but rub file commit` | Fix existing commits |

</rub_power>

<comparison>

## vs Other Workflows

| Aspect | Graphite | Git Worktrees | GitButler |
|--------|----------|---------------|-----------|
| Multi-agent concurrency | Serial | N directories | Parallel ✓ |
| Post-hoc organization | Difficult | Difficult | `but rub` ✓ |
| PR Submission | `gt submit` ✓ | Manual | GUI only |
| Physical layout | 1 directory | N × repo | 1 directory ✓ |
| Context switching | `gt checkout` | `cd` | None ✓ |
| Conflict detection | Late (merge) | Late (merge) | Early ✓ |
| Disk usage | 1 × repo | N × repo | 1 × repo ✓ |

</comparison>

<rules>

ALWAYS:
- Use unique branch names per agent: `<agent>-<type>-<desc>`
- Assign files immediately after creating: `but rub <id> <branch>`
- Snapshot before coordinated operations
- Broadcast status to other agents when completing work
- Check for 🔒 locked files before modifying

NEVER:
- Use `git commit` — breaks GitButler state
- Let files sit in "Unassigned Changes" — assign immediately
- Modify files locked to other branches
- Mix git and but commands during active agent sessions

</rules>

<troubleshooting>

## Common Issues

| Symptom | Cause | Solution |
|---------|-------|----------|
| Agent commit "orphaned" | Used `git commit` | Find with `git reflog`, recover |
| Files in wrong branch | Forgot assignment | `but rub <id> <correct-branch>` |
| Conflicting edits | Overlapping files | Reassign hunks to different branches |
| Lost agent work | Branch deleted | `but undo` or restore from oplog |

## Recovery

```bash
# Find orphaned commits
git reflog

# Recover agent work
but oplog
but undo

# Extract from snapshot
git show <snapshot>:index/path/to/file.txt
```

</troubleshooting>

<limitations>

## Current Limitations

- **No PR submission CLI** — use `gh pr create` after organizing
- **Overlapping file edits** — adjacent lines can only go to one branch
- **No stack navigation CLI** — no `gt up`/`gt down` equivalent

**Recommendation:** Use for exploratory multi-agent work. For production automation requiring PR submission, consider Graphite until CLI matures.

</limitations>

<references>

- [version-control skill](../version-control/SKILL.md) — core GitButler workflows
- [stack-workflows skill](../stack-workflows/SKILL.md) — stacked branches
- [GitButler AI Docs](https://docs.gitbutler.com/features/ai-integration/) — official AI integration
- [Agents Tab Blog](https://blog.gitbutler.com/agents-tab) — Claude Code integration details

</references>

```

### ../complete-branch/SKILL.md

```markdown
---
name: complete-branch
version: 2.0.0
description: This skill should be used when completing branches, merging to main, creating PRs with GitButler, or when `--complete-branch` flag is mentioned.
---

# Complete GitButler Virtual Branch

Virtual branch ready → snapshot → merge to main → cleanup → return.

<when_to_use>

- Virtual branch work is complete and ready to ship
- Tests pass and code is reviewed (if required)
- Ready to merge changes into main branch
- Need to clean up completed branches

NOT for: ongoing work, branches needing more development, stacks (complete bottom-to-top)

</when_to_use>

<prerequisites>

**Before completing any branch:**
- [ ] GitButler initialized (`but --version` succeeds)
- [ ] Virtual branch exists with committed changes
- [ ] Main branch tracked as base
- [ ] No uncommitted changes (or changes assigned to branches)
- [ ] Tests passing

</prerequisites>

<quick_start>

## Quick Start (7 Steps)

```bash
# 1. Verify branch state
but status
but log

# 2. Create safety snapshot
but snapshot --message "Before integrating feature-auth"

# 3. Switch to main
git checkout main

# 4. Update main from remote
git pull origin main

# 5. Merge virtual branch
git merge --no-ff refs/gitbutler/feature-auth -m "feat: add user authentication"

# 6. Push to remote
git push origin main

# 7. Clean up and return
but branch rm feature-auth
git checkout gitbutler/workspace
```

</quick_start>

<pre_flight>

## Pre-Integration Checklist

```bash
# All work committed?
but status  # Your branch should show committed changes

# Tests passing?
bun test  # or npm test, cargo test, etc.

# Branch up to date with main?
but base update

# No uncommitted changes?
but status  # Should show no unassigned files
git status  # Should be clean or show only .gitbutler/ changes

# Safety snapshot created?
but snapshot --message "Before integrating feature-auth"
```

</pre_flight>

<workflows>

## Integration Workflows

### A. Direct Merge to Main

```bash
# 1. Verify branch state
but status
but log

# 2. Create snapshot
but snapshot --message "Before integrating feature-auth"

# 3. Switch to main
git checkout main

# 4. Update main
git pull origin main

# 5. Merge with --no-ff (preserves history)
git merge --no-ff refs/gitbutler/feature-auth -m "feat: add user authentication"

# 6. Push
git push origin main

# 7. Clean up
but branch rm feature-auth
git checkout gitbutler/workspace
```

### B. Pull Request Workflow

```bash
# 1. Push branch to remote
git push origin refs/gitbutler/feature-auth:refs/heads/feature-auth

# 2. Create PR
gh pr create --base main --head feature-auth \
  --title "feat: add user authentication" \
  --body "Description..."

# 3. Wait for review and approval

# 4. Merge PR (via GitHub UI or CLI)
gh pr merge feature-auth --squash

# 5. Update main and clean up
git checkout main
git pull origin main
but branch rm feature-auth
git checkout gitbutler/workspace
```

### C. Stacked Branches (Bottom-Up)

```bash
# Must merge in order: base → dependent → final

# 1. Merge base branch first
git checkout main && git pull
git merge --no-ff refs/gitbutler/feature-base -m "feat: base feature"
git push origin main
but branch rm feature-base
git checkout gitbutler/workspace

# 2. Update remaining branches
but base update

# 3. Merge next level
git checkout main && git pull
git merge --no-ff refs/gitbutler/feature-api -m "feat: API feature"
git push origin main
but branch rm feature-api
git checkout gitbutler/workspace

# 4. Repeat for remaining stack levels
```

</workflows>

<recovery>

## Error Recovery

### Merge Conflicts

```bash
# View conflicted files
git status

# Resolve conflicts manually

# Stage resolved files
git add src/auth.ts

# Complete merge
git commit

# Verify and push
git push origin main

# Clean up
but branch rm feature-auth
git checkout gitbutler/workspace
```

### Push Rejected (Main Moved Ahead)

```bash
git pull origin main
# Resolve any conflicts if main diverged
git push origin main
```

### Undo Integration (Not Pushed Yet)

```bash
git reset --hard HEAD~1
git checkout gitbutler/workspace
```

### Undo Integration (Already Pushed)

```bash
git revert -m 1 HEAD
git push origin main
```

</recovery>

<cleanup>

## Post-Integration Cleanup

```bash
# Delete integrated virtual branch
but branch rm feature-auth

# Clean up remote branch (if created for PR)
git push origin --delete feature-auth

# Verify workspace is clean
but status  # Should show remaining active branches only
but log     # Branch should be gone
```

</cleanup>

<rules>

ALWAYS:
- Create snapshot before integration: `but snapshot --message "..."`
- Use `--no-ff` flag to preserve branch history
- Return to workspace after git operations: `git checkout gitbutler/workspace`
- Run tests before integrating
- Complete stacked branches bottom-to-top

NEVER:
- Merge without snapshot backup
- Skip updating main first (`git pull`)
- Forget to return to `gitbutler/workspace`
- Merge middle of stack before base
- Force push to main without explicit confirmation

</rules>

<troubleshooting>

## Common Issues

| Symptom | Cause | Solution |
|---------|-------|----------|
| Merge conflicts | Diverged from main | Resolve conflicts, stage, commit |
| Push rejected | Main moved ahead | `git pull`, resolve, push |
| Branch not found | Wrong ref path | Use `refs/gitbutler/<name>` |
| Can't return to workspace | Integration branch issue | `git checkout gitbutler/workspace` |

## Emergency Recovery

```bash
# If integration went wrong
but oplog
but undo  # Restores pre-integration state

# If stuck after git operations
git checkout gitbutler/workspace
```

</troubleshooting>

<best_practices>

## Best Practices

**Keep branches small:**
- Small branches = easier merges
- Aim for single responsibility per branch

**Update base regularly:**

```bash
but base update
```

**Test before integrating:**
- Always run full test suite before merging

**Meaningful merge commits:**

```bash
# Good: Describes what and why
git merge --no-ff feature-auth -m "feat: add JWT-based user authentication"

# Bad: Generic message
git merge --no-ff feature-auth -m "Merge branch"
```

</best_practices>

<references>

- [version-control skill](../version-control/SKILL.md) — core GitButler workflows
- [stack-workflows skill](../stack-workflows/SKILL.md) — stacked branches
- [REFERENCE.md](../version-control/REFERENCE.md) — CLI reference and troubleshooting

</references>

```

### references/reference.md

```markdown
# GitButler Reference

Complete CLI reference, JSON schemas, troubleshooting, and recovery patterns.

---

## Command Reference

### Global Options

```bash
but [OPTIONS] <COMMAND>

Global Options (must come BEFORE subcommand):
  -C, --current-dir <PATH>   Run from specified directory
  -j, --json                 JSON output format
  -h, --help                 Show help
```

**Critical**: Global flags come first:

```bash
✓ but --json status
✗ but status --json  # Error: unexpected argument
```

### Inspection Commands

| Command | Description |
|---------|-------------|
| `but status` | View uncommitted changes and file assignments |
| `but status -f, --files` | Show modified files in each commit |
| `but status -r` | Display code review status |
| `but log` | View commits on active branches |
| `but oplog` | View operations history (snapshots) |
| `but .` or `but /path` | Open GitButler GUI for repository |

**Status Output Example:**

```
╭┄00 [Unassigned Changes]
│   m6 A test-file.md
│   p9 M existing-file.ts
├╯

╭┄g4 [feature-branch]
│   🔒 i3 M locked-file.ts
●   abc1234 feat: initial commit
├╯

● 0c60c71 (common base) [origin/main]
```

**File Status Codes:**
- `A` — Added
- `M` — Modified
- `D` — Deleted
- `🔒` — Locked (belongs to this branch's commits)

**IDs:**
- `00`, `g4` — Branch IDs
- `m6`, `p9`, `i3` — File/hunk IDs (use with `but rub`)

### Branch Management

| Command | Description |
|---------|-------------|
| `but branch new <name>` | Create virtual branch (based on trunk) |
| `but branch new <name> --anchor <parent>` | Create stacked branch |
| `but branch new <name> -a <parent>` | Short form for stacked branch |
| `but branch delete <name>` | Soft delete (requires confirmation) |
| `but branch delete <name> --force` | Force delete |
| `but branch list` | List all branches |
| `but branch list --local` | Only local branches |
| `but branch rm <name>` | Remove virtual branch |

### Committing

| Command | Description |
|---------|-------------|
| `but commit -m "message"` | Commit to inferred branch |
| `but commit <branch> -m "message"` | Commit to specific branch |
| `but commit <branch> -o -m "msg"` | Only commit assigned files (`-o` flag) |
| `but commit` | Opens `$EDITOR` for message |

**Note:** Unlike git, GitButler commits all changes by default. Use `-o/--only` to commit only assigned files.

### File and Commit Manipulation

#### `but rub` (Swiss Army Knife)

```bash
but rub <source> <target>
```

| Source | Target | Operation | Description |
|--------|--------|-----------|-------------|
| File ID | Branch ID | **Assign** | Move file to branch |
| File ID | Commit SHA | **Amend** | Add file changes to commit |
| Commit SHA | Branch ID | **Move** | Relocate commit to branch |
| Commit SHA | Commit SHA | **Squash** | Combine newer into older |

#### Other Editing Commands

| Command | Description |
|---------|-------------|
| `but new <target>` | Insert blank commit (before commit ID or at top of branch) |
| `but describe` | Edit commit message or rename branch |
| `but absorb` | Amend uncommitted changes (v0.17.6+) |
| `but mark "pattern" <branch>` | Auto-assign files matching pattern |
| `but unmark` | Remove mark rules |

### Forge Integration (GitHub)

| Command | Description |
|---------|-------------|
| `but forge auth` | Authenticate with GitHub (OAuth flow) |
| `but forge list-users` | List authenticated accounts |
| `but forge forget <username>` | Remove authenticated account |
| `but push` | Push changes to remote |
| `but publish` | Publish review requests for branches |
| `but publish -b <branch>` | Publish specific branch |
| `but publish -f, --with-force` | Allow force push (default: true) |
| `but publish -r, --run-hooks` | Execute pre-push hooks (default: true) |

### Base Branch Operations

| Command | Description |
|---------|-------------|
| `but base check` | Fetch remotes and check mergeability |
| `but base update` | Update workspace with latest from base |

### Operations History (Undo/Restore)

| Command | Description |
|---------|-------------|
| `but oplog` | View operation history |
| `but undo` | Undo last operation |
| `but restore <snapshot-id>` | Restore to specific snapshot |
| `but snapshot --message "msg"` | Create manual snapshot |

### AI Integration Commands

**Claude Code Hooks:**

| Command | Purpose |
|---------|---------|
| `but claude pre-tool` | Run before code generation/editing |
| `but claude post-tool` | Run after editing completes |
| `but claude stop` | Run when agent session ends |

**Cursor Hooks:**

| Command | Purpose |
|---------|---------|
| `but cursor after-edit` | Triggered when Cursor edits files |
| `but cursor stop` | Triggered when task completes |

**MCP Server:**

| Command | Purpose |
|---------|---------|
| `but mcp` | Start MCP server for agent integration |

---

## JSON Output Schemas

### `but --json status`

Key fields:
- `path` — Filename as ASCII array (requires decoding)
- `assignments` — Hunk-level file assignments
- `stackId` — Which stack this belongs to (null if unassigned)

**Limitations:**
- File IDs (`m6`, `g4`) not exposed in JSON
- Paths are ASCII arrays, not strings
- Parse text output for IDs

### `but --json log`

Key fields:
- `tip` — Current HEAD of branch (commit SHA)
- `baseCommit` — Where branch diverges from parent
- `pushStatus` — `completelyUnpushed` | `unpushedCommits` | `fullyPushed`
- `state.type` — `LocalOnly` | `LocalAndRemote`
- `parentIds` — Parent commits (useful for finding stacks)

**Useful jq patterns:**

```bash
# Get all branch names
but --json log | jq '.[0].branchDetails[] | .name'

# Check push status
but --json log | jq '.[0].branchDetails[] | {name, pushStatus}'

# Find unpushed branches
but --json log | jq '.[0].branchDetails[] | select(.pushStatus != "fullyPushed") | .name'
```

---

## GitButler vs Graphite

| Aspect | Graphite | GitButler |
|--------|----------|-----------|
| **Model** | Linear stacks of physical branches | Virtual branches with optional stacking |
| **Workflow** | Plan → Branch → Code → Commit → Stack | Code → Organize → Assign → Commit |
| **Branch Switching** | Required (`gt up`/`gt down`) | Never needed (all applied) |
| **Branch Creation** | `gt create -am "msg"` | `but branch new name [--anchor parent]` |
| **Committing** | `gt modify -cam "msg"` | `but commit -m "msg"` |
| **Stack Navigation** | ✓ `gt up`/`gt down` | ✗ No CLI equivalent |
| **PR Submission** | ✓ `gt submit --stack` | ✗ No CLI (GUI or `gh` CLI) |
| **JSON Output** | Limited | ✓ Comprehensive via `--json` |
| **Multi-Feature Work** | Switch branches | All in one workspace |
| **CLI Completeness** | ✓ Full automation | ⚠️ Partial (missing PR/push) |

**Choose Graphite when:**
- Need end-to-end CLI automation
- PR submission required in scripts
- Terminal-first workflow
- Stack navigation commands needed

**Choose GitButler when:**
- Multiple unrelated features simultaneously
- Multi-agent concurrent development
- Exploratory coding (organize after)
- Post-hoc commit reorganization
- Visual organization preferred

**Don't use both in same repo** — incompatible models.

---

## Troubleshooting Guide

### Quick Reference

| Symptom | Cause | Solution |
|---------|-------|----------|
| Broken pipe panic | Output piped directly | Capture to variable first |
| Filename with dash fails | Interpreted as range | Use file ID from `but status` |
| Branch not in `but log` | Not tracked | `but track --parent <parent>` |
| Files not committing | Not assigned | `but rub <file-id> <branch>` |
| Mixed git/but broke state | Used git commands | `but base update` or `but init` |
| Workspace stuck loading | Backend timeout | Check oplog, restore snapshot |
| "Workspace commit not found" | HEAD changed externally | `git checkout gitbutler/workspace` |

### Common Issues

#### Broken Pipe Panic

**Problem:** `but status` panics when output consumed partially.

```bash
✗ but status | head -5  # Panic!

✓ status_output=$(but status)
  echo "$status_output" | head -5
```

#### Filename Parsing Issues

**Problem:** Dashes in filenames interpreted as range syntax.

```bash
✗ but rub file-with-dashes.md branch  # Fails

✓ but rub m6 branch  # Use file ID from but status
```

#### Integration Branch Conflicts

**Problem:** Mixed `git` and `but` commands corrupted state.

**Solutions:**
1. `but base update` to resync
2. If severely broken: `but init` to reinitialize

#### Files Not Committing

**Causes:**
1. Files not assigned to branch
2. Missing `-o` flag (only commit assigned files)

```bash
# Check assignments
but status

# Assign files
but rub <file-id> <branch>

# Commit with -o flag
but commit <branch> -o -m "message"
```

#### Workspace Stuck Loading

**Symptoms:**
- Loading spinner indefinitely
- Can see trunk/remote branches but not workspace

**Recovery:**
1. Wait 60 seconds for timeout
2. Check logs: `~/Library/Logs/com.gitbutler.app/GitButler.log` (macOS)
3. Use Operations History to restore previous snapshot
4. Last resort: Remove and re-add project

#### "GitButler workspace commit not found"

**Cause:** `gitbutler/workspace` branch modified or deleted outside GitButler.

**Recovery:**

```bash
# Return to integration branch
git checkout gitbutler/integration

# If that fails, check oplog
cat .git/gitbutler/operations-log.toml
git log <head_sha>

# Remove and re-add project to GitButler
```

### Recovery Scenarios

#### Lost Work (Accidentally Deleted Branch)

```bash
# Check oplog for deletion
but oplog

# Undo deletion (if last operation)
but undo

# Or restore to snapshot before deletion
but restore <snapshot-id>
```

#### Corrupted Workspace State

```bash
# Step 1: Snapshot current state
but snapshot --message "Before recovery"

# Step 2: Update base
but base update

# Step 3: Last resort - reinitialize
but init
```

#### Recovering from Mixed Git/But Commands

**If you committed with `git commit`:**

```bash
# Work is still in working directory
# Find orphaned commit
git reflog

# Create branch from it
git branch recovered <commit-sha>

# Return to GitButler
git checkout gitbutler/integration
```

**If you checked out another branch:**

```bash
# Return to GitButler
git checkout gitbutler/integration
# GitButler will resume operation
```

#### Virtual Branches Disappeared

Virtual branches are Git refs — they're still there:

```bash
# List all virtual branch refs
git for-each-ref refs/gitbutler/

# Create regular branch from virtual branch
git branch recovered-feature refs/gitbutler/Feature-A

# Or push directly to remote
git push origin refs/gitbutler/Feature-A:refs/heads/feature-a
```

#### Extract Data from Corrupted Project

```bash
# Backup everything
cp -r .git .git-backup

# Extract all virtual branch refs
git for-each-ref refs/gitbutler/ > gitbutler-refs.txt

# Create regular branch from each
while read sha type ref; do
  name=$(basename "$ref")
  git branch "recovered-$name" "$sha"
done < gitbutler-refs.txt

# Extract latest oplog snapshot
LATEST=$(cat .git/gitbutler/operations-log.toml | grep head_sha | awk '{print $3}' | tr -d '"')
git archive $LATEST index/ | tar -x -C recovered-uncommitted/
```

### Operations Log (Oplog) Deep Dive

**Location:** `.git/gitbutler/operations-log.toml`

**Snapshot contents:**

```
<snapshot-commit>
├── virtual_branches.toml     # Branch metadata
├── virtual_branches/         # Branch content trees
├── index/                    # Working directory state
├── target_tree/              # Base branch (e.g., main)
└── conflicts/                # Merge conflict info
```

**Operation types:**
- `CreateCommit` — Made a commit
- `CreateBranch` — Created branch
- `UpdateWorkspaceBase` — Updated base branch
- `RestoreFromSnapshot` — Reverted to snapshot
- `FileChanges` — Uncommitted changes detected
- `DeleteBranch` — Deleted branch
- `SquashCommit` — Squashed commits

**Manual inspection:**

```bash
# Find oplog head
OPLOG_HEAD=$(cat .git/gitbutler/operations-log.toml | grep head_sha | awk '{print $3}' | tr -d '"')

# View snapshot history
git log $OPLOG_HEAD --oneline

# Show virtual branches config from snapshot
git show <snapshot-sha>:virtual_branches.toml

# Extract file from snapshot
git show <snapshot-sha>:index/path/to/file.txt
```

### Prevention Best Practices

**Golden Rules:**
1. **NEVER remove project to fix errors** — may delete actual source files
2. **Commit frequently** — committed work is safer than WIP
3. **Push virtual branches to remote** — backup your work
4. **Don't mix GitButler and stock Git commands** — choose one workflow

**Before risky operations:**

```bash
but snapshot --message "Before major reorganization"
```

**Before GitButler updates:**
1. Commit everything
2. Push all branches to remote
3. Verify Operations History accessible

---

## Version History

**v0.18.2** (Nov 2024) — UX improvements, bug fixes
**v0.18.1** (Nov 2024) — Codegen agent CLI-aware
**v0.18.0** (Nov 2024) — `but .` command, enhanced status output
**v0.17.6** — `but absorb` command
**v0.17.0** — Shell completion, push capability, review status display

```

### references/examples.md

```markdown
# GitButler Examples

Real-world patterns and workflows for virtual branches, multi-agent collaboration, and post-hoc organization.

---

## Basic Workflows

### First Virtual Branch

```bash
# Initialize (one time)
cd /path/to/repo
but init

# Check state
but status
# ● 0c60c71 (common base) [origin/main]

# Create branch
but branch new feature-user-auth

# Make changes
echo "export function authenticate()" > src/auth.ts
echo "test('authenticates user')" > src/auth.test.ts

# Check status for file IDs
but status
# ╭┄00 [Unassigned Changes]
# │   m6 A src/auth.ts
# │   p9 A src/auth.test.ts

# Assign and commit
but rub m6 feature-user-auth
but rub p9 feature-user-auth
but commit feature-user-auth -m "feat: add user authentication"
```

### Context Switching (No Checkout!)

```bash
# Working on feature when bug reported
but branch new feature-dashboard
echo "Dashboard code" > dashboard.ts
but rub <id> feature-dashboard

# Bug reported - switch context immediately (no checkout!)
but branch new bugfix-login-timeout
echo "Fix timeout" > login.ts
but rub <id> bugfix-login-timeout

# Both exist in same workspace
but status  # Shows both branches

# Commit bugfix first (urgent)
but commit bugfix-login-timeout -m "fix: resolve login timeout"

# Continue feature work
but commit feature-dashboard -m "feat: add dashboard"
```

---

## Reorganizing Work

### Moving Commits Between Branches

```bash
# Oops, committed to wrong branch!
but log
# Shows def5678 "feat: add new feature" on bugfix-branch

# Create correct branch
but branch new feature-new-capability

# Move the commit
but rub def5678 feature-new-capability

# Commit moved!
but log
```

### Squashing Commits

```bash
# Too many small commits
but log
# c3d4e5f, c2d3e4f, c1d2e3f on feature-branch

# Squash (newer into older)
but rub c3d4e5f c2d3e4f
```

### Post-Hoc File Assignment

```bash
# Made changes without branches
echo "Auth code" > auth.ts
echo "API code" > api.ts
echo "Docs" > README.md

but status
# Shows all files in Unassigned Changes

# Create branches and organize
but branch new feature-auth
but branch new feature-api
but branch new docs-update

# Assign to respective branches
but rub m6 feature-auth
but rub p9 feature-api
but rub i3 docs-update

# Commit each
but commit feature-auth -m "feat: add authentication"
but commit feature-api -m "feat: add API endpoints"
but commit docs-update -m "docs: update readme"
```

---

## Multi-Agent Patterns

### Parallel Feature Development

```bash
# Agent 1 (Claude)
but branch new claude-feature-auth
echo "Auth implementation" > src/auth.ts
but rub <id> claude-feature-auth
but commit claude-feature-auth -m "feat: add authentication"

# Agent 2 (Droid) - simultaneously, same workspace!
but branch new droid-feature-api
echo "API implementation" > src/api.ts
but rub <id> droid-feature-api
but commit droid-feature-api -m "feat: add API endpoints"

# Zero conflicts, zero coordination overhead
```

### Sequential Handoffs

```bash
# Agent A: Initial implementation
but branch new feature-user-management
echo "Initial user code" > user.ts
but rub <id> feature-user-management
but commit feature-user-management -m "feat: initial user management"

# Agent A hands off to Agent B
but branch new feature-user-management-tests --anchor feature-user-management

# Agent B: Adds tests
echo "Tests for user management" > user.test.ts
but rub <id> feature-user-management-tests
but commit feature-user-management-tests -m "test: add user management tests"
```

### Cross-Agent Commit Transfer

```bash
# Agent A finishes work
but branch new agent-a-feature
but commit agent-a-feature -m "feat: implementation complete"

# Agent B creates their branch
but branch new agent-b-continuation

# Transfer commit from A to B
but rub abc1234 agent-b-continuation

# Agent B continues
echo "More work" >> feature.ts
but commit agent-b-continuation -m "feat: continue implementation"
```

---

## Stack Management

### Creating a Linear Stack

```bash
# Base refactoring
but branch new refactor-database
echo "Refactor database layer" > db-refactor.ts
but rub <id> refactor-database
but commit refactor-database -m "refactor: restructure database"

# Build on refactoring
but branch new feature-new-model --anchor refactor-database
echo "New data model" > model.ts
but rub <id> feature-new-model
but commit feature-new-model -m "feat: add new data model"

# Add tests on top
but branch new test-new-model --anchor feature-new-model
echo "Model tests" > model.test.ts
but rub <id> test-new-model
but commit test-new-model -m "test: comprehensive model tests"

# Visualize stack
but log
```

### Submit Stack as PRs

```bash
git push origin refactor-database
gh pr create --title "refactor: database layer" --base main

git push origin feature-new-model
gh pr create --title "feat: new data model" --base refactor-database

git push origin test-new-model
gh pr create --title "test: model tests" --base feature-new-model
```

---

## Emergency Recovery

### Recover Deleted Branch

```bash
# Oops, deleted wrong branch
but branch delete important-feature --force

# Check oplog
but oplog

# Undo deletion
but undo

# Verify recovery
but log  # Branch recovered!
```

### Recover from Bad Reorganization

```bash
# Snapshot before risky operations
but snapshot --message "Before reorganizing commits"

# Attempt reorganization
but rub <commit1> <branch1>
but rub <commit2> <branch2>

# Result is a mess - restore to snapshot
snapshot_id=$(but oplog | grep "Before reorganizing" | awk '{print $1}')
but restore $snapshot_id

# Back to pre-reorganization state!
```

### Recover from Mixed Git/But Commands

```bash
# Made changes on virtual branch
but branch new my-feature
echo "changes" > file.ts

# Accidentally used git
git add file.ts
git commit -m "oops"  # WRONG!

# Recovery
but base update

# If still broken, reinitialize
but snapshot --message "Before recovery"
but init
```

---

## Tips and Patterns

### Branch Naming

```bash
# Agent-based naming
but branch new claude-feat-user-auth
but branch new droid-fix-api-timeout

# Task-based naming
but branch new feature-authentication
but branch new bugfix-timeout
```

### Snapshot Cadence

```bash
but snapshot --message "Before major reorganization"
but snapshot --message "Before multi-agent coordination"
but snapshot --message "Before complex stack changes"
```

### File Assignment Discipline

```bash
# Good: Assign immediately
echo "code" > file1.ts
but rub <id> my-branch  # Right away
```

### JSON Output

```bash
# Get all branch names
but --json log | jq '.[0].branchDetails[] | .name'

# Check push status
but --json log | jq '.[0].branchDetails[] | {name, pushStatus}'

# Find unpushed branches
but --json log | jq '.[0].branchDetails[] | select(.pushStatus != "fullyPushed") | .name'
```

```

### ../stack-workflows/SKILL.md

```markdown
---
name: stack-workflows
version: 2.0.0
description: This skill should be used when creating stacked branches, dependent features, reviewable PR breakdown, or when stack, stacked branches, or `--anchor` are mentioned.
---

# GitButler Stack Workflows

Dependent branches → anchor-based stacking → reviewable chunks.

<when_to_use>

- Sequential dependencies (e.g., refactor → API → frontend)
- Large features broken into reviewable chunks
- Granular code review (approve/merge early phases independently)
- Post-hoc stack organization after exploratory coding

NOT for: independent parallel features (use virtual branches), projects using Graphite stacking

</when_to_use>

<stack_vs_virtual>

## Stacked vs Virtual Branches

| Type | Use Case | Dependencies |
|------|----------|--------------|
| **Virtual** | Independent, unrelated work | None — parallel |
| **Stacked** | Sequential dependencies | Each builds on parent |

Stacked branches = virtual branches split into dependent sequence.
Default: Virtual branches are stacks of one.

</stack_vs_virtual>

<create>

## Creating Stacks

```bash
# Base branch (no anchor)
but branch new base-feature

# Stacked branch (--anchor specifies parent)
but branch new child-feature --anchor base-feature

# Third level
but branch new grandchild-feature --anchor child-feature
```

**Result:** `base-feature` ← `child-feature` ← `grandchild-feature`

**Short form:** `-a` instead of `--anchor`

```bash
but branch new child -a parent
```

</create>

<patterns>

## Stack Patterns

### Feature Dependency Stack

```bash
# Auth foundation
but branch new auth-core
but commit auth-core -m "feat: add authentication core"

# OAuth layer depends on auth core
but branch new auth-oauth --anchor auth-core
but commit auth-oauth -m "feat: add OAuth integration"

# Social login depends on OAuth
but branch new auth-social --anchor auth-oauth
but commit auth-social -m "feat: add social login"
```

### Refactoring Stack

```bash
# Extract utilities
but branch new refactor-extract-utils
but commit refactor-extract-utils -m "refactor: extract common utilities"

# Update consumers
but branch new refactor-use-utils --anchor refactor-extract-utils
but commit refactor-use-utils -m "refactor: use extracted utilities"

# Clean up
but branch new refactor-cleanup --anchor refactor-use-utils
but commit refactor-cleanup -m "refactor: remove deprecated code"
```

### Deep Stack (5 levels)

```bash
but branch new db-schema
but branch new data-access --anchor db-schema
but branch new business-logic --anchor data-access
but branch new api-endpoints --anchor business-logic
but branch new frontend-integration --anchor api-endpoints
```

</patterns>

<post_hoc>

## Post-Hoc Stack Organization

**Problem:** Created branches independently, now want to stack them.

**Solution:** Recreate with correct anchors:

```bash
# Current: three independent branches
# feature-a, feature-b, feature-c

# Stack feature-b on feature-a
but branch new feature-b-stacked --anchor feature-a
commit_sha=$(but log | grep "feature-b:" | head -1 | awk '{print $1}')
but rub $commit_sha feature-b-stacked
but branch delete feature-b --force

# Stack feature-c on feature-b-stacked
but branch new feature-c-stacked --anchor feature-b-stacked
commit_sha=$(but log | grep "feature-c:" | head -1 | awk '{print $1}')
but rub $commit_sha feature-c-stacked
but branch delete feature-c --force
```

</post_hoc>

<pr_workflow>

## PR Preparation for Stacks

**GitButler CLI lacks native PR submission.** Use GitHub CLI:

```bash
# Push branches
git push -u origin base-feature
git push -u origin dependent-feature

# Create PRs with correct base branches
gh pr create --base main --head base-feature \
  --title "feat: base feature" \
  --body "First in stack"

gh pr create --base base-feature --head dependent-feature \
  --title "feat: dependent feature" \
  --body "Depends on base-feature PR"
```

**GitHub Settings:**
- Enable automatic branch deletion after merge
- Use **Merge** strategy (recommended) — no force pushes needed
- Merge bottom-to-top (sequential order)

</pr_workflow>

<reorganize>

## Stack Reorganization

### Squashing Within Stack

```bash
newer_commit=$(but log | grep "newer" | awk '{print $1}')
older_commit=$(but log | grep "older" | awk '{print $1}')
but rub $newer_commit $older_commit
```

### Moving Commits Between Stack Levels

```bash
commit_sha=$(but log | grep "specific commit" | awk '{print $1}')
but rub $commit_sha correct-branch
```

### Splitting a Branch

```bash
# Original has multiple features
but branch new second-feature --anchor original-branch
commit_sha=$(but log | grep "second feature commit" | awk '{print $1}')
but rub $commit_sha second-feature
```

</reorganize>

<navigation>

## Stack Navigation

**Note:** Virtual branches don't need checkout — all branches active simultaneously.

```bash
# View full stack structure
but log

# Work on any branch directly (no checkout needed)
but commit base-feature -m "update base"
but commit dependent-feature -m "update dependent"

# JSON for programmatic analysis
but --json log | jq '.[] | .branchDetails[] | {name, baseCommit}'
```

</navigation>

<rules>

ALWAYS:
- Create stacks with `--anchor` from the start
- Merge stacks bottom-to-top (base first, dependents after)
- Snapshot before reorganizing: `but snapshot --message "Before stack reorganization"`
- Keep each level small (100-250 LOC) for reviewability
- Delete empty branches after reorganization

NEVER:
- Skip stack levels when merging
- Stack independent, unrelated features (use virtual branches)
- Create deep stacks (5+ levels) without good reason
- Forget anchor when creating dependent branches

</rules>

<troubleshooting>

## Common Issues

| Symptom | Cause | Solution |
|---------|-------|----------|
| Stack not showing in `but log` | Missing `--anchor` | Recreate with correct anchor |
| Commits in wrong stack level | Wrong branch targeted | `but rub <sha> correct-branch` |
| Can't merge middle of stack | Wrong order | Merge bottom-to-top only |

## Recovery

```bash
# Recreate branch with correct anchor
but branch new child-stacked --anchor parent
commit_sha=$(but log | grep "child:" | head -1 | awk '{print $1}')
but rub $commit_sha child-stacked
but branch delete child --force
```

</troubleshooting>

<best_practices>

## Best Practices

### Planning

- Start simple: 2-3 levels max initially
- Single responsibility per level
- Only stack when there's a real dependency

### Maintenance

- Run `but log` regularly to verify structure
- Commit to correct branches immediately
- Clean up empty branches

### Communication

- Clear commit messages explaining why stack level exists
- Descriptive names indicating stack relationship
- Share `but status` when coordinating

</best_practices>

<references>

- [version-control skill](../version-control/SKILL.md) — core GitButler workflows
- [complete-branch skill](../complete-branch/SKILL.md) — merging to main
- [multi-agent skill](../multi-agent/SKILL.md) — multi-agent coordination
- [GitButler Stacks Docs](https://docs.gitbutler.com/features/branch-management/stacked-branches)

</references>

```

version-control | SkillHub