You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .github/copilot-instructions.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -17,7 +17,7 @@ No Makefile, no code generation, no external linter config. Standard Go toolchai
17
17
18
18
-`cmd/`: One Cobra command per file. Each exports `<Name>Cmd(cfg *config.Config)` with logic in `run<Name>()`.
19
19
-`internal/git/`: `Ops` interface (52 methods) wrapping git CLI. `MockOps` for tests. Package-level functions delegate to swappable `ops` variable.
20
-
-`internal/github/`: `ClientOps` interface (13 methods) for GitHub API. `MockClient` for tests. Stack operations use the public Stacks REST API (`/repos/{owner}/{repo}/stacks`).
20
+
-`internal/github/`: `ClientOps` interface (18 methods) for GitHub API. `MockClient` for tests. Stack operations use the public Stacks REST API (`/repos/{owner}/{repo}/stacks`); merges use the async merge API (`/repos/{owner}/{repo}/pulls/{n}/merge-async`), with `BaseBranchPolicy` (GraphQL) gating merge-queue branches.
21
21
-`internal/config/`: `Config` struct passed to all commands. Holds I/O, colors, and test hooks (`SelectFn`, `ConfirmFn`, `InputFn`, `GitHubClientOverride`).
22
22
-`internal/stack/`: Stack file (`.git/gh-stack`, JSON) management with file locking.
@@ -109,7 +109,7 @@ if errors.As(err, &exitErr) { ... }
109
109
### Key interfaces
110
110
111
111
-**`git.Ops`** (`internal/git/gitops.go`): 52 methods wrapping git CLI calls. The production implementation uses `cli/go-gh`'s `client.Command()` via `run()` and `runSilent()` helpers. Package-level functions (e.g., `git.CurrentBranch()`) delegate to a swappable package-level `ops` variable.
112
-
-**`github.ClientOps`** (`internal/github/client_interface.go`): 13 methods for GitHub API (PRs, stacks). Stack operations use the public Stacks REST API (`/repos/{owner}/{repo}/stacks`): `ListStacks`, `FindStackForPR`, `GetStack`, `CreateStack`, `AddToStack` (delta append), `Unstack`. Injected via `cfg.GitHubClientOverride` in tests.
112
+
-**`github.ClientOps`** (`internal/github/client_interface.go`): 18 methods for GitHub API (PRs, stacks, merges). Stack operations use the public Stacks REST API (`/repos/{owner}/{repo}/stacks`): `ListStacks`, `FindStackForPR`, `GetStack`, `CreateStack`, `AddToStack` (delta append), `Unstack`. Async stack merges use `RepoMergeConfig` (GraphQL allowed methods + viewer default), `MergeStackAsync`, and `GetAsyncMergeResult` (`/repos/{owner}/{repo}/pulls/{n}/merge-async`); `BaseBranchPolicy` (GraphQL) reports whether the base branch requires a merge queue (unsupported). Injected via `cfg.GitHubClientOverride` in tests.
113
113
-**`config.Config`** (`internal/config/config.go`): Central configuration passed to all commands. Holds I/O streams, color functions, and test hook fields (`SelectFn`, `ConfirmFn`, `InputFn`, `RepoOverride`).
gh stack link --base develop --open feat-a feat-b feat-c
440
440
```
441
441
442
+
### `gh stack merge`
443
+
444
+
Merge one or multiple stacked PRs at once.
445
+
446
+
```
447
+
gh stack merge [<stack-number> | <pr-number>]
448
+
```
449
+
450
+
All members of the stack up to and including your chosen pull request are merged into the base branch in a single, all-or-nothing operation: if any PR can't be merged, none are.
451
+
452
+
With no argument, the current active local stack is used. Pass a stack number to merge a stack you don't have checked out (a purely remote operation), or a pull request number to merge directly up to that PR.
453
+
454
+
In an interactive terminal, a short wizard walks you through three steps — choose which PRs to merge, pick the merge method, and confirm. In a non-interactive terminal, or with `--yes`, the whole stack (or everything up to the given PR) is merged without prompting, using your last-used merge method unless one is specified.
455
+
456
+
Only basic pull request state is checked before merging (open and not a draft); GitHub evaluates branch protection and repository rules when the merge runs, so any such failure is reported back to you. **Admin bypass is not supported** for stacked PR merges at this time.
457
+
458
+
Note that this command does not work with merge queues. If the stack's base branch uses a merge queue, use `gh pr merge` instead.
459
+
460
+
| Flag | Description |
461
+
|------|-------------|
462
+
|`--merge-method <method>`| Merge method to use: `merge`, `squash`, or `rebase`|
463
+
|`--merge` / `--squash` / `--rebase`| Shorthands for the corresponding merge method |
464
+
|`-y, --yes`| Merge without prompting for confirmation |
465
+
466
+
**Examples:**
467
+
468
+
```sh
469
+
# Merge the current stack (interactive picker)
470
+
gh stack merge
471
+
472
+
# Merge a stack you don't have checked out, by stack number
473
+
gh stack merge 7
474
+
475
+
# Merge everything up to and including PR #42
476
+
gh stack merge 42
477
+
478
+
# Merge the whole current stack without prompting, squashing
Copy file name to clipboardExpand all lines: docs/src/content/docs/guides/workflows.md
+30-1Lines changed: 30 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -33,7 +33,10 @@ gh stack rebase
33
33
# 7. Push the updated branches
34
34
gh stack push
35
35
36
-
# 8. Sync upstream changes as PRs get merged
36
+
# 8. Land the stack once it's approved (merges bottom to top, atomically)
37
+
gh stack merge
38
+
39
+
# 9. Sync upstream changes as PRs get merged
37
40
gh stack sync
38
41
```
39
42
@@ -120,6 +123,32 @@ gh stack push
120
123
121
124
The rebase ensures all branches above the changed one pick up the fixes. `gh stack push` uses `--force-with-lease` to safely update the rebased branches.
122
125
126
+
## Merging Your Stack
127
+
128
+
When your stack is approved, land it with `gh stack merge`. Regular `gh pr merge` doesn't work with stacked PRs — `gh stack merge` uses GitHub's atomic stack merge, which merges every PR up to and including your chosen one in a single, all-or-nothing operation. If any PR can't be merged, none are.
129
+
130
+
```sh
131
+
# Merge the current stack (interactive picker for how far up to merge)
132
+
gh stack merge
133
+
134
+
# Merge everything up to and including a specific PR
135
+
gh stack merge 42
136
+
137
+
# Merge a stack you don't have checked out, by its stack number
138
+
gh stack merge 7
139
+
140
+
# Merge without prompting for confirmation, specifying the merge method
141
+
gh stack merge --yes --squash
142
+
```
143
+
144
+
In an interactive terminal, a short wizard lets you choose how far up the stack to merge, pick the merge method (only the ones your repository allows, defaulting to your last-used method), and confirm — then shows live progress. In a non-interactive terminal, or with `--yes`, the whole stack (or everything up to the given PR) is merged without prompting. After merging, run `gh stack sync` to update your local branches.
145
+
146
+
The exception is a trunk that uses a merge queue: `gh stack merge` merges directly rather than through the queue, so it isn't supported there. Use `gh pr merge` or the GitHub web UI to merge through the queue instead.
147
+
148
+
:::note[Admin bypass not supported]
149
+
Stack merges currently do not support admin bypass merging.
150
+
:::
151
+
123
152
## Syncing After Merges
124
153
125
154
When a PR at the bottom of the stack is merged on GitHub, use `gh stack sync` to update your local state:
All members of the stack up to and including your chosen pull request are merged into the base branch in a single, all-or-nothing operation: if any PR can't be merged, none are.
472
+
473
+
With no argument, the current active local stack is used. Pass a stack number to merge a stack you don't have checked out (a purely remote operation), or a pull request number to merge directly up to that PR.
474
+
475
+
In an interactive terminal, a short wizard walks you through three steps — choose which PRs to merge, pick the merge method, and confirm. In a non-interactive terminal, or with `--yes`, the whole stack (or everything up to the given PR) is merged without prompting, using your last-used merge method unless one is specified.
476
+
477
+
Only basic pull request state is checked before merging (open and not a draft); GitHub evaluates branch protection and repository rules when the merge runs, so any such failure is reported back to you. **Admin bypass is not supported** for stacked PR merges at this time.
478
+
479
+
Note that this command does not work with merge queues. If the stack's base branch uses a merge queue, use `gh pr merge` instead.
480
+
481
+
| Flag | Description |
482
+
|------|-------------|
483
+
|`--merge-method <method>`| Merge method to use: `merge`, `squash`, or `rebase`|
484
+
|`--merge` / `--squash` / `--rebase`| Shorthands for the corresponding merge method |
485
+
|`-y, --yes`| Merge without prompting for confirmation |
486
+
487
+
**Examples:**
488
+
489
+
```sh
490
+
# Merge the current stack (interactive picker)
491
+
gh stack merge
492
+
493
+
# Merge a stack you don't have checked out, by stack number
494
+
gh stack merge 7
495
+
496
+
# Merge everything up to and including PR #42
497
+
gh stack merge 42
498
+
499
+
# Merge the whole current stack without prompting, squashing
500
+
gh stack merge --yes --squash
501
+
```
502
+
503
+
---
504
+
463
505
## Navigation
464
506
465
507
Move between branches in the current stack without having to remember branch names. The **bottom** of the stack is the branch closest to the trunk, and the **top** is furthest from it. `up` moves away from trunk; `down` moves toward it.
7.**Use standard `git add` and `git commit` for staging and committing.** This gives you full control over which changes go into each branch. The `-Am` shortcut is available but should not be the default approach—stacked PRs are most effective when each branch contains a deliberate, logical set of changes.
62
62
8.**Navigate down the stack when you need to change a lower layer.** If you're working on a frontend branch and realize you need API changes, don't hack around it at the current layer. Navigate to the appropriate branch (`gh stack down`, `gh stack checkout`, or `gh stack bottom`), make and commit the changes there, run `gh stack rebase --upstack`, then navigate back up to continue.
63
63
9.**Use `gh stack link` for external tool workflows.** When branches are managed by an external tool (jj, Sapling, etc.), use `gh stack link branch-a branch-b`. `link` does not rely on local tracking state and is intended for API-driven PR and stack management. Provide at least two branches/PRs to create or update a stack, or a stack number followed by the new branches/PRs to append them to the top of an existing stack (e.g. `gh stack link 7 branch-c`).
64
+
10.**Use `gh stack merge --yes` to merge stacked PRs.**`gh pr merge` does not work with stacked PRs. In a non-interactive terminal `gh stack merge` runs without prompting and merges the entire stack (bottom to top) atomically; pass `--yes` to be explicit. Scope the merge by passing a pull request number (`gh stack merge 42 --yes` merges everything up to and including PR #42) or a stack number (`gh stack merge 7 --yes`, which needs no local checkout). Choose the method with `--squash`, `--rebase`, `--merge`, or `--merge-method <method>`; without one, the last-used method is used. The merge is all-or-nothing — if any PR can't be merged, none are, and the failure reason is reported. Only basic pull request state is checked before merging (open and not a draft); admin bypass is not supported for stacked PR merges. This command does not work with merge queues — if the base branch uses a merge queue, the command exits with an error, so use `gh pr merge` instead.
64
65
65
66
**Never do any of the following — each triggers an interactive prompt or TUI that will hang:**
66
67
- ❌ `gh stack view` or `gh stack view --short` — always use `gh stack view --json`
@@ -164,6 +165,10 @@ Small, incidental fixes (e.g., fixing a typo you noticed) can go in the current
164
165
| Check out by branch (local only) |`gh stack checkout feature-auth`|
165
166
| Tear down the current stack to restructure it |`gh stack unstack`|
166
167
| Tear down a specific stack by number |`gh stack unstack 7`|
168
+
| Merge the whole current stack |`gh stack merge --yes`|
169
+
| Merge a stack by number |`gh stack merge 7 --yes`|
170
+
| Merge up to a specific PR |`gh stack merge 42 --yes`|
171
+
| Merge with a specific method |`gh stack merge --yes --squash`|
0 commit comments