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.
- package/LICENSE +21 -0
- package/README.md +147 -0
- package/command/b-branch-commit.md +105 -0
- package/command/b-branch-gc.md +58 -0
- package/command/b-branch-pr.md +221 -0
- package/command/b-branch.md +88 -0
- package/dist/auto-update.d.ts +39 -0
- package/dist/auto-update.d.ts.map +1 -0
- package/dist/cli.d.ts +85 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/config.d.ts +36 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1731 -0
- package/dist/logger.d.ts +21 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/notify.d.ts +11 -0
- package/dist/notify.d.ts.map +1 -0
- package/dist/plugin.d.ts +21 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/reword.d.ts +104 -0
- package/dist/reword.d.ts.map +1 -0
- package/dist/state.d.ts +38 -0
- package/dist/state.d.ts.map +1 -0
- package/package.json +56 -0
- package/postinstall.mjs +10 -0
- package/skill/gitbutler/SKILL.md +275 -0
- package/skill/gitbutler/references/cheatsheet.md +271 -0
- package/skill/gitbutler/references/concepts.md +333 -0
- package/skill/gitbutler/references/examples.md +512 -0
- package/skill/gitbutler/references/reference.md +504 -0
- package/skill/gitbutler/references/tutorial.md +486 -0
|
@@ -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.
|