Version control using GitButler's virtual branches for parallel multi-branch work, post-hoc organization, and multi-agent collaboration. Use when working with GitButler, virtual branches, `but` commands, stacked PRs, multi-agent workflows, or when `--gitbutler` or `--but` flags are mentioned.
/plugin marketplace add outfitter-dev/agents/plugin install gitbutler@outfitterThis skill inherits all available tools. When active, it can use any tool Claude has access to.
EXAMPLES.mdREFERENCE.mdVirtual branches → parallel development → post-hoc organization.
<when_to_use>
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# 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"
but branch new <name>but status to see file IDsbut rub <file-id> <branch-name>but commit <branch> -m "message"but rubSwiss 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) |
<parallel_development>
# 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
Multiple AI agents working concurrently in same repo:
# 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 for advanced patterns </parallel_development>
<completion> ## Completing WorkCRITICAL: GitButler CLI lacks native commands for merging to main or creating PRs. Use git for integration.
# 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 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>
Three integration methods:
1. Agents Tab (Claude Code, recommended)
2. Lifecycle Hooks
{
"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
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:
git commit on virtual branches — breaks GitButler stategit add — GitButler manages indexgit checkout on virtual branches — no checkout neededgitbutler/integration to remote — it's local-onlybut status directly — causes panic; capture output first:
status_output=$(but status)
echo "$status_output" | head -5
| 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 |
# 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 REFERENCE.md 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> - [REFERENCE.md](REFERENCE.md) — complete CLI reference and troubleshooting - [EXAMPLES.md](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>This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.