opencode-gitbutler 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,271 @@
1
+ # GitButler CLI Cheat Sheet
2
+
3
+ Quick reference for `but` commands. For full details, see `references/reference.md`.
4
+
5
+ ## GitButler Detection
6
+
7
+ ```bash
8
+ git branch --show-current
9
+ # "gitbutler/workspace" → Use 'but' commands for all writes
10
+ ```
11
+
12
+ | Command Type | Rule |
13
+ |---|---|
14
+ | Read-only (`git log`, `git diff`, `git show`, `git blame`) | ✅ Safe, use freely |
15
+ | Has `but` equivalent (commit, push, branch, rebase) | ⚠️ **Must use `but`** |
16
+ | No `but` equivalent (cherry-pick, stash, tag, revert) | ✅ Use `git` |
17
+ | Destructive (`reset --hard`, `push --force`) | ⚠️ Create snapshot first |
18
+
19
+ ---
20
+
21
+ ## Session Start (Every Time)
22
+
23
+ ```bash
24
+ but pull # Sync upstream
25
+ but status --json -f # See workspace state
26
+ ```
27
+
28
+ ---
29
+
30
+ ## Git → But Command Mapping
31
+
32
+ | Git Command | But Command | Notes |
33
+ |---|---|---|
34
+ | `git status` | `but status --json` | Use `--json` for agents, `-f` for file lists |
35
+ | `git add <file>` | `but stage <id> <branch>` | Stage to specific branch |
36
+ | `git commit -m` | `but commit <branch> -m --changes <ids>` | Always use `--changes` |
37
+ | `git commit --amend` | `but absorb <id>` or `but amend <id> <commit>` | Smart or explicit amend |
38
+ | `git checkout -b` | `but branch new <name>` | Creates virtual branch |
39
+ | `git checkout` / `git switch` | `but apply <branch>` | Activate branch |
40
+ | `git rebase -i` (squash) | `but squash <commits>` | No editor needed |
41
+ | `git rebase -i` (reword) | `but reword <id> -m` | Auto-rebases dependents |
42
+ | `git push` | `but push <branch>` | Push specific branch |
43
+ | `git push --force` | `but push --with-force` | Use carefully |
44
+ | `git reflog` | `but oplog` | More powerful — tracks everything |
45
+ | `git reset --hard` | `but oplog restore <sha>` | Safer, reversible |
46
+ | N/A | `but undo` | Undo last operation |
47
+ | N/A | `but absorb` | Auto-amend to correct commit |
48
+ | N/A | `but pr new <branch> -t` | Push + create PR in one step |
49
+
50
+ ---
51
+
52
+ ## Inspection
53
+
54
+ ```bash
55
+ but status --json # Workspace overview (agent-friendly)
56
+ but status --json -f # With full file lists
57
+ but show <id> --json # Details about commit/branch
58
+ but diff <id> # Diff for file, branch, or commit
59
+ but diff --json # Diff with hunk IDs (for --changes)
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Branching
65
+
66
+ ```bash
67
+ but branch new <name> # Independent (parallel) branch
68
+ but branch new <name> -a <id> # Stacked (dependent) branch
69
+ but branch # List all branches
70
+ but apply <id> # Activate branch in workspace
71
+ but unapply <id> # Deactivate branch from workspace
72
+ but branch delete <id> # Delete branch
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Committing
78
+
79
+ ```bash
80
+ # RECOMMENDED: commit specific files
81
+ but commit <branch> -m "msg" --changes <id>,<id>
82
+
83
+ # Commit only pre-staged files
84
+ but commit <branch> --only -m "msg"
85
+
86
+ # RISKY: commits ALL uncommitted changes
87
+ but commit <branch> -m "msg"
88
+ ```
89
+
90
+ **Getting IDs for `--changes`:**
91
+ - File IDs: `but status --json`
92
+ - Hunk IDs: `but diff --json` (for fine-grained control)
93
+
94
+ ---
95
+
96
+ ## Staging
97
+
98
+ ```bash
99
+ but stage <file-id> <branch> # Assign file to branch
100
+ ```
101
+
102
+ ---
103
+
104
+ ## The `rub` Multi-Tool
105
+
106
+ One command, four operations based on source/target types:
107
+
108
+ | Source | Target | Operation | Example |
109
+ |---|---|---|---|
110
+ | File | Branch | **Stage** | `but rub a1 bu` |
111
+ | File | Commit | **Amend** | `but rub a1 c3` |
112
+ | Commit | Commit | **Squash** | `but rub c2 c3` |
113
+ | Commit | Branch | **Move** | `but rub c2 bv` |
114
+
115
+ ---
116
+
117
+ ## Editing History
118
+
119
+ ```bash
120
+ but reword <id> -m "new msg" # Edit commit message or rename branch
121
+ but squash <c1> <c2> <c3> # Squash specific commits
122
+ but squash <c1>..<c4> # Squash a range
123
+ but squash <branch> # Squash all commits in branch
124
+ but amend <file-id> <commit-id> # Explicit amend (you choose target)
125
+ but absorb <file-id> # Smart amend (GitButler chooses target)
126
+ but absorb <file-id> --dry-run # Preview absorb
127
+ but move <commit> <target> # Move commit to different location
128
+ but uncommit <commit-id> # Uncommit back to unstaged area
129
+ but discard <file-id> # Discard uncommitted changes
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Remote Operations
135
+
136
+ ```bash
137
+ but push <branch> # Push specific branch
138
+ but push # Push all branches with unpushed commits
139
+ but push --dry-run # Preview what would be pushed
140
+ but pull # Fetch and rebase all branches
141
+ but pr new <branch> -t # Push + create PR (auto-title)
142
+ but pr new <branch> -m "Title" # Push + create PR with custom message
143
+ ```
144
+
145
+ ---
146
+
147
+ ## Undo & Recovery
148
+
149
+ ```bash
150
+ but undo # Undo last operation (one step back)
151
+ but oplog # View all operations
152
+ but oplog snapshot -m "checkpoint" # Create named checkpoint
153
+ but oplog restore <snapshot-id> # Restore to any point
154
+ ```
155
+
156
+ **Quick decision:**
157
+ - Last thing went wrong → `but undo`
158
+ - Need to go back further → `but oplog` → `but oplog restore <id>`
159
+
160
+ ---
161
+
162
+ ## Conflict Resolution
163
+
164
+ ```bash
165
+ but resolve <commit-id> # Enter resolution mode
166
+ # Fix conflicts in files...
167
+ but resolve status # Check remaining conflicts
168
+ but resolve finish # Finalize resolution
169
+ but resolve cancel # Abort, return to workspace
170
+ ```
171
+
172
+ ---
173
+
174
+ ## Marks (Auto-staging)
175
+
176
+ ```bash
177
+ but mark <branch-id> # New changes auto-stage to this branch
178
+ but mark <commit-id> # New changes auto-amend into this commit
179
+ but mark <id> --delete # Remove mark
180
+ but unmark # Remove all marks
181
+ ```
182
+
183
+ ---
184
+
185
+ ## Post-Merge Cleanup
186
+
187
+ ```bash
188
+ but unapply <merged-branch> # MUST do BEFORE pull
189
+ but pull # Then pull merged changes
190
+ ```
191
+
192
+ **Order matters.** Pull before unapply = orphan branch errors.
193
+
194
+ ---
195
+
196
+ ## Status Symbols
197
+
198
+ | Symbol | Meaning |
199
+ |---|---|
200
+ | `A` | Added (new file) |
201
+ | `M` | Modified |
202
+ | `D` | Deleted |
203
+ | `[LOCKED]` | File depends on specific commit (absorb target) |
204
+ | `●` | Commit |
205
+ | `CONFLICTED` | Needs conflict resolution |
206
+
207
+ ---
208
+
209
+ ## Safety Rules
210
+
211
+ 1. **Always use `--changes`** when committing in multi-agent environments
212
+ 2. **Never discard changes you didn't create** — `zz` may contain others' work
213
+ 3. **Always `but unapply` before `but pull`** after PR merge
214
+ 4. **Always `but pull` at session start** to prevent stale-base conflicts
215
+ 5. **Always `but status --json`** before using IDs — they change after every operation
216
+
217
+ ---
218
+
219
+ ## Common Workflows (Quick)
220
+
221
+ ### Commit specific files
222
+
223
+ ```bash
224
+ but status --json -f # Get file IDs
225
+ but commit bu -m "msg" --changes a1,a2
226
+ ```
227
+
228
+ ### Fix typo in old commit
229
+
230
+ ```bash
231
+ but status --json # Find commit ID
232
+ but reword c2 -m "Fixed message"
233
+ ```
234
+
235
+ ### Squash all branch commits
236
+
237
+ ```bash
238
+ but squash bu
239
+ but reword c1 -m "Clean single commit message"
240
+ ```
241
+
242
+ ### Auto-amend a fix into the right commit
243
+
244
+ ```bash
245
+ but status --json -f # Check for [LOCKED] indicator
246
+ but absorb a1 --dry-run # Preview
247
+ but absorb a1 # Execute
248
+ ```
249
+
250
+ ### Recover from mistake
251
+
252
+ ```bash
253
+ but undo # Quick: undo last operation
254
+ # OR
255
+ but oplog # Find the right snapshot
256
+ but oplog restore <id> # Time travel
257
+ ```
258
+
259
+ ### Full feature flow
260
+
261
+ ```bash
262
+ but pull
263
+ but branch new feat/my-feature
264
+ # make changes...
265
+ but status --json -f
266
+ but commit feat/my-feature -m "Implement feature" --changes a1,a2
267
+ but pr new feat/my-feature -t
268
+ # after merge:
269
+ but unapply feat/my-feature
270
+ but pull
271
+ ```
@@ -0,0 +1,333 @@
1
+ # GitButler CLI Key Concepts
2
+
3
+ Deep dive into GitButler's conceptual model and philosophy.
4
+
5
+ ## The Workspace Model
6
+
7
+ ### Traditional Git: Serial Branching
8
+
9
+ ```
10
+ main ──┬── feature-a (checkout here, work, commit, checkout back)
11
+ └── feature-b (checkout here, work, commit, checkout back)
12
+ ```
13
+
14
+ - Work on ONE branch at a time
15
+ - Switch contexts with `git checkout`
16
+ - Changes are isolated by branch
17
+
18
+ ### GitButler: Parallel Stacks
19
+
20
+ ```
21
+ workspace (gitbutler/workspace)
22
+ ├─ feature-a (applied, merged into workspace)
23
+ ├─ feature-b (applied, merged into workspace)
24
+ └─ feature-c (unapplied, not in workspace)
25
+ ```
26
+
27
+ - Work on MULTIPLE branches simultaneously
28
+ - No context switching - all applied branches merged in working directory
29
+ - Changes are ASSIGNED to branches, not isolated by checkout
30
+
31
+ ### Key Implications
32
+
33
+ 1. **No `git checkout`**: You don't switch between branches. All applied branches exist simultaneously in your workspace.
34
+
35
+ 2. **Multiple staging areas**: Each branch is like having its own `git add` staging area. You stage files to specific branches.
36
+
37
+ 3. **The `gitbutler/workspace` branch**: A merge commit containing all applied stacks. Don't interact with it directly - use `but` commands.
38
+
39
+ 4. **Applied vs Unapplied**: Control which branches are active:
40
+ - Applied branches: In your working directory
41
+ - Unapplied branches: Exist but not active
42
+ - Use `but apply`/`but unapply` to control
43
+
44
+ ## CLI IDs: Short Identifiers
45
+
46
+ Every object gets a short, human-readable CLI ID shown in `but status`:
47
+
48
+ ```
49
+ Commits: c1, c2, c3, c4, c5
50
+ Branches: bu, bv, bw
51
+ Files: a1, a2, a3
52
+ Hunks: h1, h2, h3
53
+ ```
54
+
55
+ **Why?** Git commit SHAs are long (40 chars). CLI IDs are short (2-3 chars) and unique within your current workspace context.
56
+
57
+ **Usage:** Pass these IDs as arguments to commands:
58
+
59
+ ```bash
60
+ but commit bu -m "message" # Commit to branch 'bu'
61
+ but stage a1 bu # Stage file 'a1' to branch 'bu'
62
+ but rub c2 c3 # Squash commits 'c2' and 'c3'
63
+ ```
64
+
65
+ ## Parallel vs Stacked Branches
66
+
67
+ ### Parallel Branches (Independent Work)
68
+
69
+ Create with `but branch new <name>`:
70
+
71
+ ```
72
+ main ──┬── api-endpoint (independent)
73
+ └── ui-update (independent)
74
+ ```
75
+
76
+ Use when:
77
+
78
+ - Tasks don't depend on each other
79
+ - Can be merged independently
80
+ - No shared code between them
81
+
82
+ Example: Adding a new API endpoint and updating button styles are independent.
83
+
84
+ ### Stacked Branches (Dependent Work)
85
+
86
+ Create with `but branch new <name> -a <anchor>`:
87
+
88
+ ```
89
+ main ── authentication ── user-profile ── settings-page
90
+ (base) (stacked) (stacked)
91
+ ```
92
+
93
+ Use when:
94
+
95
+ - Feature B needs code from Feature A
96
+ - Building incrementally on previous work
97
+ - Creating a series of related changes
98
+
99
+ Example: User profile page needs authentication to be implemented first.
100
+
101
+ **Dependency tracking:** GitButler automatically tracks which changes depend on which commits. You can't stage dependent changes to the wrong branch.
102
+
103
+ ## Multiple Staging Areas
104
+
105
+ Traditional git has ONE staging area:
106
+
107
+ ```bash
108
+ git add file1.js # Stage to THE staging area
109
+ git add file2.js # Stage to THE staging area
110
+ git commit # Commit from THE staging area
111
+ ```
112
+
113
+ GitButler has MULTIPLE staging areas (one per branch):
114
+
115
+ ```bash
116
+ but stage file1.js api-branch # Stage to api-branch's staging area
117
+ but stage file2.js ui-branch # Stage to ui-branch's staging area
118
+ but commit api-branch -m "..." # Commit from api-branch's staging area
119
+ but commit ui-branch -m "..." # Commit from ui-branch's staging area
120
+ ```
121
+
122
+ **Unstaged changes:** Files not staged to any branch yet. Use `but status` to see them, then `but stage` to assign them.
123
+
124
+ **Auto-assignment:** If only one branch is applied, changes may auto-assign to it.
125
+
126
+ ## The `but rub` Philosophy
127
+
128
+ `but rub` is the core primitive operation: "rub two things together" to perform an action.
129
+
130
+ ### What Happens Based on Types
131
+
132
+ The operation performed depends on what you combine:
133
+
134
+ | Source | Target | Operation | Example |
135
+ |--------|--------|-----------|---------|
136
+ | File | Branch | Stage file to branch | `but rub a1 bu` |
137
+ | File | Commit | Amend file into commit | `but rub a1 c3` |
138
+ | Commit | Commit | Squash commits | `but rub c2 c3` |
139
+ | Commit | Branch | Move commit to branch | `but rub c2 bu` |
140
+
141
+ ### Higher-Level Conveniences
142
+
143
+ These commands are wrappers around `but rub`:
144
+
145
+ - `but stage <file> <branch>` = `but rub <file> <branch>`
146
+ - `but amend <file> <commit>` = `but rub <file> <commit>`
147
+ - `but squash` = Multiple `but rub <commit> <commit>` operations
148
+ - `but move` = `but rub <commit> <target>` with position control
149
+
150
+ **Why this design?** One powerful primitive is easier to understand and maintain than many specialized commands. Once you understand `but rub`, you understand the editing model.
151
+
152
+ ## Dependency Tracking
153
+
154
+ GitButler tracks dependencies between changes automatically.
155
+
156
+ ### How It Works
157
+
158
+ ```
159
+ Commit C1: Added function foo()
160
+ Commit C2: Added function bar()
161
+ Uncommitted: Call to foo() in new code
162
+ ```
163
+
164
+ The uncommitted change **depends on** C1 (because it calls `foo()`).
165
+
166
+ **Implications:**
167
+
168
+ 1. Can't stage this change to a branch that doesn't have C1
169
+ 2. `but absorb` will automatically amend it into C1 (or a commit after C1)
170
+ 3. If you try to move the change, GitButler prevents invalid operations
171
+
172
+ ### Why This Matters
173
+
174
+ Prevents you from creating broken states:
175
+
176
+ - Can't move dependent code away from its dependencies
177
+ - Can't stage changes to wrong branches
178
+ - Ensures each branch remains independently functional
179
+
180
+ ## Empty Commits as Placeholders
181
+
182
+ You can create empty commits:
183
+
184
+ ```bash
185
+ but commit empty --before c3
186
+ but commit empty --after c3
187
+ ```
188
+
189
+ **Use cases:**
190
+
191
+ 1. **Mark future work:** Create empty commit as placeholder for changes you'll make
192
+ 2. **Mark targets:** Use with `but mark <empty-commit-id>` so future changes auto-amend into it
193
+ 3. **Organize history:** Add semantic markers in commit history
194
+
195
+ Example workflow:
196
+
197
+ ```bash
198
+ but commit empty -m "TODO: Add error handling" --before c5
199
+ but mark <empty-commit-id>
200
+ # Now work on error handling, changes auto-amend into the placeholder
201
+ ```
202
+
203
+ ## Auto-Staging and Auto-Commit (Marks)
204
+
205
+ Set a "mark" on a branch or commit to automatically organize new changes.
206
+
207
+ ### Mark a Branch
208
+
209
+ ```bash
210
+ but mark <branch-id>
211
+ ```
212
+
213
+ New unstaged changes automatically stage to this branch. Useful when focused on one feature.
214
+
215
+ ### Mark a Commit
216
+
217
+ ```bash
218
+ but mark <commit-id>
219
+ ```
220
+
221
+ New changes automatically amend into this commit. Useful for iterative refinement.
222
+
223
+ ### Remove Marks
224
+
225
+ ```bash
226
+ but mark <id> --delete # Remove specific mark
227
+ but unmark # Remove all marks
228
+ ```
229
+
230
+ **Example workflow:**
231
+
232
+ ```bash
233
+ but branch new refactor
234
+ but mark <refactor-branch-id>
235
+ # Make lots of changes - they all auto-stage to refactor branch
236
+ but unmark
237
+ ```
238
+
239
+ ## Operation History (Oplog)
240
+
241
+ Every operation in GitButler is recorded in the oplog (operation log).
242
+
243
+ ### What Gets Recorded
244
+
245
+ - Branch creation/deletion
246
+ - Commits
247
+ - Stage operations
248
+ - Rub/squash/move operations
249
+ - Push/pull operations
250
+
251
+ ### Using Oplog
252
+
253
+ ```bash
254
+ but oplog # View history
255
+ but undo # Undo last operation
256
+ but oplog restore <snapshot-id> # Restore to specific point
257
+ ```
258
+
259
+ Think of it as "git reflog" but for all GitButler operations, not just branch movements.
260
+
261
+ **Safety net:** Made a mistake? `but undo` it. Experimented and want to go back? `but oplog restore` to earlier snapshot.
262
+
263
+ ## Applied vs Unapplied Branches
264
+
265
+ Branches can be in two states:
266
+
267
+ ### Applied Branches
268
+
269
+ - Active in your workspace
270
+ - Merged into `gitbutler/workspace`
271
+ - Changes visible in working directory
272
+ - Can make changes, commit, stage files
273
+
274
+ ### Unapplied Branches
275
+
276
+ - Exist but not active
277
+ - Not in working directory
278
+ - Can't make changes (must apply first)
279
+ - Useful for temporarily setting aside work
280
+
281
+ ### Controlling State
282
+
283
+ ```bash
284
+ but apply <id> # Make branch active
285
+ but unapply <id> # Make branch inactive
286
+ ```
287
+
288
+ **Use cases:**
289
+
290
+ - Unapply branches causing conflicts
291
+ - Focus on subset of work (unapply others)
292
+ - Temporarily set aside work without deleting
293
+
294
+ ## Conflict Resolution Mode
295
+
296
+ When `but pull` causes conflicts, affected commits are marked as conflicted.
297
+
298
+ ### Resolution Workflow
299
+
300
+ 1. **Identify:** `but status` shows conflicted commits
301
+ 2. **Enter mode:** `but resolve <commit-id>`
302
+ 3. **Fix conflicts:** Edit files, remove conflict markers
303
+ 4. **Check:** `but resolve status` shows remaining conflicts
304
+ 5. **Finalize:** `but resolve finish` or `but resolve cancel`
305
+
306
+ ### During Resolution
307
+
308
+ - You're in a special mode focused on that commit
309
+ - Other GitButler operations are limited
310
+ - `but status` shows you're in resolution mode
311
+ - Must finish or cancel before continuing normal work
312
+
313
+ ## Read-Only Git Commands
314
+
315
+ Git commands that don't modify state are safe to use:
316
+
317
+ **Safe (read-only):**
318
+
319
+ - `git log` - View history
320
+ - `git diff` - See changes
321
+ - `git show` - View commits
322
+ - `git blame` - See line history
323
+ - `git reflog` - View reference log
324
+
325
+ **Unsafe (modifying):**
326
+
327
+ - `git status` - Shows merged workspace, not individual stacks
328
+ - `git commit` - Commits to wrong place
329
+ - `git checkout` - Breaks workspace model
330
+ - `git rebase` - Conflicts with GitButler's management
331
+ - `git merge` - Use `but merge` instead
332
+
333
+ **Rule of thumb:** If it reads, it's fine. If it writes, use `but` instead.