📦 deps(thirdparty): update snapshots
This commit is contained in:
@@ -0,0 +1,296 @@
|
||||
---
|
||||
name: gitbutler-complete-branch
|
||||
description: This skill should be used when the user asks to "complete a branch", "merge to main", "finish my feature", "ship this branch", "integrate to main", "create a PR from GitButler", or when `--complete-branch` flag is mentioned. Guides completion of GitButler virtual branches with safety snapshots, integration workflows, and cleanup.
|
||||
metadata:
|
||||
version: "1.0.0"
|
||||
author: outfitter
|
||||
category: version-control
|
||||
related-skills:
|
||||
- gitbutler-virtual-branches
|
||||
- gitbutler-stacks
|
||||
---
|
||||
|
||||
# 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 CLI** (preferred): `but oplog snapshot` -> `but push <branch>` -> `but pr new <branch>` -> merge PR on GitHub -> `but branch delete <branch>`
|
||||
|
||||
**Direct merge**: `but oplog snapshot` -> `git checkout main` -> `git pull` -> `git merge --no-ff refs/gitbutler/<branch>` -> `git push` -> `but branch delete <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 pull` | Up to date with main |
|
||||
| Snapshot created | `but oplog snapshot -m "Before integrating..."` | Snapshot ID returned |
|
||||
|
||||
## Integration Workflows
|
||||
|
||||
### A. Using CLI (Preferred)
|
||||
|
||||
```bash
|
||||
# 1. Verify branch state
|
||||
but status
|
||||
but show feature-auth
|
||||
|
||||
# 2. Create snapshot
|
||||
but oplog snapshot --message "Before publishing feature-auth"
|
||||
|
||||
# 3. Authenticate with forge (one-time)
|
||||
but config forge auth
|
||||
|
||||
# 4. Push branch and create PR
|
||||
but push feature-auth
|
||||
but pr new feature-auth
|
||||
|
||||
# 5. Review and merge PR on GitHub
|
||||
|
||||
# 6. Update local and clean up
|
||||
but pull
|
||||
but branch delete feature-auth
|
||||
```
|
||||
|
||||
**Benefits:**
|
||||
- Full CLI workflow, no GUI needed
|
||||
- Correct base branch set automatically for stacks
|
||||
- Stays in GitButler workspace throughout
|
||||
|
||||
### B. Direct Merge to Main
|
||||
|
||||
```bash
|
||||
# 1. Verify branch state
|
||||
but status
|
||||
but show feature-auth
|
||||
|
||||
# 2. Create snapshot
|
||||
but oplog 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 delete feature-auth
|
||||
git checkout gitbutler/workspace
|
||||
```
|
||||
|
||||
### C. Manual 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 delete feature-auth
|
||||
git checkout gitbutler/workspace
|
||||
```
|
||||
|
||||
### D. 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 delete feature-base
|
||||
git checkout gitbutler/workspace
|
||||
|
||||
# 2. Update remaining branches
|
||||
but pull
|
||||
|
||||
# 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 delete 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
|
||||
|
||||
```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 delete 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
|
||||
```
|
||||
|
||||
## Post-Integration Cleanup
|
||||
|
||||
```bash
|
||||
# Delete integrated virtual branch
|
||||
but branch delete 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 status # Branch should be gone
|
||||
```
|
||||
|
||||
<rules>
|
||||
|
||||
ALWAYS:
|
||||
- Create snapshot before integration: `but oplog 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
|
||||
|
||||
| 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
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
**Keep branches small:**
|
||||
- Small branches = easier merges
|
||||
- Aim for single responsibility per branch
|
||||
|
||||
**Update base regularly:**
|
||||
|
||||
```bash
|
||||
but pull
|
||||
```
|
||||
|
||||
**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"
|
||||
```
|
||||
|
||||
<references>
|
||||
|
||||
### Related Skills
|
||||
|
||||
- [gitbutler-virtual-branches](../virtual-branches/SKILL.md) — Core GitButler workflows
|
||||
- [gitbutler-stacks](../stacks/SKILL.md) — Stacked branches
|
||||
|
||||
### Reference Files
|
||||
|
||||
- [gitbutler-virtual-branches/references/reference.md](../virtual-branches/references/reference.md) — CLI reference and troubleshooting
|
||||
|
||||
### External
|
||||
|
||||
- [GitButler GitHub Integration](https://docs.gitbutler.com/features/forge-integration/github-integration)
|
||||
|
||||
</references>
|
||||
@@ -0,0 +1,357 @@
|
||||
---
|
||||
name: gitbutler-multi-agent
|
||||
description: This skill should be used when coordinating multiple AI agents working concurrently, handling agent handoffs, transferring commits between agents, or when "multi-agent", "concurrent agents", "parallel agents", "agent collaboration", or "parallel execution" are mentioned with GitButler. Provides virtual branch patterns for parallel execution without coordination overhead.
|
||||
metadata:
|
||||
version: "1.0.0"
|
||||
author: outfitter
|
||||
category: version-control
|
||||
related-skills:
|
||||
- gitbutler-virtual-branches
|
||||
- gitbutler-stacks
|
||||
- multi-agent-vcs
|
||||
---
|
||||
|
||||
# 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
|
||||
|
||||
## Workflow 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
|
||||
```
|
||||
|
||||
### Pattern 4: Agent Code Review Cycle
|
||||
|
||||
Reviewer agent commits fixes separately, then swap/merge:
|
||||
|
||||
```bash
|
||||
# Author agent implements
|
||||
but branch new author-impl
|
||||
but commit author-impl -m "feat: implement feature"
|
||||
|
||||
# Reviewer agent creates sibling branch for fixes
|
||||
but branch new reviewer-fixes
|
||||
# ... reviewer makes fixes ...
|
||||
but commit reviewer-fixes -m "fix: address review feedback"
|
||||
|
||||
# Adopt reviewer fixes into author branch
|
||||
but rub <reviewer-commit> author-impl
|
||||
|
||||
# Clean audit trail, final branch has both
|
||||
```
|
||||
|
||||
### Pattern 5: Agent Swarm (Many Agents, One Branch)
|
||||
|
||||
Multiple agents contribute to a single feature:
|
||||
|
||||
```bash
|
||||
but branch new shared-feature
|
||||
|
||||
# Agent A assigns their work
|
||||
but rub <a-file-id> shared-feature
|
||||
|
||||
# Agent B assigns their work
|
||||
but rub <b-file-id> shared-feature
|
||||
|
||||
# Agent C assigns their work
|
||||
but rub <c-file-id> shared-feature
|
||||
|
||||
# Single commit with all contributions
|
||||
but commit shared-feature -m "feat: collaborative implementation"
|
||||
```
|
||||
|
||||
Use with Workspace Rules (`but mark`) for auto-assignment to branches.
|
||||
|
||||
### Pattern 6: Exploratory Development
|
||||
|
||||
Compare multiple approaches in parallel:
|
||||
|
||||
```bash
|
||||
# Parent branch with shared setup
|
||||
but branch new perf-parent
|
||||
but commit perf-parent -m "chore: benchmark setup"
|
||||
|
||||
# Strategy A
|
||||
but branch new perf-strategy-a --anchor perf-parent
|
||||
but commit perf-strategy-a -m "perf: try caching approach"
|
||||
|
||||
# Strategy B
|
||||
but branch new perf-strategy-b --anchor perf-parent
|
||||
but commit perf-strategy-b -m "perf: try batching approach"
|
||||
|
||||
# Run benchmarks on each, keep winner
|
||||
but rub <winning-commit> perf-parent
|
||||
```
|
||||
|
||||
### Pattern 7: Emergency Hotfix (Feature Work Continues)
|
||||
|
||||
Ship a fix without disturbing ongoing multi-agent work:
|
||||
|
||||
```bash
|
||||
# Create isolated hotfix branch
|
||||
but branch new hotfix-urgent
|
||||
but rub <file-id> hotfix-urgent
|
||||
but commit hotfix-urgent -m "fix: prod outage"
|
||||
|
||||
# Push and create PR
|
||||
but push hotfix-urgent
|
||||
but pr new hotfix-urgent
|
||||
|
||||
# Other agents continue unaffected in their lanes
|
||||
```
|
||||
|
||||
## 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`.
|
||||
|
||||
## AI Integration Methods
|
||||
|
||||
### 1. Agents Tab (GUI)
|
||||
|
||||
- Branch-agent binding in GitButler GUI
|
||||
- Each virtual branch = independent agent session
|
||||
- Automatic commit management per session
|
||||
- Parallel execution with branch isolation
|
||||
- Access: `but gui` then navigate to Agents Tab
|
||||
|
||||
### 2. Lifecycle Hooks (CLI)
|
||||
|
||||
| Platform | Commands |
|
||||
|----------|----------|
|
||||
| **Claude Code** | `but claude pre-tool`, `but claude post-tool`, `but claude stop` |
|
||||
| **Cursor** | `but cursor after-edit`, `but cursor stop` |
|
||||
|
||||
Example Claude Code hooks config (`.claude/hooks.json`):
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PostToolUse": [{"matcher": "Edit|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 programmatic access
|
||||
```
|
||||
|
||||
Exposes `gitbutler_update_branches` tool for async commit processing.
|
||||
|
||||
### 4. Workspace Rules (Auto-Assignment)
|
||||
|
||||
```bash
|
||||
but mark agent-auth-branch
|
||||
but mark agent-api-branch
|
||||
```
|
||||
|
||||
New changes auto-route to the marked branch.
|
||||
|
||||
**Key Instruction for All Agents:**
|
||||
> "Never use the git commit command after a task is finished"
|
||||
|
||||
For detailed hook configs and MCP schemas, see `references/ai-integration.md`.
|
||||
|
||||
## 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 |
|
||||
|
||||
## 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"
|
||||
```
|
||||
|
||||
**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
|
||||
|
||||
## 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 | `but push` + `but pr new` ✓ |
|
||||
| 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 ✓ |
|
||||
|
||||
## Decision Framework: When to Use What
|
||||
|
||||
### Use GitButler when:
|
||||
|
||||
- Multiple agents work in same repo simultaneously
|
||||
- Exploratory development (organize code after writing)
|
||||
- Frequent reorganization of commits between branches
|
||||
- Visual organization preferred (GUI + CLI)
|
||||
- Early conflict detection matters
|
||||
|
||||
### Use Graphite when:
|
||||
|
||||
- Fully automated CLI workflows (scripted end-to-end)
|
||||
- Terminal-first teams
|
||||
- Established stacked PR practices
|
||||
- Need `gt up`/`gt down` stack navigation
|
||||
|
||||
### Use Git Worktrees when:
|
||||
|
||||
- Complete branch isolation required
|
||||
- Different dependencies per branch
|
||||
- CI/CD needs separate checkouts
|
||||
|
||||
**Don't mix in same repo** - Choose one model per repository.
|
||||
|
||||
<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
|
||||
|
||||
| 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
|
||||
```
|
||||
|
||||
## Limitations
|
||||
|
||||
- **Overlapping file edits** — adjacent lines can only go to one branch
|
||||
- **No stack navigation CLI** — no `gt up`/`gt down` equivalent (all branches always applied)
|
||||
- **MCP server limited** — only `gitbutler_update_branches` tool currently exposed
|
||||
|
||||
<references>
|
||||
|
||||
### Reference Files
|
||||
|
||||
- **`references/ai-integration.md`** — Detailed hook configs, MCP schemas, troubleshooting
|
||||
|
||||
### Related Skills
|
||||
|
||||
- [gitbutler-virtual-branches](../virtual-branches/SKILL.md) — Core GitButler workflows
|
||||
- [gitbutler-stacks](../stacks/SKILL.md) — Stacked branches
|
||||
- **outfitter:multi-agent-vcs** — Tool-agnostic multi-agent policy (invoke with Skill tool)
|
||||
|
||||
### External
|
||||
|
||||
- [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>
|
||||
@@ -0,0 +1,273 @@
|
||||
# Multi-Agent AI Integration Reference
|
||||
|
||||
Detailed configuration and patterns for multi-agent workflows with GitButler.
|
||||
|
||||
---
|
||||
|
||||
## Hook Configuration by Platform
|
||||
|
||||
### Claude Code
|
||||
|
||||
File: `.claude/hooks.json`
|
||||
|
||||
```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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Hook | Purpose |
|
||||
|------|---------|
|
||||
| `but claude pre-tool` | Snapshot before changes |
|
||||
| `but claude post-tool` | Auto-assign changes to agent's branch |
|
||||
| `but claude stop` | Finalize commits, cleanup |
|
||||
|
||||
### Cursor
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"after-edit": "but cursor after-edit",
|
||||
"stop": "but cursor stop"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MCP Server
|
||||
|
||||
### Starting
|
||||
|
||||
```bash
|
||||
but mcp
|
||||
```
|
||||
|
||||
### Available Tool
|
||||
|
||||
**`gitbutler_update_branches`**
|
||||
|
||||
```typescript
|
||||
{
|
||||
prompt: string // Description of changes
|
||||
}
|
||||
```
|
||||
|
||||
Returns immediately; commits processed asynchronously.
|
||||
|
||||
### Current Limitations
|
||||
|
||||
- Single tool available
|
||||
- No branch creation
|
||||
- No stack operations
|
||||
- No push/PR operations
|
||||
|
||||
---
|
||||
|
||||
## Multi-Agent Coordination Strategies
|
||||
|
||||
### Strategy 1: Branch-Per-Agent
|
||||
|
||||
Each agent owns dedicated branch(es):
|
||||
|
||||
```bash
|
||||
# Agent A owns auth domain
|
||||
but branch new agent-a-auth
|
||||
but mark agent-a-auth
|
||||
|
||||
# Agent B owns api domain
|
||||
but branch new agent-b-api
|
||||
but mark agent-b-api
|
||||
|
||||
# New changes auto-route to marked branch
|
||||
```
|
||||
|
||||
**Best for:** Independent parallel development
|
||||
|
||||
### Strategy 2: Shared Branch with Turn-Taking
|
||||
|
||||
Agents share branch, coordinate via file-based status:
|
||||
|
||||
```bash
|
||||
# File-based coordination
|
||||
but status > /tmp/agent-$(whoami)-status.txt
|
||||
|
||||
# Other agents check before modifying
|
||||
```
|
||||
|
||||
**Best for:** Sequential refinement of same feature
|
||||
|
||||
### Strategy 3: Stack-Per-Agent
|
||||
|
||||
Agents own stack levels:
|
||||
|
||||
```bash
|
||||
# Agent A: Foundation layer
|
||||
but branch new foundation
|
||||
but commit foundation -m "feat: foundation"
|
||||
|
||||
# Agent B: Build on foundation
|
||||
but branch new feature --anchor foundation
|
||||
but commit feature -m "feat: feature layer"
|
||||
|
||||
# Agent C: Tests on top
|
||||
but branch new tests --anchor feature
|
||||
but commit tests -m "test: comprehensive tests"
|
||||
```
|
||||
|
||||
**Best for:** Layered architecture development
|
||||
|
||||
### Strategy 4: Review Pairs
|
||||
|
||||
Author and reviewer agents work in parallel:
|
||||
|
||||
```bash
|
||||
# Author implements
|
||||
but branch new author-impl
|
||||
|
||||
# Reviewer creates sibling for fixes
|
||||
but branch new reviewer-fixes
|
||||
|
||||
# Swap commits as needed
|
||||
but rub <commit> <other-branch>
|
||||
```
|
||||
|
||||
**Best for:** Code review cycles
|
||||
|
||||
---
|
||||
|
||||
## Status Broadcasting
|
||||
|
||||
### File-Based
|
||||
|
||||
```bash
|
||||
# Broadcast status
|
||||
but status > /tmp/agent-status-$(hostname)-$(date +%s).txt
|
||||
|
||||
# Other agents poll status files
|
||||
```
|
||||
|
||||
### Issue Tracker Comments
|
||||
|
||||
```markdown
|
||||
[AGENT-A] Completed auth module
|
||||
- Branch: agent-a-auth
|
||||
- Commits: abc1234
|
||||
- Ready for review
|
||||
```
|
||||
|
||||
### JSON for Programmatic Inspection
|
||||
|
||||
```bash
|
||||
# Machine-readable status
|
||||
but status --json | jq '.stacks'
|
||||
but show feature-branch --json | jq '.commits'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Agent Instructions Template
|
||||
|
||||
Add to agent system prompt:
|
||||
|
||||
```
|
||||
## GitButler Rules
|
||||
|
||||
1. NEVER use `git commit` - use `but commit`
|
||||
2. NEVER use `git add` - GitButler manages staging
|
||||
3. NEVER use `git checkout` - all branches always applied
|
||||
4. ALWAYS check file IDs with `but status` before `but rub`
|
||||
5. ALWAYS snapshot before risky operations: `but oplog snapshot`
|
||||
6. Return to workspace after git ops: `git checkout gitbutler/workspace`
|
||||
|
||||
## Your Branch
|
||||
- Name: {agent-branch-name}
|
||||
- Pattern: {file-pattern}
|
||||
|
||||
Assign your changes: `but rub <file-id> {agent-branch-name}`
|
||||
Commit your work: `but commit {agent-branch-name} -m "your message"`
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting Multi-Agent
|
||||
|
||||
### Agents modifying same files
|
||||
|
||||
**Symptom:** Overlapping hunks in unassigned changes
|
||||
|
||||
**Solution:**
|
||||
1. Assign non-overlapping hunks to respective branches
|
||||
2. For overlapping lines: coordinate which agent owns them
|
||||
3. Use `but mark` rules for clearer ownership
|
||||
|
||||
### Lost agent work
|
||||
|
||||
**Recovery:**
|
||||
|
||||
```bash
|
||||
# Check oplog
|
||||
but oplog
|
||||
|
||||
# Undo if recent
|
||||
but undo
|
||||
|
||||
# Or restore from snapshot
|
||||
but oplog restore <snapshot-id>
|
||||
```
|
||||
|
||||
### Agent committed with git
|
||||
|
||||
**Symptom:** Orphaned commit not in GitButler
|
||||
|
||||
**Recovery:**
|
||||
|
||||
```bash
|
||||
git reflog # Find orphaned commit
|
||||
# Create new branch from it
|
||||
git branch recovered <commit-sha>
|
||||
# Return to GitButler
|
||||
git checkout gitbutler/workspace
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [GitButler MCP Docs](https://docs.gitbutler.com/features/ai-integration/mcp-server)
|
||||
- [Claude Code Hooks Docs](https://docs.gitbutler.com/features/ai-integration/claude-code-hooks)
|
||||
- [Cursor Hooks Docs](https://docs.gitbutler.com/features/ai-integration/cursor-hooks)
|
||||
@@ -0,0 +1,246 @@
|
||||
---
|
||||
name: gitbutler-stacks
|
||||
description: This skill should be used when creating stacks, dependent branches, or when "stack", "stacked branches", "anchor", "--anchor", "but branch new -a", "create dependent branch", or "break feature into PRs" are mentioned with GitButler. Covers anchor-based stacking for dependent features and reviewable PR breakdown.
|
||||
metadata:
|
||||
version: "1.0.0"
|
||||
author: outfitter
|
||||
category: version-control
|
||||
related-skills:
|
||||
- gitbutler-virtual-branches
|
||||
- gitbutler-complete-branch
|
||||
- gitbutler-multi-agent
|
||||
---
|
||||
|
||||
# GitButler Stacks
|
||||
|
||||
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>
|
||||
|
||||
## 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.
|
||||
|
||||
## 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
|
||||
```
|
||||
|
||||
## Stack Patterns
|
||||
|
||||
Common patterns: feature dependency chains, refactoring sequences, deep stacks.
|
||||
|
||||
**Example - Feature Dependency:**
|
||||
|
||||
```bash
|
||||
but branch new auth-core
|
||||
but branch new auth-oauth --anchor auth-core
|
||||
but branch new auth-social --anchor auth-oauth
|
||||
```
|
||||
|
||||
See `references/patterns.md` for detailed patterns with commit examples.
|
||||
|
||||
## Post-Hoc Stack Organization
|
||||
|
||||
Convert independent branches into a stack by recreating with correct anchors:
|
||||
|
||||
1. Create new branch with `--anchor` pointing to intended parent
|
||||
2. Move commits with `but rub <sha> <new-branch>`
|
||||
3. Delete original branch
|
||||
|
||||
See `references/reorganization.md` for detailed workflows.
|
||||
|
||||
## Publishing Stacks
|
||||
|
||||
### Using CLI (Preferred)
|
||||
|
||||
```bash
|
||||
# Push and create PR for a branch
|
||||
but push dependent-feature
|
||||
but pr new dependent-feature
|
||||
|
||||
# Push all unpushed branches
|
||||
but push
|
||||
```
|
||||
|
||||
`but push` + `but pr new` handles:
|
||||
- Pushing branches to remote
|
||||
- Creating PRs with correct base branches
|
||||
- Updating existing PRs if already created
|
||||
|
||||
### Using GitHub CLI (Alternative)
|
||||
|
||||
```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)
|
||||
|
||||
## Conflict Handling in Stacks
|
||||
|
||||
GitButler resolves conflicts **per-commit** during rebase:
|
||||
|
||||
1. When base branch updates, dependent commits rebase automatically
|
||||
2. Conflicted commits marked but don't block other commits
|
||||
3. Resolve conflicts per affected commit
|
||||
4. Partial resolution can be saved and continued later
|
||||
|
||||
```bash
|
||||
# Update base (may trigger rebases in stack)
|
||||
but pull
|
||||
|
||||
# Check which commits have conflicts
|
||||
but status
|
||||
|
||||
# Resolve in editor, GitButler auto-detects resolution
|
||||
```
|
||||
|
||||
**Unlike git rebase:** Remaining commits continue rebasing even if some conflict.
|
||||
|
||||
## Stack Reorganization
|
||||
|
||||
Key operations for restructuring stacks:
|
||||
|
||||
| Operation | Command |
|
||||
|-----------|---------|
|
||||
| Squash commits | `but squash <branch>` or `but rub <newer> <older>` |
|
||||
| Move commit | `but rub <sha> <target-branch>` |
|
||||
| Split branch | Create anchored branch, move commits |
|
||||
|
||||
See `references/reorganization.md` for detailed examples.
|
||||
|
||||
## Stack Navigation
|
||||
|
||||
**Note:** Virtual branches don't need checkout — all branches active simultaneously.
|
||||
|
||||
```bash
|
||||
# View full stack structure
|
||||
but status
|
||||
|
||||
# Work on any branch directly (no checkout needed)
|
||||
but commit base-feature -m "update base"
|
||||
but commit dependent-feature -m "update dependent"
|
||||
|
||||
# Inspect a specific branch
|
||||
but show dependent-feature
|
||||
|
||||
# JSON for programmatic analysis
|
||||
but show dependent-feature --json | jq '.commits[] | .id'
|
||||
```
|
||||
|
||||
<rules>
|
||||
|
||||
ALWAYS:
|
||||
- Create stacks with `--anchor` from the start
|
||||
- Merge stacks bottom-to-top (base first, dependents after)
|
||||
- Snapshot before reorganizing: `but oplog 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
|
||||
|
||||
| Symptom | Cause | Solution |
|
||||
|---------|-------|----------|
|
||||
| Stack not showing in `but status` | 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
|
||||
|
||||
To fix a branch with wrong/missing anchor: create new branch with correct anchor, move commits with `but rub`, delete original.
|
||||
|
||||
See `references/reorganization.md` for complete recovery procedures.
|
||||
|
||||
## 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 status` 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
|
||||
|
||||
<references>
|
||||
|
||||
### Reference Files
|
||||
|
||||
- **`references/patterns.md`** — Detailed stack patterns (feature dependency, refactoring, deep stacks)
|
||||
- **`references/reorganization.md`** — Post-hoc organization, squashing, moving commits, splitting
|
||||
|
||||
### Related Skills
|
||||
|
||||
- [gitbutler-virtual-branches](../virtual-branches/SKILL.md) — Core GitButler workflows
|
||||
- [gitbutler-complete-branch](../complete-branch/SKILL.md) — Merging to main
|
||||
- [gitbutler-multi-agent](../multi-agent/SKILL.md) — Multi-agent coordination
|
||||
|
||||
### External
|
||||
|
||||
- [GitButler Stacks Docs](https://docs.gitbutler.com/features/branch-management/stacked-branches)
|
||||
- [Stacked Branches Blog](https://blog.gitbutler.com/stacked-branches-with-gitbutler)
|
||||
|
||||
</references>
|
||||
@@ -0,0 +1,53 @@
|
||||
# Stack Patterns
|
||||
|
||||
Detailed patterns for GitButler stacked branches.
|
||||
|
||||
## Feature Dependency Stack
|
||||
|
||||
Build features that depend on each other in sequence.
|
||||
|
||||
```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
|
||||
|
||||
Break large refactors into reviewable phases.
|
||||
|
||||
```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)
|
||||
|
||||
For complex features requiring many dependent phases.
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
**Caution:** Deep stacks increase merge complexity. Prefer 2-3 levels when possible.
|
||||
@@ -0,0 +1,70 @@
|
||||
# Stack Reorganization
|
||||
|
||||
Advanced techniques for reorganizing GitButler stacks.
|
||||
|
||||
## 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 show feature-b --json | jq -r '.commits[0].id')
|
||||
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 show feature-c --json | jq -r '.commits[0].id')
|
||||
but rub $commit_sha feature-c-stacked
|
||||
but branch delete feature-c --force
|
||||
```
|
||||
|
||||
## Squashing Within Stack
|
||||
|
||||
Combine commits within the same stack level.
|
||||
|
||||
```bash
|
||||
# Squash all commits in a branch
|
||||
but squash my-branch
|
||||
|
||||
# Or squash specific commits
|
||||
but squash <newer-commit> <older-commit>
|
||||
```
|
||||
|
||||
## Moving Commits Between Stack Levels
|
||||
|
||||
Relocate a commit to the correct branch in the stack.
|
||||
|
||||
```bash
|
||||
# Use commit ID from `but status` or `but show`
|
||||
but rub <commit-id> correct-branch
|
||||
```
|
||||
|
||||
## Splitting a Branch
|
||||
|
||||
Extract part of a branch into a new stack level.
|
||||
|
||||
```bash
|
||||
# Original has multiple features
|
||||
but branch new second-feature --anchor original-branch
|
||||
# Use commit ID from `but show original-branch`
|
||||
but rub <commit-id> second-feature
|
||||
```
|
||||
|
||||
## Recovery
|
||||
|
||||
Recreate a branch with correct anchor when the original was created wrong.
|
||||
|
||||
```bash
|
||||
# Recreate branch with correct anchor
|
||||
but branch new child-stacked --anchor parent
|
||||
commit_sha=$(but show child --json | jq -r '.commits[0].id')
|
||||
but rub $commit_sha child-stacked
|
||||
but branch delete child --force
|
||||
```
|
||||
@@ -0,0 +1,250 @@
|
||||
---
|
||||
name: gitbutler-virtual-branches
|
||||
description: This skill should be used when the user asks to "create a virtual branch", "assign file to branch", "work on multiple features simultaneously", "organize commits after coding", "use but commands", or mentions GitButler, virtual branches, parallel development without checkout, post-hoc commit organization, multi-agent concurrent development, or `--gitbutler`/`--but` flags.
|
||||
metadata:
|
||||
version: "1.0.0"
|
||||
author: outfitter
|
||||
category: version-control
|
||||
related-skills:
|
||||
- gitbutler-multi-agent
|
||||
- gitbutler-stacks
|
||||
- gitbutler-complete-branch
|
||||
---
|
||||
|
||||
# GitButler Virtual Branches
|
||||
|
||||
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_to_use>
|
||||
|
||||
## This, Not That
|
||||
|
||||
| Task | This | Not That |
|
||||
| ---- | ---- | -------- |
|
||||
| Initialize workspace | `but setup` | manual setup |
|
||||
| Create branch | `but branch new name` | `git checkout -b name` |
|
||||
| View changes | `but status` | `git status` |
|
||||
| Assign file to branch | `but rub <file-id> <branch>` | manual staging |
|
||||
| Commit to branch | `but commit <branch> -m "msg"` | `git commit -m "msg"` |
|
||||
| Move commit | `but rub <sha> <branch>` | `git cherry-pick` |
|
||||
| Squash commits | `but squash <branch>` | `git rebase -i` |
|
||||
| Undo operation | `but undo` | `git reset` |
|
||||
| Switch context | Create new branch | `git checkout` |
|
||||
|
||||
**Key difference from Git**: All branches visible at once. Organize files to branches after editing. No checkout.
|
||||
|
||||
## 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` |
|
||||
| Oplog | Operations log for undo/restore — your safety net |
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Initialize (one time)
|
||||
but setup
|
||||
|
||||
# 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) |
|
||||
|
||||
## Essential Commands
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `but setup` | Initialize GitButler in repository |
|
||||
| `but status` | View changes and file IDs |
|
||||
| `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 absorb` | Auto-amend uncommitted changes to appropriate commits |
|
||||
| `but squash <commits>` | Squash commits (by IDs, range, or branch) |
|
||||
| `but show <id>` | Inspect a commit or branch in detail |
|
||||
| `but resolve <commit>` | Enter conflict resolution mode |
|
||||
| `but push` | Push branches to remote |
|
||||
| `but pr new` | Create/update PRs on forge |
|
||||
| `but config forge auth` | Authenticate with GitHub (OAuth) |
|
||||
| `but mark <branch>` | Auto-assign new changes to branch |
|
||||
| `but unmark` | Remove all mark rules from workspace |
|
||||
| `but oplog` | Show operation history |
|
||||
| `but undo` | Undo last operation |
|
||||
| `but oplog snapshot --message "msg"` | Create manual snapshot |
|
||||
| `but pull` | Update workspace with latest base |
|
||||
| `but gui` | Open GitButler GUI for current repo |
|
||||
|
||||
**JSON output**: Use `--json` or `-j` flag on any command: `but status --json`
|
||||
|
||||
## Parallel 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
|
||||
```
|
||||
|
||||
## Conflict Handling
|
||||
|
||||
GitButler handles conflicts **per-commit** during rebase/update (unlike Git's all-or-nothing model):
|
||||
|
||||
1. Rebase continues even when some commits conflict
|
||||
2. Conflicted commits marked in UI/status
|
||||
3. Use `but resolve` to enter resolution mode per commit
|
||||
4. Partial resolution can be saved for later
|
||||
|
||||
```bash
|
||||
# Update base (may cause conflicts)
|
||||
but pull
|
||||
|
||||
# Check which commits have conflicts
|
||||
but status
|
||||
|
||||
# Enter resolution mode for a specific commit
|
||||
but resolve <commit-id>
|
||||
|
||||
# Fix conflicts in your editor, then check remaining
|
||||
but resolve status
|
||||
|
||||
# Finalize when done (or cancel to abort)
|
||||
but resolve finish
|
||||
```
|
||||
|
||||
For detailed conflict resolution workflows, see `references/reference.md#conflict-resolution`.
|
||||
|
||||
## Auto-Assignment with Marks
|
||||
|
||||
Set up workspace rules to auto-assign files to branches:
|
||||
|
||||
```bash
|
||||
# Auto-assign new changes to auth-feature branch
|
||||
but mark auth-feature
|
||||
|
||||
# Remove all rules
|
||||
but unmark
|
||||
```
|
||||
|
||||
Useful for multi-agent workflows where changes should route to a specific branch.
|
||||
|
||||
<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 oplog 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
|
||||
|
||||
| Symptom | Solution |
|
||||
|---------|----------|
|
||||
| Files not committing | Assign first: `but rub <file-id> <branch>` |
|
||||
| Broken pipe panic | Capture output: `output=$(but status)` |
|
||||
| Mixed git/but broke state | `but pull` or `but setup` |
|
||||
| Lost work | `but undo` or `but oplog restore <snapshot-id>` |
|
||||
|
||||
For detailed troubleshooting (branch tracking, conflicts, filename issues), see `references/reference.md#troubleshooting-guide`.
|
||||
|
||||
## Recovery
|
||||
|
||||
Quick undo: `but undo` | Full restore: `but oplog restore <snapshot-id>` | View history: `but oplog`
|
||||
|
||||
For recovery from lost work or corrupted state, see `references/reference.md#recovery-scenarios`.
|
||||
|
||||
<references>
|
||||
|
||||
### Reference Files
|
||||
|
||||
- **`references/reference.md`** — Complete CLI reference, JSON schemas, troubleshooting
|
||||
- **`references/examples.md`** — Real-world workflow patterns with commands
|
||||
- **`references/ai-integration.md`** — Hooks, MCP server, agent lifecycle
|
||||
|
||||
### Related Skills
|
||||
|
||||
- [gitbutler-multi-agent](../multi-agent/SKILL.md) — Multi-agent coordination
|
||||
- [gitbutler-stacks](../stacks/SKILL.md) — Stacked branches
|
||||
- [gitbutler-complete-branch](../complete-branch/SKILL.md) — Merging to main
|
||||
|
||||
### External
|
||||
|
||||
- [GitButler Docs](https://docs.gitbutler.com/) — Official documentation
|
||||
- [GitButler AI Integration](https://docs.gitbutler.com/features/ai-integration/) — Hooks and MCP
|
||||
|
||||
</references>
|
||||
@@ -0,0 +1,238 @@
|
||||
# AI Integration Reference
|
||||
|
||||
GitButler provides hooks, MCP server, and GUI features for AI agent integration.
|
||||
|
||||
---
|
||||
|
||||
## Lifecycle Hooks
|
||||
|
||||
GitButler CLI commands that can be called from AI agent lifecycle hooks.
|
||||
|
||||
### Claude Code Hooks
|
||||
|
||||
Add to `.claude/hooks.json`:
|
||||
|
||||
```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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Hook commands:**
|
||||
|
||||
| Command | Trigger | Purpose |
|
||||
|---------|---------|---------|
|
||||
| `but claude pre-tool` | Before Edit/Write | Prepare workspace, snapshot |
|
||||
| `but claude post-tool` | After Edit/Write | Auto-assign changes |
|
||||
| `but claude stop` | Session ends | Finalize commits, cleanup |
|
||||
|
||||
### Cursor Hooks
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"after-edit": "but cursor after-edit",
|
||||
"stop": "but cursor stop"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Hook commands:**
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `but cursor after-edit` | Auto-assign/commit after Cursor edits |
|
||||
| `but cursor stop` | Finalize when task completes |
|
||||
|
||||
---
|
||||
|
||||
## MCP Server
|
||||
|
||||
Start GitButler's MCP server for programmatic agent access:
|
||||
|
||||
```bash
|
||||
but mcp
|
||||
```
|
||||
|
||||
### Available Tool
|
||||
|
||||
**`gitbutler_update_branches`**
|
||||
|
||||
Updates commits based on prompt and changes. Designed for async processing:
|
||||
|
||||
1. Agent calls after making code changes
|
||||
2. GitButler records changes + prompt immediately (returns fast)
|
||||
3. Processing happens asynchronously to create commits
|
||||
|
||||
**Input schema:**
|
||||
|
||||
```typescript
|
||||
{
|
||||
prompt: string // Description of changes made
|
||||
}
|
||||
```
|
||||
|
||||
**Current limitations:**
|
||||
|
||||
- No branch creation via MCP
|
||||
- No stack management
|
||||
- No push/submit operations
|
||||
- No branch navigation
|
||||
- No restack commands
|
||||
|
||||
**Future roadmap (from GitButler docs):**
|
||||
|
||||
- Auto-absorbing changes into existing commits
|
||||
- Creating new branches based on prompt theme
|
||||
- Creating stacked branches
|
||||
- More sophisticated commit organization
|
||||
|
||||
---
|
||||
|
||||
## Agents Tab (GUI)
|
||||
|
||||
GitButler GUI provides an Agents Tab for Claude Code integration:
|
||||
|
||||
1. **Branch-Agent Binding**: Each virtual branch can be tied to an agent session
|
||||
2. **Parallel Execution**: Multiple agents run simultaneously, isolated by branch
|
||||
3. **Automatic Commit Management**: Agent work auto-committed to their branch
|
||||
4. **Session Persistence**: Agent context preserved across restarts
|
||||
|
||||
### Setup
|
||||
|
||||
1. Open GitButler GUI for repo: `but gui`
|
||||
2. Navigate to Agents Tab
|
||||
3. Create agent sessions tied to virtual branches
|
||||
4. Configure which branches each agent can modify
|
||||
|
||||
---
|
||||
|
||||
## Agent Workflow Patterns
|
||||
|
||||
### Pattern 1: Hook-Based Auto-Commit
|
||||
|
||||
Let GitButler handle commits automatically:
|
||||
|
||||
```bash
|
||||
# Agent instruction
|
||||
"Never use the git commit command after a task is finished"
|
||||
```
|
||||
|
||||
PostToolUse hook creates commits automatically.
|
||||
|
||||
### Pattern 2: Explicit Agent Commits
|
||||
|
||||
Agent controls commit timing:
|
||||
|
||||
```bash
|
||||
# Agent creates branch
|
||||
but branch new agent-feature
|
||||
|
||||
# Agent makes changes...
|
||||
|
||||
# Agent assigns and commits explicitly
|
||||
but rub <file-id> agent-feature
|
||||
but commit agent-feature -m "feat: implementation"
|
||||
```
|
||||
|
||||
### Pattern 3: Multi-Agent with Marks
|
||||
|
||||
Set up auto-assignment for agent branches:
|
||||
|
||||
```bash
|
||||
# Agent A's branch receives new changes
|
||||
but mark agent-a-auth
|
||||
|
||||
# Agent B's branch receives new changes
|
||||
but mark agent-b-api
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Agent Instructions
|
||||
|
||||
When configuring agents to work with GitButler:
|
||||
|
||||
1. **Never use `git commit`** - Breaks GitButler state
|
||||
2. **Never use `git add`** - GitButler manages index
|
||||
3. **Never use `git checkout`** - All branches always applied
|
||||
4. **Always return to workspace** after any git operations: `git checkout gitbutler/workspace`
|
||||
5. **Use `but status` to find file IDs** before using `but rub`
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Agent commit "orphaned"
|
||||
|
||||
**Cause:** Agent used `git commit` instead of `but commit`.
|
||||
|
||||
**Solution:**
|
||||
|
||||
```bash
|
||||
git reflog # Find orphaned commit
|
||||
but branch new recovered-work
|
||||
# Manually apply changes or cherry-pick
|
||||
```
|
||||
|
||||
### MCP server not responding
|
||||
|
||||
**Cause:** Feature may be behind experimental flag.
|
||||
|
||||
**Solution:**
|
||||
|
||||
1. Check GitButler version (0.16+)
|
||||
2. Enable experimental features in GUI settings
|
||||
3. Restart `but mcp`
|
||||
|
||||
### Hooks not triggering
|
||||
|
||||
**Verify:**
|
||||
|
||||
1. Hook file location correct (`.claude/hooks.json`)
|
||||
2. JSON syntax valid
|
||||
3. `but` command in PATH
|
||||
4. GitButler initialized in repo
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [GitButler MCP Server Docs](https://docs.gitbutler.com/features/ai-integration/mcp-server)
|
||||
- [Claude Code Hooks Docs](https://docs.gitbutler.com/features/ai-integration/claude-code-hooks)
|
||||
- [Cursor Hooks Docs](https://docs.gitbutler.com/features/ai-integration/cursor-hooks)
|
||||
- [Agents Tab Blog Post](https://blog.gitbutler.com/agents-tab)
|
||||
@@ -0,0 +1,402 @@
|
||||
# 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 setup
|
||||
|
||||
# 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 status
|
||||
# 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 status
|
||||
```
|
||||
|
||||
### Squashing Commits
|
||||
|
||||
```bash
|
||||
# Too many small commits on feature-branch
|
||||
# Squash using explicit command
|
||||
but squash feature-branch
|
||||
```
|
||||
|
||||
### 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 status
|
||||
```
|
||||
|
||||
### Submit Stack as PRs
|
||||
|
||||
```bash
|
||||
# Using but CLI (preferred)
|
||||
but push refactor-database
|
||||
but pr new refactor-database
|
||||
|
||||
but push feature-new-model
|
||||
but pr new feature-new-model
|
||||
|
||||
but push test-new-model
|
||||
but pr new test-new-model
|
||||
```
|
||||
|
||||
```bash
|
||||
# Alternative: using git + gh directly
|
||||
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 status # Branch recovered!
|
||||
```
|
||||
|
||||
### Recover from Bad Reorganization
|
||||
|
||||
```bash
|
||||
# Snapshot before risky operations
|
||||
but oplog 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 oplog 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 pull
|
||||
|
||||
# If still broken, reinitialize
|
||||
but oplog snapshot --message "Before recovery"
|
||||
but setup
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## New in 0.19.0
|
||||
|
||||
### Selective Commit with `--changes`
|
||||
|
||||
```bash
|
||||
# Check status for file/hunk IDs
|
||||
but status
|
||||
# ╭┄00 [Unassigned Changes]
|
||||
# │ m6 A src/auth.ts
|
||||
# │ p9 A src/api.ts
|
||||
# │ i3 M README.md
|
||||
|
||||
# Commit only specific files by ID
|
||||
but commit feature-auth -p m6,i3 -m "feat: add auth and update docs"
|
||||
|
||||
# p9 remains uncommitted
|
||||
```
|
||||
|
||||
### Conflict Resolution with `but resolve`
|
||||
|
||||
```bash
|
||||
# After pulling, a commit has conflicts
|
||||
but pull
|
||||
but status
|
||||
# Shows conflicted commit with ⚠️ marker
|
||||
|
||||
# Enter resolution mode
|
||||
but resolve abc1234
|
||||
|
||||
# Fix conflict markers in your editor
|
||||
# Check what's left
|
||||
but resolve status
|
||||
|
||||
# Finalize
|
||||
but resolve finish
|
||||
```
|
||||
|
||||
### Squashing with Ranges
|
||||
|
||||
```bash
|
||||
# Squash all commits in a branch
|
||||
but squash feature-branch
|
||||
|
||||
# Squash specific commits
|
||||
but squash abc1234 def5678
|
||||
|
||||
# Squash a range
|
||||
but squash abc1234..ghi9012
|
||||
```
|
||||
|
||||
### Absorb with Preview
|
||||
|
||||
```bash
|
||||
# Preview where changes would be absorbed
|
||||
but absorb --dry-run
|
||||
|
||||
# Absorb into new commits instead of amending
|
||||
but absorb --new
|
||||
```
|
||||
|
||||
### Push with Preview
|
||||
|
||||
```bash
|
||||
# See what would be pushed without pushing
|
||||
but push --dry-run
|
||||
|
||||
# Push a specific branch
|
||||
but push feature-auth
|
||||
|
||||
# Push all unpushed branches
|
||||
but push
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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 oplog snapshot --message "Before major reorganization"
|
||||
but oplog snapshot --message "Before multi-agent coordination"
|
||||
but oplog 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 branch commits
|
||||
but show feature-branch --json | jq '.commits[] | .id'
|
||||
|
||||
# Workspace overview
|
||||
but status --json | jq '.stacks'
|
||||
```
|
||||
@@ -0,0 +1,534 @@
|
||||
# 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
|
||||
```
|
||||
|
||||
**JSON output**: Use `--json` or `-j` per command, or as a global flag:
|
||||
|
||||
```bash
|
||||
but status --json # Per-command flag
|
||||
but --json status # Global flag (also works)
|
||||
```
|
||||
|
||||
### Inspection Commands
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `but status` | View uncommitted changes and file assignments |
|
||||
| `but status -f` | Show modified files in each commit |
|
||||
| `but status -v, --verbose` | Show verbose output with commit author and timestamp |
|
||||
| `but show <id>` | Show detailed info about a commit or branch |
|
||||
| `but diff` | Show diff of all uncommitted changes |
|
||||
| `but diff <id>` | Show diff for a specific entity (file, branch, commit) |
|
||||
| `but oplog` | View operations history (snapshots) |
|
||||
| `but gui` | Open GitButler GUI for current repo |
|
||||
|
||||
**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 unapply <name>` | Remove branch from workspace (keeps in Git) |
|
||||
| `but apply <name>` | Apply an unapplied branch to workspace |
|
||||
| `but pick <source> [branch]` | Cherry-pick commit from unapplied 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 -p <id>,<id>` | Commit specific files/hunks by CLI ID |
|
||||
| `but commit --ai` | Generate commit message with AI |
|
||||
| `but commit -c` | Create new branch for this commit |
|
||||
| `but commit` | Opens `$EDITOR` for message |
|
||||
| `but commit empty --before <target>` | Insert blank commit before target |
|
||||
| `but commit empty --after <target>` | Insert blank commit after target |
|
||||
|
||||
**Note:** Unlike git, GitButler commits all changes by default. Use `-o/--only` to commit only assigned files, or `-p/--changes` to select specific file/hunk IDs.
|
||||
|
||||
### 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 commit empty --before/--after <target>` | Insert blank commit before or after target |
|
||||
| `but reword` | Edit commit message or rename branch |
|
||||
| `but absorb` | Auto-amend uncommitted changes to appropriate commits based on context |
|
||||
| `but absorb --dry-run` | Preview what absorb would do without changing anything |
|
||||
| `but absorb --new` | Create new commits instead of amending existing ones |
|
||||
| `but squash <commits>` | Squash commits together (by IDs, range, or branch name) |
|
||||
| `but move <commit> <target>` | Move commit to a different location in the stack |
|
||||
| `but amend <file> <commit>` | Amend a file change into a specific commit |
|
||||
| `but uncommit <source>` | Uncommit changes back to unstaged area |
|
||||
| `but discard <id>` | Discard uncommitted changes from worktree |
|
||||
| `but mark <branch>` | Auto-assign new changes to branch |
|
||||
| `but unmark` | Remove all mark rules from workspace |
|
||||
|
||||
**`but absorb`**: Analyzes uncommitted changes and automatically amends them to the appropriate existing commits based on file context and change location. Similar to `git absorb` but integrated with virtual branches.
|
||||
|
||||
### Forge Integration (GitHub)
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `but config forge auth` | Authenticate with GitHub via OAuth flow |
|
||||
| `but config forge list-users` | List authenticated accounts |
|
||||
| `but config forge forget <username>` | Remove authenticated account |
|
||||
| `but push [branch]` | Push branch to remote |
|
||||
| `but push -d, --dry-run` | Preview what would be pushed |
|
||||
| `but push -f, --with-force` | Force push |
|
||||
| `but push -r, --run-hooks` | Execute pre-push hooks |
|
||||
| `but pr new [branch]` | Create PR for branch on forge |
|
||||
|
||||
**Push + PR workflow:**
|
||||
1. Push branch to remote: `but push feature-auth`
|
||||
2. Create PR: `but pr new feature-auth`
|
||||
3. Or push all unpushed branches: `but push` (non-interactive)
|
||||
4. Requires prior `but config forge auth` for first-time setup
|
||||
|
||||
### Base Branch Operations
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `but pull --check` | Fetch remotes and check mergeability |
|
||||
| `but pull` | Update workspace with latest from base |
|
||||
|
||||
### Operations History (Undo/Restore)
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `but oplog` | View operation history |
|
||||
| `but undo` | Undo last operation |
|
||||
| `but oplog restore <snapshot-id>` | Restore to specific snapshot |
|
||||
| `but oplog snapshot --message "msg"` | Create manual snapshot |
|
||||
|
||||
### Conflict Resolution
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `but resolve <commit-id>` | Enter resolution mode for a conflicted commit |
|
||||
| `but resolve status` | Show remaining conflicted files |
|
||||
| `but resolve finish` | Finalize resolution and return to workspace |
|
||||
| `but resolve cancel` | Cancel resolution and return to workspace |
|
||||
|
||||
**Workflow:**
|
||||
1. `but status` shows conflicted commits
|
||||
2. `but resolve <commit-id>` to enter resolution mode
|
||||
3. Fix conflict markers in your editor
|
||||
4. `but resolve status` to check remaining conflicts
|
||||
5. `but resolve finish` to finalize
|
||||
|
||||
### Workspace Lifecycle
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `but setup` | Initialize GitButler project from existing Git repo |
|
||||
| `but setup --init` | Initialize new Git repo and set up GitButler |
|
||||
| `but teardown` | Exit GitButler mode, return to normal Git |
|
||||
|
||||
**`but teardown`**: Creates an oplog snapshot, checks out the first active branch as a regular Git branch, and provides instructions for returning to GitButler mode.
|
||||
|
||||
### Configuration
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `but config` | Show configuration overview |
|
||||
| `but config user` | View user configuration |
|
||||
| `but config user set name "Name"` | Set user name |
|
||||
| `but config user set email "email"` | Set user email |
|
||||
| `but config forge` | View forge configuration |
|
||||
| `but config forge auth` | Authenticate with forge (GitHub OAuth) |
|
||||
| `but config forge list-users` | List authenticated accounts |
|
||||
| `but config forge forget <user>` | Remove authenticated account |
|
||||
|
||||
### 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 status --json`
|
||||
|
||||
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 show <branch> --json`
|
||||
|
||||
Shows detailed branch info with commits. Key fields:
|
||||
- `commits` — Array of commits on the branch
|
||||
- `commits[].id` — Commit SHA
|
||||
|
||||
### `but diff --json`
|
||||
|
||||
Shows diffs in JSON format for programmatic analysis.
|
||||
|
||||
**Useful jq patterns:**
|
||||
|
||||
```bash
|
||||
# Get branch commits
|
||||
but show feature-branch --json | jq '.commits[] | .id'
|
||||
|
||||
# Workspace overview
|
||||
but status --json | jq '.stacks'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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 (all applied) |
|
||||
| **PR Submission** | ✓ `gt submit --stack` | ✓ `but push` + `but pr new` |
|
||||
| **JSON Output** | Limited | ✓ Comprehensive via `--json` per command |
|
||||
| **Multi-Feature Work** | Switch branches | All in one workspace |
|
||||
| **CLI Completeness** | ✓ Full automation | ✓ Full automation (as of 0.19.0) |
|
||||
| **Conflict Resolution** | Standard git rebase | ✓ Per-commit via `but resolve` |
|
||||
|
||||
**Choose Graphite when:**
|
||||
- Stack navigation commands needed (`gt up`/`gt down`)
|
||||
- Terminal-first linear workflow
|
||||
- Established stacked PR practices
|
||||
|
||||
**Choose GitButler when:**
|
||||
- Multiple unrelated features simultaneously
|
||||
- Multi-agent concurrent development
|
||||
- Exploratory coding (organize after)
|
||||
- Post-hoc commit reorganization
|
||||
- Per-commit conflict resolution needed
|
||||
- Visual organization preferred (GUI + CLI)
|
||||
|
||||
**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 visible | Not applied | `but apply <branch>` or `but pick <commit>` |
|
||||
| Files not committing | Not assigned | `but rub <file-id> <branch>` |
|
||||
| Mixed git/but broke state | Used git commands | `but pull` or `but setup` |
|
||||
| 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 pull` to resync
|
||||
2. If severely broken: `but setup` 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 oplog restore <snapshot-id>
|
||||
```
|
||||
|
||||
#### Corrupted Workspace State
|
||||
|
||||
```bash
|
||||
# Step 1: Snapshot current state
|
||||
but oplog snapshot --message "Before recovery"
|
||||
|
||||
# Step 2: Update base
|
||||
but pull
|
||||
|
||||
# Step 3: Last resort - reinitialize
|
||||
but setup
|
||||
```
|
||||
|
||||
#### 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 oplog snapshot --message "Before major reorganization"
|
||||
```
|
||||
|
||||
**Before GitButler updates:**
|
||||
1. Commit everything
|
||||
2. Push all branches to remote
|
||||
3. Verify Operations History accessible
|
||||
Reference in New Issue
Block a user