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>
TL;DR
Using but publish (preferred): but snapshot -> but publish -b <branch> -> merge PR on GitHub -> but branch rm <branch>
Direct merge: but snapshot -> git checkout main -> git pull -> git merge --no-ff refs/gitbutler/<branch> -> git push -> but branch rm <branch> -> git checkout gitbutler/workspace
Manual PR workflow: git push origin refs/gitbutler/<branch>:refs/heads/<branch> -> gh pr create -> merge PR -> cleanup
See detailed workflows below.
Pre-Integration Checklist
Run through before any integration:
| Check | Command | Expected |
|---|---|---|
| GitButler running | but --version | Version output |
| Work committed | but status | Committed changes, no unassigned files |
| Tests passing | bun test (or project equivalent) | All green |
| Base updated | but base update | Up to date with main |
| Snapshot created | but snapshot -m "Before integrating..." | Snapshot ID returned |
Integration Workflows
A. Using but publish (Preferred)
# 1. Verify branch state but status but log # 2. Create snapshot but snapshot --message "Before publishing feature-auth" # 3. Authenticate with forge (one-time) but forge auth # 4. Publish branch (pushes and creates PR) but publish -b feature-auth # 5. Review and merge PR on GitHub # 6. Update local and clean up but base update but branch rm feature-auth
Benefits:
- •Handles push and PR creation in one command
- •Correct base branch set automatically for stacks
- •Stays in GitButler workspace throughout
B. Direct Merge to Main
# 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
C. Manual Pull Request Workflow
# 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
D. Stacked Branches (Bottom-Up)
# 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
For comprehensive stacked branch management, load the gitbutler-stacks skill.
Error Recovery
Merge Conflicts
# 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)
git pull origin main # Resolve any conflicts if main diverged git push origin main
Undo Integration (Not Pushed Yet)
git reset --hard HEAD~1 git checkout gitbutler/workspace
Undo Integration (Already Pushed)
git revert -m 1 HEAD git push origin main
Post-Integration Cleanup
# 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
ALWAYS:
- •Create snapshot before integration:
but snapshot --message "..." - •Use
--no-ffflag 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
Troubleshooting
| 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
# If integration went wrong but oplog but undo # Restores pre-integration state # If stuck after git operations git checkout gitbutler/workspace
Best Practices
Keep branches small:
- •Small branches = easier merges
- •Aim for single responsibility per branch
Update base regularly:
but base update
Test before integrating:
- •Always run full test suite before merging
Meaningful merge commits:
# 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"
Related Skills
- •gitbutler-virtual-branches — Core GitButler workflows
- •gitbutler-stacks — Stacked branches
Reference Files
- •gitbutler-virtual-branches/references/reference.md — CLI reference and troubleshooting