dubstack 0.5.0 → 0.6.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/README.md +355 -204
- package/dist/index.js +956 -114
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,362 +1,513 @@
|
|
|
1
1
|
# DubStack
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
DubStack (`dub`) is a local-first CLI for stacked branch workflows.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
It is designed for the Graphite mental model: small, dependent PRs that are easy to review, update, and rebase.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Why DubStack
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Large PRs are hard to review and painful to keep up to date.
|
|
10
|
+
|
|
11
|
+
Stacked branches let you split work into focused layers:
|
|
12
|
+
|
|
13
|
+
```text
|
|
10
14
|
(main)
|
|
11
|
-
└─ feat/
|
|
12
|
-
└─ feat/
|
|
13
|
-
└─ feat/
|
|
15
|
+
└─ feat/auth-types
|
|
16
|
+
└─ feat/auth-login
|
|
17
|
+
└─ feat/auth-tests
|
|
14
18
|
```
|
|
15
19
|
|
|
16
|
-
When
|
|
20
|
+
When a lower branch changes, `dub restack` propagates it upstack.
|
|
17
21
|
|
|
18
22
|
## Install
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
### Homebrew (recommended)
|
|
21
25
|
|
|
22
26
|
```bash
|
|
23
27
|
brew tap wiseiodev/dubstack
|
|
24
28
|
brew install dubstack
|
|
25
29
|
```
|
|
26
30
|
|
|
27
|
-
|
|
31
|
+
Update:
|
|
28
32
|
|
|
29
33
|
```bash
|
|
30
34
|
brew upgrade dubstack
|
|
31
35
|
```
|
|
32
36
|
|
|
33
|
-
|
|
37
|
+
### npm
|
|
34
38
|
|
|
35
39
|
```bash
|
|
36
40
|
npm install -g dubstack
|
|
37
41
|
```
|
|
38
42
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
> Requires **Node ≥ 22** and **pnpm**.
|
|
43
|
+
### From source
|
|
42
44
|
|
|
43
45
|
```bash
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
git clone https://github.com/wiseiodev/dubstack.git
|
|
47
|
+
cd dubstack
|
|
46
48
|
pnpm install
|
|
47
|
-
|
|
48
|
-
# Link globally so `dub` is available everywhere
|
|
49
49
|
pnpm build
|
|
50
50
|
pnpm link --global
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
+
## Graphite Mental Model
|
|
54
|
+
|
|
55
|
+
If you have `gt` muscle memory, use this as a fast map:
|
|
56
|
+
|
|
57
|
+
| Graphite (`gt`) | DubStack (`dub`) |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `gt create` | `dub create` |
|
|
60
|
+
| `gt modify` | `dub modify` or `dub m` |
|
|
61
|
+
| `gt submit` / `gt ss` | `dub submit` / `dub ss` |
|
|
62
|
+
| `gt sync` | `dub sync` |
|
|
63
|
+
| `gt checkout` / `gt co` | `dub checkout` / `dub co` |
|
|
64
|
+
| `gt log` / `gt ls` | `dub log` / `dub ls` |
|
|
65
|
+
| `gt up` / `gt down` | `dub up` / `dub down` |
|
|
66
|
+
| `gt top` / `gt bottom` | `dub top` / `dub bottom` |
|
|
67
|
+
| `gt info` | `dub info` |
|
|
68
|
+
| `gt pr` | `dub pr` |
|
|
69
|
+
| `gt restack` | `dub restack` |
|
|
70
|
+
| `gt continue` | `dub continue` |
|
|
71
|
+
| `gt abort` | `dub abort` |
|
|
72
|
+
| `gt track --parent` | `dub track --parent` |
|
|
73
|
+
| `gt untrack` | `dub untrack` |
|
|
74
|
+
| `gt delete` | `dub delete` |
|
|
75
|
+
| `gt parent` | `dub parent` |
|
|
76
|
+
| `gt children` | `dub children` |
|
|
77
|
+
| `gt trunk` | `dub trunk` |
|
|
78
|
+
| `gt undo` | `dub undo` |
|
|
79
|
+
|
|
53
80
|
## Quick Start
|
|
54
81
|
|
|
55
82
|
```bash
|
|
56
|
-
# 1
|
|
57
|
-
cd my-project
|
|
58
|
-
dub init
|
|
59
|
-
|
|
60
|
-
# 2. Start stacking branches
|
|
83
|
+
# 1) Start from trunk
|
|
61
84
|
git checkout main
|
|
62
|
-
|
|
63
|
-
# hack hack hack, commit...
|
|
64
|
-
|
|
65
|
-
dub create feat/api-endpoint
|
|
66
|
-
# hack hack hack, commit...
|
|
85
|
+
git pull
|
|
67
86
|
|
|
68
|
-
|
|
69
|
-
#
|
|
87
|
+
# 2) Create stacked branches
|
|
88
|
+
# Create + stage all + commit
|
|
89
|
+
dub create feat/auth-types -am "feat: add auth types"
|
|
90
|
+
dub create feat/auth-login -am "feat: add login flow"
|
|
91
|
+
dub create feat/auth-tests -am "test: add auth tests"
|
|
70
92
|
|
|
71
|
-
# 3
|
|
93
|
+
# 3) View stack
|
|
72
94
|
dub log
|
|
73
95
|
|
|
74
|
-
# 4
|
|
75
|
-
|
|
76
|
-
dub restack
|
|
77
|
-
|
|
78
|
-
# 4b. Sync local stack state with remote branches
|
|
79
|
-
dub sync
|
|
96
|
+
# 4) Submit stack PRs
|
|
97
|
+
dub ss
|
|
80
98
|
|
|
81
|
-
# 5
|
|
82
|
-
|
|
83
|
-
dub undo
|
|
99
|
+
# 5) Open PR for current branch
|
|
100
|
+
dub pr
|
|
84
101
|
```
|
|
85
102
|
|
|
86
|
-
|
|
103
|
+
For a more detailed walkthrough, see [`QUICKSTART.md`](./QUICKSTART.md).
|
|
87
104
|
|
|
88
|
-
|
|
105
|
+
## Command Reference
|
|
89
106
|
|
|
90
|
-
|
|
107
|
+
### `dub init`
|
|
91
108
|
|
|
92
|
-
|
|
93
|
-
# Install all skills
|
|
94
|
-
dub skills add
|
|
109
|
+
Initialize DubStack state in the current git repository.
|
|
95
110
|
|
|
96
|
-
|
|
97
|
-
dub
|
|
111
|
+
```bash
|
|
112
|
+
dub init
|
|
98
113
|
```
|
|
99
114
|
|
|
100
|
-
|
|
115
|
+
Notes:
|
|
116
|
+
- `dub create` auto-initializes state if needed.
|
|
117
|
+
- Running `dub init` manually is still useful for explicit setup.
|
|
118
|
+
|
|
119
|
+
### `dub create <branch>`
|
|
120
|
+
|
|
121
|
+
Create a branch stacked on top of the current branch.
|
|
101
122
|
|
|
102
123
|
```bash
|
|
103
|
-
#
|
|
104
|
-
|
|
124
|
+
# branch only
|
|
125
|
+
dub create feat/my-change
|
|
105
126
|
|
|
106
|
-
#
|
|
107
|
-
|
|
127
|
+
# create + commit staged changes
|
|
128
|
+
dub create feat/my-change -m "feat: ..."
|
|
129
|
+
|
|
130
|
+
# stage all + create + commit
|
|
131
|
+
dub create feat/my-change -am "feat: ..."
|
|
132
|
+
|
|
133
|
+
# stage tracked-file updates + create + commit
|
|
134
|
+
dub create feat/my-change -um "feat: ..."
|
|
135
|
+
|
|
136
|
+
# interactive hunk staging + create + commit
|
|
137
|
+
dub create feat/my-change -pm "feat: ..."
|
|
108
138
|
```
|
|
109
139
|
|
|
110
|
-
|
|
140
|
+
Flags:
|
|
141
|
+
- `-m, --message <message>`: commit message
|
|
142
|
+
- `-a, --all`: stage all changes before commit (requires `-m`)
|
|
143
|
+
- `-u, --update`: stage tracked-file updates before commit (requires `-m`)
|
|
144
|
+
- `-p, --patch`: select hunks interactively before commit (requires `-m`)
|
|
111
145
|
|
|
112
|
-
### `dub
|
|
146
|
+
### `dub modify` / `dub m`
|
|
113
147
|
|
|
114
|
-
|
|
148
|
+
Amend or create commits on the current branch, then restack descendants.
|
|
115
149
|
|
|
116
150
|
```bash
|
|
117
|
-
|
|
118
|
-
|
|
151
|
+
# amend current commit
|
|
152
|
+
dub modify
|
|
119
153
|
|
|
120
|
-
|
|
121
|
-
-
|
|
122
|
-
- **Idempotent** — safe to run multiple times
|
|
154
|
+
# create a new commit
|
|
155
|
+
dub modify -c -m "fix: ..."
|
|
123
156
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
157
|
+
# interactive staging
|
|
158
|
+
dub modify -p
|
|
159
|
+
|
|
160
|
+
# stage all tracked updates
|
|
161
|
+
dub modify -u
|
|
162
|
+
|
|
163
|
+
# show staged diff before modify
|
|
164
|
+
dub modify -v
|
|
165
|
+
|
|
166
|
+
# show staged + unstaged diff before modify
|
|
167
|
+
dub modify -vv
|
|
168
|
+
|
|
169
|
+
# interactive rebase of this branch's commits
|
|
170
|
+
dub modify --interactive-rebase
|
|
127
171
|
```
|
|
128
172
|
|
|
129
|
-
|
|
173
|
+
Flags:
|
|
174
|
+
- `-a, --all`
|
|
175
|
+
- `-u, --update`
|
|
176
|
+
- `-p, --patch`
|
|
177
|
+
- `-c, --commit`
|
|
178
|
+
- `-e, --edit`
|
|
179
|
+
- `-m, --message <message>` (repeatable)
|
|
180
|
+
- `-v, --verbose` (repeatable)
|
|
181
|
+
- `--interactive-rebase`
|
|
130
182
|
|
|
131
|
-
### `dub
|
|
183
|
+
### `dub checkout` / `dub co`
|
|
132
184
|
|
|
133
|
-
|
|
185
|
+
Checkout a branch directly or use interactive search.
|
|
134
186
|
|
|
135
187
|
```bash
|
|
136
|
-
#
|
|
137
|
-
dub
|
|
188
|
+
# checkout explicit branch
|
|
189
|
+
dub checkout feat/auth-login
|
|
138
190
|
|
|
139
|
-
#
|
|
140
|
-
dub
|
|
141
|
-
```
|
|
191
|
+
# interactive picker
|
|
192
|
+
dub checkout
|
|
142
193
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
- Auto-creates a new stack if the parent isn't already tracked
|
|
146
|
-
- Saves an undo snapshot before any mutation
|
|
194
|
+
# checkout trunk for current tracked stack
|
|
195
|
+
dub checkout --trunk
|
|
147
196
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|---|---|
|
|
151
|
-
| Not initialized | `DubStack is not initialized. Run 'dub init' first.` |
|
|
152
|
-
| Branch already exists | `Branch '<name>' already exists.` |
|
|
153
|
-
| Detached HEAD | `HEAD is detached. Check out a branch first.` |
|
|
197
|
+
# interactive picker including non-tracked local branches
|
|
198
|
+
dub checkout --show-untracked
|
|
154
199
|
|
|
155
|
-
|
|
200
|
+
# interactive picker scoped to current stack
|
|
201
|
+
dub checkout --stack
|
|
202
|
+
```
|
|
156
203
|
|
|
157
|
-
### `dub log`
|
|
204
|
+
### `dub log` / `dub ls` / `dub l`
|
|
158
205
|
|
|
159
|
-
|
|
206
|
+
Render tracked stacks as an ASCII tree.
|
|
160
207
|
|
|
161
208
|
```bash
|
|
162
209
|
dub log
|
|
210
|
+
dub ls
|
|
211
|
+
dub l
|
|
212
|
+
|
|
213
|
+
# show only current stack
|
|
214
|
+
dub log --stack
|
|
215
|
+
|
|
216
|
+
# show all stacks explicitly
|
|
217
|
+
dub log --all
|
|
218
|
+
|
|
219
|
+
# reverse branch ordering for quick top-down scan
|
|
220
|
+
dub log --reverse
|
|
163
221
|
```
|
|
164
222
|
|
|
165
|
-
|
|
223
|
+
### Navigation: `dub up`, `dub down`, `dub top`, `dub bottom`
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
# move one branch upstack
|
|
227
|
+
dub up
|
|
228
|
+
|
|
229
|
+
# move multiple levels upstack
|
|
230
|
+
dub up 2
|
|
231
|
+
# or: dub up --steps 2
|
|
232
|
+
|
|
233
|
+
# move downstack
|
|
234
|
+
dub down
|
|
235
|
+
dub down 2
|
|
236
|
+
|
|
237
|
+
# jump to tip branch in current path
|
|
238
|
+
dub top
|
|
166
239
|
|
|
240
|
+
# jump to first branch above root
|
|
241
|
+
dub bottom
|
|
167
242
|
```
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
243
|
+
|
|
244
|
+
### `dub info` and `dub branch info`
|
|
245
|
+
|
|
246
|
+
Show tracked metadata for a branch.
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
# current branch
|
|
250
|
+
dub info
|
|
251
|
+
|
|
252
|
+
# explicit branch
|
|
253
|
+
dub info feat/auth-login
|
|
254
|
+
|
|
255
|
+
# equivalent legacy style
|
|
256
|
+
dub branch info
|
|
173
257
|
```
|
|
174
258
|
|
|
175
|
-
|
|
176
|
-
- **Root branches** are shown in parentheses, e.g. `(main)`
|
|
177
|
-
- **Deleted branches** still tracked in state show `⚠ (missing)`
|
|
178
|
-
- Multiple stacks are separated by blank lines
|
|
259
|
+
### Orientation: `dub parent`, `dub children`, `dub trunk`
|
|
179
260
|
|
|
180
|
-
|
|
261
|
+
Quickly inspect where the current branch sits in its tracked stack.
|
|
181
262
|
|
|
182
|
-
|
|
263
|
+
```bash
|
|
264
|
+
dub parent # direct parent of current branch
|
|
265
|
+
dub children # direct children
|
|
266
|
+
dub trunk # stack root/trunk branch
|
|
267
|
+
```
|
|
183
268
|
|
|
184
|
-
|
|
269
|
+
All three commands accept an optional branch argument:
|
|
185
270
|
|
|
186
271
|
```bash
|
|
187
|
-
dub
|
|
272
|
+
dub parent feat/auth-login
|
|
273
|
+
dub children feat/auth-types
|
|
274
|
+
dub trunk feat/auth-tests
|
|
188
275
|
```
|
|
189
276
|
|
|
190
|
-
|
|
277
|
+
If branch metadata is missing, these commands print a remediation path using `dub track`.
|
|
191
278
|
|
|
192
|
-
|
|
193
|
-
2. Walks the tree in topological order (parents first)
|
|
194
|
-
3. For each child branch, runs `git rebase --onto <parent_new_tip> <parent_old_tip> <child>`
|
|
195
|
-
4. Skips branches whose parent hasn't moved
|
|
196
|
-
5. Returns you to the branch you started on
|
|
279
|
+
### `dub track [branch] [--parent <branch>]`
|
|
197
280
|
|
|
198
|
-
|
|
281
|
+
Track an existing local branch or re-parent a tracked branch.
|
|
199
282
|
|
|
200
|
-
|
|
283
|
+
```bash
|
|
284
|
+
# track current branch
|
|
285
|
+
dub track
|
|
201
286
|
|
|
287
|
+
# track explicit branch
|
|
288
|
+
dub track feat/auth-login --parent feat/auth-types
|
|
289
|
+
|
|
290
|
+
# repair parent metadata
|
|
291
|
+
dub track feat/auth-login --parent main
|
|
202
292
|
```
|
|
203
|
-
⚠ Conflict while restacking 'feat/api-endpoint'
|
|
204
|
-
Resolve conflicts, stage changes, then run: dub restack --continue
|
|
205
|
-
```
|
|
206
293
|
|
|
207
|
-
|
|
294
|
+
Notes:
|
|
295
|
+
- If `--parent` is omitted, DubStack tries to infer a safe default.
|
|
296
|
+
- In interactive shells, DubStack prompts when parent choice is ambiguous.
|
|
297
|
+
- Re-parenting can require follow-up rebasing via `dub restack`.
|
|
298
|
+
|
|
299
|
+
### `dub untrack [branch] [--downstack]`
|
|
300
|
+
|
|
301
|
+
Remove branch metadata from DubStack without deleting local git branches.
|
|
208
302
|
|
|
209
303
|
```bash
|
|
210
|
-
#
|
|
211
|
-
|
|
212
|
-
|
|
304
|
+
# untrack current branch only
|
|
305
|
+
dub untrack
|
|
306
|
+
|
|
307
|
+
# untrack explicit branch and descendants
|
|
308
|
+
dub untrack feat/auth-login --downstack
|
|
213
309
|
```
|
|
214
310
|
|
|
215
|
-
|
|
311
|
+
Use this when branch exists locally but should no longer participate in stack operations.
|
|
312
|
+
|
|
313
|
+
### `dub delete [branch] [--upstack|--downstack] [--force] [--quiet]`
|
|
314
|
+
|
|
315
|
+
Delete local branches with stack-aware expansion and metadata repair.
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
# delete one branch (with confirmation)
|
|
319
|
+
dub delete feat/auth-login
|
|
320
|
+
|
|
321
|
+
# delete branch and descendants
|
|
322
|
+
dub delete feat/auth-login --upstack
|
|
216
323
|
|
|
217
|
-
|
|
324
|
+
# delete branch and ancestors toward trunk
|
|
325
|
+
dub delete feat/auth-login --downstack
|
|
218
326
|
|
|
327
|
+
# fully non-interactive destructive delete
|
|
328
|
+
dub delete feat/auth-login --upstack --force --quiet
|
|
219
329
|
```
|
|
220
|
-
✔ Stack is already up to date
|
|
221
330
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
331
|
+
Flags:
|
|
332
|
+
- `--upstack`: include descendants
|
|
333
|
+
- `--downstack`: include ancestors (excluding root)
|
|
334
|
+
- `-f, --force`: force delete unmerged branches
|
|
335
|
+
- `-q, --quiet`: skip confirmation prompt
|
|
336
|
+
|
|
337
|
+
### `dub continue` / `dub abort`
|
|
338
|
+
|
|
339
|
+
Unified recovery pair for interrupted restacks and rebases.
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
# continue active restack/rebase
|
|
343
|
+
dub continue
|
|
344
|
+
|
|
345
|
+
# abort active restack/rebase
|
|
346
|
+
dub abort
|
|
225
347
|
```
|
|
226
348
|
|
|
227
|
-
|
|
228
|
-
| Condition | Message |
|
|
229
|
-
|---|---|
|
|
230
|
-
| Uncommitted changes | `Working tree has uncommitted changes. Commit or stash them before restacking.` |
|
|
231
|
-
| Branch not in a stack | `Branch '<name>' is not part of any stack.` |
|
|
232
|
-
| Tracked branch deleted | `Branch '<name>' is tracked in state but no longer exists in git.` |
|
|
349
|
+
Use these when the CLI reports conflicts or an in-progress operation.
|
|
233
350
|
|
|
234
|
-
|
|
351
|
+
### `dub submit` / `dub ss`
|
|
235
352
|
|
|
236
|
-
|
|
353
|
+
Push stack branches and create or update PRs.
|
|
237
354
|
|
|
238
|
-
|
|
355
|
+
```bash
|
|
356
|
+
dub submit
|
|
357
|
+
dub ss
|
|
358
|
+
|
|
359
|
+
# preview only
|
|
360
|
+
dub submit --dry-run
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### `dub pr [branch-or-number]`
|
|
364
|
+
|
|
365
|
+
Open a PR in browser via `gh`.
|
|
239
366
|
|
|
240
367
|
```bash
|
|
241
|
-
|
|
368
|
+
# current branch PR
|
|
369
|
+
dub pr
|
|
370
|
+
|
|
371
|
+
# explicit branch / PR target
|
|
372
|
+
dub pr feat/auth-login
|
|
373
|
+
dub pr 123
|
|
242
374
|
```
|
|
243
375
|
|
|
244
|
-
|
|
376
|
+
### `dub sync`
|
|
377
|
+
|
|
378
|
+
Synchronize tracked branches with remote refs, then optionally restack.
|
|
245
379
|
|
|
246
380
|
```bash
|
|
247
|
-
#
|
|
381
|
+
# sync current stack
|
|
382
|
+
dub sync
|
|
383
|
+
|
|
384
|
+
# sync all tracked stacks
|
|
248
385
|
dub sync --all
|
|
249
386
|
|
|
250
|
-
#
|
|
387
|
+
# non-interactive mode
|
|
251
388
|
dub sync --no-interactive
|
|
252
389
|
|
|
253
|
-
#
|
|
390
|
+
# force destructive sync decisions
|
|
254
391
|
dub sync --force
|
|
255
392
|
|
|
256
|
-
#
|
|
393
|
+
# skip post-sync restack
|
|
257
394
|
dub sync --no-restack
|
|
258
395
|
```
|
|
259
396
|
|
|
260
|
-
Current behavior:
|
|
261
|
-
-
|
|
262
|
-
-
|
|
263
|
-
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
397
|
+
Current sync behavior includes:
|
|
398
|
+
- fetch tracked refs from `origin`
|
|
399
|
+
- attempt trunk fast-forward (or overwrite with `--force`)
|
|
400
|
+
- cleanup for merged/closed PR branches whose commits are confirmed in trunk
|
|
401
|
+
- reconcile local/remote divergence states per branch
|
|
402
|
+
- restack by default after sync
|
|
403
|
+
|
|
404
|
+
### `dub restack`
|
|
405
|
+
|
|
406
|
+
Rebase stack branches onto updated parents.
|
|
407
|
+
|
|
408
|
+
```bash
|
|
409
|
+
dub restack
|
|
410
|
+
|
|
411
|
+
# continue after resolving conflicts
|
|
412
|
+
dub restack --continue
|
|
413
|
+
```
|
|
274
414
|
|
|
275
415
|
### `dub undo`
|
|
276
416
|
|
|
277
|
-
|
|
417
|
+
Undo last `dub create` or `dub restack` operation.
|
|
278
418
|
|
|
279
419
|
```bash
|
|
280
420
|
dub undo
|
|
281
421
|
```
|
|
282
422
|
|
|
283
|
-
|
|
423
|
+
### `dub skills`
|
|
284
424
|
|
|
285
|
-
|
|
286
|
-
- **After `restack`:** Force-resets every rebased branch to its pre-rebase commit, restores state
|
|
425
|
+
Install or remove packaged agent skills.
|
|
287
426
|
|
|
288
|
-
|
|
427
|
+
```bash
|
|
428
|
+
# install all bundled skills
|
|
429
|
+
dub skills add
|
|
289
430
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
✔ Undid 'restack': Reset 3 branches to pre-restack state
|
|
293
|
-
```
|
|
431
|
+
# install one skill
|
|
432
|
+
dub skills add dubstack
|
|
294
433
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
434
|
+
# remove one skill
|
|
435
|
+
dub skills remove dub-flow
|
|
436
|
+
|
|
437
|
+
# preview without changing anything
|
|
438
|
+
dub skills add --dry-run
|
|
439
|
+
dub skills remove --dry-run
|
|
440
|
+
```
|
|
300
441
|
|
|
301
|
-
|
|
442
|
+
## Typical Workflows
|
|
302
443
|
|
|
303
|
-
|
|
444
|
+
### Add review feedback to a middle branch
|
|
304
445
|
|
|
305
446
|
```bash
|
|
306
|
-
#
|
|
307
|
-
|
|
308
|
-
dub create feat/data-layer
|
|
309
|
-
# write code, commit
|
|
447
|
+
# jump to branch needing edits
|
|
448
|
+
dub co feat/auth-login
|
|
310
449
|
|
|
311
|
-
|
|
312
|
-
|
|
450
|
+
# edit + amend + restack descendants
|
|
451
|
+
dub m -a -m "fix: address feedback"
|
|
313
452
|
|
|
314
|
-
|
|
315
|
-
|
|
453
|
+
# resubmit stack
|
|
454
|
+
dub ss
|
|
455
|
+
```
|
|
316
456
|
|
|
317
|
-
|
|
318
|
-
dub log
|
|
319
|
-
# (main)
|
|
320
|
-
# └─ feat/data-layer
|
|
321
|
-
# └─ feat/api-routes
|
|
322
|
-
# └─ feat/frontend (Current)
|
|
323
|
-
|
|
324
|
-
# Later: main gets updated, or you amend feat/data-layer
|
|
325
|
-
git checkout feat/data-layer
|
|
326
|
-
# amend your commits...
|
|
327
|
-
dub restack
|
|
328
|
-
# ✔ Restacked 2 branch(es)
|
|
329
|
-
# ↳ feat/api-routes
|
|
330
|
-
# ↳ feat/frontend
|
|
457
|
+
### Sync after trunk moves
|
|
331
458
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
459
|
+
```bash
|
|
460
|
+
git checkout main
|
|
461
|
+
git pull
|
|
462
|
+
dub sync
|
|
335
463
|
```
|
|
336
464
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
DubStack stores all state locally inside your git repo:
|
|
465
|
+
### Recover from restack conflict
|
|
340
466
|
|
|
467
|
+
```bash
|
|
468
|
+
dub restack
|
|
469
|
+
# resolve conflicts
|
|
470
|
+
git add <resolved-files>
|
|
471
|
+
dub restack --continue
|
|
341
472
|
```
|
|
473
|
+
|
|
474
|
+
## Troubleshooting
|
|
475
|
+
|
|
476
|
+
| Problem | What to do |
|
|
477
|
+
|---|---|
|
|
478
|
+
| `gh CLI not found` | Install GitHub CLI: https://cli.github.com |
|
|
479
|
+
| `Not authenticated with GitHub` | Run `gh auth login` |
|
|
480
|
+
| Branch not part of stack | Create via `dub create` or run from tracked branch |
|
|
481
|
+
| Restack conflict | Resolve files, `git add`, `dub restack --continue` |
|
|
482
|
+
| Rebase/restack interrupted | Use `dub continue` to resume, `dub abort` to cancel |
|
|
483
|
+
| Branch not tracked | Run `dub track <branch> --parent <parent>` |
|
|
484
|
+
| Need metadata-only removal | Use `dub untrack` (or `--downstack`) |
|
|
485
|
+
| Need stack-aware branch deletion | Use `dub delete` with `--upstack` / `--downstack` |
|
|
486
|
+
| Sync skipped branch | Re-run with `--interactive` or `--force` as appropriate |
|
|
487
|
+
| Wrong operation during create/restack | Use `dub undo` (single-level) |
|
|
488
|
+
|
|
489
|
+
## State Files
|
|
490
|
+
|
|
491
|
+
DubStack stores local state in your repo:
|
|
492
|
+
|
|
493
|
+
```text
|
|
342
494
|
.git/dubstack/
|
|
343
|
-
├── state.json
|
|
344
|
-
├── undo.json
|
|
345
|
-
└── restack-progress.json
|
|
495
|
+
├── state.json
|
|
496
|
+
├── undo.json
|
|
497
|
+
└── restack-progress.json
|
|
346
498
|
```
|
|
347
499
|
|
|
348
|
-
Nothing is pushed to your remote
|
|
500
|
+
Nothing is pushed to your remote from these files.
|
|
349
501
|
|
|
350
502
|
## Development
|
|
351
503
|
|
|
352
504
|
```bash
|
|
353
|
-
pnpm install
|
|
354
|
-
pnpm
|
|
355
|
-
pnpm
|
|
356
|
-
pnpm
|
|
357
|
-
pnpm
|
|
358
|
-
pnpm
|
|
359
|
-
pnpm checks:fix # auto-fix lint + format issues
|
|
505
|
+
pnpm install
|
|
506
|
+
pnpm test
|
|
507
|
+
pnpm typecheck
|
|
508
|
+
pnpm checks
|
|
509
|
+
pnpm checks:fix
|
|
510
|
+
pnpm build
|
|
360
511
|
```
|
|
361
512
|
|
|
362
513
|
## License
|