complete-branch
This skill should be used when completing branches, merging to main, creating PRs with GitButler, or when `--complete-branch` flag is mentioned.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install outfitter-dev-agents-complete-branch
Repository
Skill path: gitbutler/skills/complete-branch
This skill should be used when completing branches, merging to main, creating PRs with GitButler, or when `--complete-branch` flag is mentioned.
Open repositoryBest 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 complete-branch into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/outfitter-dev/agents before adding complete-branch to shared team environments
- Use complete-branch for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
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>
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### ../version-control/SKILL.md
```markdown
---
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>
```
### ../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>
```