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,486 @@
1
+ # GitButler CLI Tutorial
2
+
3
+ A hands-on guide to working with `but` — safer, faster, and more intuitive than raw git.
4
+
5
+ ## Table of Contents
6
+
7
+ 1. [What is GitButler?](#what-is-gitbutler)
8
+ 2. [First Steps](#first-steps)
9
+ 3. [Understanding Status Output](#understanding-status-output)
10
+ 4. [Your First Commit](#your-first-commit)
11
+ 5. [Fixing Commit Messages](#fixing-commit-messages)
12
+ 6. [Squashing Commits](#squashing-commits)
13
+ 7. [Auto-Amending with Absorb](#auto-amending-with-absorb)
14
+ 8. [Working on Multiple Features](#working-on-multiple-features)
15
+ 9. [Stacked Branches](#stacked-branches)
16
+ 10. [Undo and Recovery](#undo-and-recovery)
17
+ 11. [Conflict Resolution](#conflict-resolution)
18
+ 12. [Creating Pull Requests](#creating-pull-requests)
19
+ 13. [Post-Merge Cleanup](#post-merge-cleanup)
20
+ 14. [Tips and Gotchas](#tips-and-gotchas)
21
+
22
+ ---
23
+
24
+ ## What is GitButler?
25
+
26
+ GitButler replaces most git write commands with safer alternatives:
27
+
28
+ | Feature | Git | GitButler |
29
+ |---------|-----|-----------|
30
+ | Undo anything | Complex reflog | `but undo` |
31
+ | Squash commits | `rebase -i` + editor | `but squash` |
32
+ | Fix old commit | stash, rebase, amend | `but absorb` |
33
+ | Multiple features | Switch branches constantly | Virtual branches (simultaneous) |
34
+ | Safe time travel | Risky reset | `but restore <sha>` |
35
+
36
+ Your repository is still a regular Git repo. GitButler works on top of it.
37
+
38
+ ---
39
+
40
+ ## First Steps
41
+
42
+ ### Check if GitButler is active
43
+
44
+ ```bash
45
+ git branch --show-current
46
+ ```
47
+
48
+ If the result is `gitbutler/workspace`, you're in GitButler mode. Use `but` commands for all write operations.
49
+
50
+ ### Start every session with
51
+
52
+ ```bash
53
+ but pull # Get latest upstream changes
54
+ but status --json -f # See workspace state
55
+ ```
56
+
57
+ **Always start here.** This prevents stale-base conflicts and shows you what's going on.
58
+
59
+ ---
60
+
61
+ ## Understanding Status Output
62
+
63
+ Run `but status` to see your workspace:
64
+
65
+ ```
66
+ ╭┄00 [Unassigned Changes]
67
+ ┊ a1 M calculator.py [LOCKED] 8ebedce
68
+ ┊ a2 A new-file.py
69
+
70
+ ┊╭┄bu [calculator-feature]
71
+ ┊● c3 859393e Add main entry point
72
+ ┊● c2 bac83b0 Add complete test suite
73
+ ┊● c1 8ebedce Add divide function
74
+ ├╯
75
+
76
+ ┊╭┄bv [utilities-feature] (no commits)
77
+ ├╯
78
+
79
+ ┴ 6e7da9e (common base) [origin/main]
80
+ ```
81
+
82
+ ### Key elements
83
+
84
+ | Element | Meaning |
85
+ |---------|---------|
86
+ | `a1`, `a2` | File/change IDs (use in commands) |
87
+ | `bu`, `bv` | Branch IDs |
88
+ | `c1`, `c2`, `c3` | Commit IDs |
89
+ | `M`, `A`, `D` | Modified, Added, Deleted |
90
+ | `[LOCKED] 8ebedce` | GitButler detected this change belongs to that commit |
91
+ | `●` | A commit in the branch |
92
+ | `(common base)` | Where branches diverge from remote |
93
+
94
+ ### For agents: use `--json`
95
+
96
+ ```bash
97
+ but status --json # Structured output for parsing
98
+ but status --json -f # With full file lists
99
+ ```
100
+
101
+ **IDs change after every operation.** Always refresh with `but status` before using IDs.
102
+
103
+ ---
104
+
105
+ ## Your First Commit
106
+
107
+ ### The Problem
108
+
109
+ You edited `api.js` and want to commit it to a branch.
110
+
111
+ ### The Solution
112
+
113
+ ```bash
114
+ # 1. Check what's changed
115
+ but status --json -f
116
+
117
+ # 2. Create a branch (if needed)
118
+ but branch new feat/add-api-endpoint
119
+
120
+ # 3. Commit specific files by their IDs
121
+ but commit feat/add-api-endpoint -m "Add user details endpoint" --changes a1
122
+ ```
123
+
124
+ ### Why `--changes`?
125
+
126
+ Without `--changes`, `but commit` grabs ALL uncommitted changes — including files from other work or other agents. **Always use `--changes <id>,<id>` to commit only what you intend.**
127
+
128
+ ```bash
129
+ # SAFE: commit only file a1
130
+ but commit bu -m "Add endpoint" --changes a1
131
+
132
+ # RISKY: commits EVERYTHING uncommitted
133
+ but commit bu -m "Add endpoint"
134
+ ```
135
+
136
+ **In git, this would be:** `git add api.js && git commit -m "Add endpoint"`
137
+
138
+ ---
139
+
140
+ ## Fixing Commit Messages
141
+
142
+ ### The Problem
143
+
144
+ ```
145
+ ● c2 8b8568c Add basic calculator fnctions ← typo!
146
+ ```
147
+
148
+ ### The Solution
149
+
150
+ ```bash
151
+ but reword c2 -m "Add basic calculator functions"
152
+ ```
153
+
154
+ GitButler automatically rebases all dependent commits. All commits get new SHAs (this is normal).
155
+
156
+ **In git, this would require:** `git rebase -i`, change `pick` to `reword`, edit in editor, save, hope for no conflicts.
157
+
158
+ ---
159
+
160
+ ## Squashing Commits
161
+
162
+ ### The Problem
163
+
164
+ ```
165
+ ● c5 Fix test edge case
166
+ ● c4 Fix another test
167
+ ● c3 Add tests
168
+ ● c2 Implement feature
169
+ ● c1 Initial scaffold
170
+ ```
171
+
172
+ Too many small commits. You want a clean history.
173
+
174
+ ### The Solution
175
+
176
+ **Squash all commits in a branch:**
177
+
178
+ ```bash
179
+ but squash bu # Squash all commits in branch bu into one
180
+ ```
181
+
182
+ **Squash specific commits:**
183
+
184
+ ```bash
185
+ but squash c3 c4 c5 # Squash these three into one
186
+ ```
187
+
188
+ **Squash a range:**
189
+
190
+ ```bash
191
+ but squash c3..c5 # Squash from c3 to c5
192
+ ```
193
+
194
+ After squashing, update the message:
195
+
196
+ ```bash
197
+ but reword c1 -m "Implement feature with full test suite"
198
+ ```
199
+
200
+ **In git, this would require:** `git rebase -i` with pick/squash commands, conflict resolution, and editor juggling.
201
+
202
+ ---
203
+
204
+ ## Auto-Amending with Absorb
205
+
206
+ This is GitButler's killer feature.
207
+
208
+ ### The Scenario
209
+
210
+ You fix a bug in a function, but the fix should go into the original commit that added that function — not as a new "fix typo" commit.
211
+
212
+ ### The Solution
213
+
214
+ ```bash
215
+ # 1. Edit the file, then check status
216
+ but status --json -f
217
+ # Shows: a1 M file.py [LOCKED] abc123 ← Detected dependency!
218
+
219
+ # 2. Preview what absorb would do
220
+ but absorb a1 --dry-run
221
+
222
+ # 3. Auto-amend to the correct commit
223
+ but absorb a1
224
+ ```
225
+
226
+ GitButler automatically:
227
+ 1. Analyzes which lines changed
228
+ 2. Finds the commit that introduced them
229
+ 3. Amends the change into that commit
230
+ 4. Rebases all dependent commits
231
+
232
+ ### Targeted vs blanket absorb
233
+
234
+ ```bash
235
+ but absorb a1 # Absorb specific file (RECOMMENDED)
236
+ but absorb bu # Absorb all changes staged to branch bu
237
+ but absorb # Absorb EVERYTHING (use with caution in multi-agent setups)
238
+ ```
239
+
240
+ **In git, this would require:** `git stash` → `git rebase -i` → mark commit for edit → `git stash pop` → `git add` → `git commit --amend` → `git rebase --continue`
241
+
242
+ With GitButler: just `but absorb a1`.
243
+
244
+ ---
245
+
246
+ ## Working on Multiple Features
247
+
248
+ ### The Problem
249
+
250
+ You need to work on an API endpoint AND fix a UI bug, but don't want to switch branches.
251
+
252
+ ### The Solution: Parallel Branches
253
+
254
+ ```bash
255
+ # 1. Create two branches
256
+ but branch new feat/api-endpoint
257
+ but branch new fix/button-styling
258
+
259
+ # 2. Edit files for both features (in the same working directory!)
260
+
261
+ # 3. Check status to get file IDs
262
+ but status --json -f
263
+ # a1 M api/users.js
264
+ # a2 M components/Button.tsx
265
+
266
+ # 4. Commit each file to the right branch
267
+ but commit feat/api-endpoint -m "Add user endpoint" --changes a1
268
+ but commit fix/button-styling -m "Fix button hover state" --changes a2
269
+
270
+ # 5. Push and create PRs independently
271
+ but pr new feat/api-endpoint -t
272
+ but pr new fix/button-styling -t
273
+ ```
274
+
275
+ **No context switching!** Both branches are active simultaneously.
276
+
277
+ **In git, this would require:** Stash, checkout, work, commit, checkout back, stash pop, repeat.
278
+
279
+ ---
280
+
281
+ ## Stacked Branches
282
+
283
+ ### When to Use
284
+
285
+ When Feature B depends on Feature A (e.g., user profile page needs authentication).
286
+
287
+ ### The Solution
288
+
289
+ ```bash
290
+ # 1. Create base branch
291
+ but branch new feat/authentication
292
+
293
+ # 2. Implement auth and commit
294
+ but commit feat/authentication -m "Add JWT authentication" --changes a1,a2
295
+
296
+ # 3. Create stacked branch anchored on auth
297
+ but branch new feat/user-profile -a feat/authentication
298
+
299
+ # 4. Implement profile (depends on auth code)
300
+ but commit feat/user-profile -m "Add user profile page" --changes a3
301
+
302
+ # 5. Push both
303
+ but push
304
+ ```
305
+
306
+ **Result:** Two PRs where user-profile depends on authentication. GitHub shows the dependency.
307
+
308
+ ### Parallel vs Stacked — when to use which
309
+
310
+ | Use Parallel | Use Stacked |
311
+ |---|---|
312
+ | Tasks don't depend on each other | Feature B needs code from Feature A |
313
+ | Can be merged independently | Must merge in order |
314
+ | API endpoint + unrelated bug fix | Auth → Profile → Settings |
315
+
316
+ ---
317
+
318
+ ## Undo and Recovery
319
+
320
+ ### Quick Undo (one step back)
321
+
322
+ ```bash
323
+ but undo # Reverts the last operation
324
+ ```
325
+
326
+ Works for: commits, squashes, absorbs, branch operations, file movements.
327
+
328
+ ### Time Travel (go back further)
329
+
330
+ ```bash
331
+ # View all operations
332
+ but oplog
333
+
334
+ # Output:
335
+ # s5 [SQUASH] SquashCommit
336
+ # s4 [CREATE] CreateCommit
337
+ # s3 [MOVE_HUNK] MoveHunk
338
+
339
+ # Restore to any point
340
+ but oplog restore s4
341
+ ```
342
+
343
+ Even undos are tracked. You can undo an undo.
344
+
345
+ ### Create Safety Checkpoints
346
+
347
+ Before risky operations:
348
+
349
+ ```bash
350
+ but oplog snapshot -m "before-major-refactor"
351
+ ```
352
+
353
+ **When to use `undo` vs `restore`:**
354
+ - **`but undo`**: Last operation went wrong. Quick single-step rollback.
355
+ - **`but oplog restore`**: Need to go back multiple operations or to a named checkpoint.
356
+
357
+ ---
358
+
359
+ ## Conflict Resolution
360
+
361
+ After `but pull`, some commits may have conflicts.
362
+
363
+ ### The Workflow
364
+
365
+ ```bash
366
+ # 1. Status shows conflicted commits
367
+ but status --json
368
+ # c3: Add validation (CONFLICTED)
369
+
370
+ # 2. Enter resolution mode
371
+ but resolve c3
372
+
373
+ # 3. Fix conflicts in files (remove <<< === >>> markers)
374
+
375
+ # 4. Check progress
376
+ but resolve status
377
+
378
+ # 5. Finalize
379
+ but resolve finish
380
+ ```
381
+
382
+ **During resolution:** You're in a special mode. Other GitButler operations are limited until you finish or cancel.
383
+
384
+ ```bash
385
+ but resolve cancel # Abort resolution, return to workspace
386
+ ```
387
+
388
+ ---
389
+
390
+ ## Creating Pull Requests
391
+
392
+ ```bash
393
+ # Auto-pushes and creates PR (recommended)
394
+ but pr new feat/my-feature -t
395
+
396
+ # With custom title/description
397
+ but pr new feat/my-feature -m "Add user dashboard
398
+
399
+ Implements the main dashboard with widgets and charts."
400
+
401
+ # From file (first line = title, rest = description)
402
+ but pr new feat/my-feature -F pr_message.txt
403
+ ```
404
+
405
+ **Key:** `but pr new` automatically pushes the branch. No need to `but push` first.
406
+
407
+ ---
408
+
409
+ ## Post-Merge Cleanup
410
+
411
+ After a PR is squash-merged on GitHub:
412
+
413
+ ```bash
414
+ # 1. MUST unapply BEFORE pull (prevents orphan branch errors)
415
+ but unapply feat/my-feature
416
+
417
+ # 2. Pull merged changes
418
+ but pull
419
+ ```
420
+
421
+ **Critical:** If you `but pull` before unapplying the merged branch, GitButler errors with orphan branch conflicts. Always unapply first.
422
+
423
+ ---
424
+
425
+ ## Tips and Gotchas
426
+
427
+ ### 1. Always refresh IDs
428
+
429
+ IDs (`a1`, `bu`, `c3`) change after every operation. Run `but status --json` before using them.
430
+
431
+ ### 2. Use `--json` for automation
432
+
433
+ All commands support `--json` for structured output. Always use it when scripting or running as an agent.
434
+
435
+ ### 3. Use `--changes` for safe commits
436
+
437
+ Never commit without `--changes` in multi-agent environments. Without it, you may commit other agents' work.
438
+
439
+ ### 4. Don't mix git and but writes
440
+
441
+ `git commit`, `git checkout`, `git push` can corrupt virtual branch state. Use `but` equivalents. Read-only git commands (`git log`, `git diff`, `git blame`) are fine.
442
+
443
+ ### 5. Commit early and often
444
+
445
+ GitButler makes editing history trivial. Small atomic commits are better than large uncommitted changes — you can always `squash`, `reword`, or `absorb` later.
446
+
447
+ ### 6. Preview before doing
448
+
449
+ ```bash
450
+ but absorb a1 --dry-run # See where file would be absorbed
451
+ but push --dry-run # See what would be pushed
452
+ ```
453
+
454
+ ### 7. The workspace commit
455
+
456
+ You'll see a "GitButler Workspace Commit" in `git log`. This is an internal placeholder — ignore it.
457
+
458
+ ### 8. Post-merge: always unapply first
459
+
460
+ ```bash
461
+ but unapply <merged-branch> # THEN
462
+ but pull # NOT the other way around
463
+ ```
464
+
465
+ ---
466
+
467
+ ## Summary: Why Use But?
468
+
469
+ | Task | Git Complexity | But Simplicity |
470
+ |------|---------------|----------------|
471
+ | Fix old commit message | `rebase -i`, edit, continue | `but reword` |
472
+ | Squash commits | `rebase -i`, pick/squash, conflicts | `but squash` |
473
+ | Amend to old commit | stash, rebase, edit, pop, amend, continue | `but absorb` |
474
+ | Undo anything | Complex/impossible | `but undo` or `but restore` |
475
+ | Multiple features | Stash, checkout, work, checkout, pop | Virtual branches |
476
+ | Targeted commit | `git add -p` | `but commit --changes` |
477
+ | Create PR | push, open browser, fill form | `but pr new -t` |
478
+
479
+ ---
480
+
481
+ ## Next Steps
482
+
483
+ - **Quick lookup:** See `references/cheatsheet.md` for a one-page command reference
484
+ - **Deep dive:** See `references/concepts.md` for the workspace model and philosophy
485
+ - **Real workflows:** See `references/examples.md` for 11 production scenarios
486
+ - **Full API:** See `references/reference.md` for every command and flag