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
{{ message }}
Repository navigation
Commit 094328f
Browse filesBrowse the repository at this point in the historyBrowse files
1.**Always supply branch names as positional arguments** to `init`, `add`, and `checkout`. Running these commands without arguments triggers interactive prompts. Branch names are used exactly as given — a name is never prefixed or transformed, so `gh stack add refactor/foo` creates a branch named `refactor/foo`.
56
56
2.**Always use `--auto` with `gh stack submit`** to auto-generate PR titles. Without `--auto`, `submit` prompts for a title for each new PR.
57
57
3.**Always use `--json` with `gh stack view`.** Without `--json`, the command launches an interactive TUI that cannot be operated by agents. There is no other appropriate flag — always pass `--json`.
58
-
4.**Use `--remote <name>` when multiple remotes are configured**, or pre-configure `git config remote.pushDefault origin`. Without this, `push`, `submit`, `sync`, `link`, and `checkout` trigger an interactive remote picker.
58
+
4.**Handle multiple remotes.** If more than one remote is configured, pre-configure `git config remote.pushDefault origin`, or pass `--remote <name>` to the commands that accept it: `push`, `submit`, `sync`, `rebase`, and `link`. `checkout`, `modify`, and `trunk` resolve a remote but have **no `--remote` flag** — they rely on `remote.pushDefault`. With multiple remotes and no configured default, these commands exit with an error in non-interactive mode.
59
59
5.**Avoid branches shared across multiple stacks.** If a branch belongs to multiple stacks, commands exit with code 6. Check out a non-shared branch first.
60
60
6.**Plan your stack layers by dependency order before writing code.** Foundational changes (models, APIs, shared utilities) go in lower branches; dependent changes (UI, consumers) go in higher branches. Think through the dependency chain before running `gh stack init`.
61
61
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.
- ❌ `gh stack init` without branch arguments — always provide branch names
69
69
- ❌ `gh stack add` without a branch name — always provide a branch name
70
70
- ❌ `gh stack checkout` without an argument — always provide a PR number or branch name
71
-
- ❌ `gh stack checkout <pr-number>` when a different local stack already exists on those branches — this triggers an unbypassable conflict resolution prompt; use `gh stack unstack` first to remove the local stack, then retry the checkout
71
+
- ❌ `gh stack checkout <pr-number>` when a different local stack already exists on those branches — this triggers an unbypassable conflict resolution prompt; use `gh stack unstack --local` first to remove the local tracking state (this keeps the stack on GitHub intact), then retry the checkout
Use `unstack` to tear down the stack, make structural changes, then re-init:
391
391
392
392
```bash
393
-
# 1. Remove the stack (locally and on GitHub)
393
+
# 1. Remove the local tracking and the GitHub stack grouping (PRs are NOT deleted)
394
394
gh stack unstack
395
395
396
396
# 2. Make structural changes — e.g. delete a branch, reorder, rename
@@ -733,6 +733,7 @@ gh stack view --json
733
733
"base": "def5678...",
734
734
"isCurrent": false,
735
735
"isMerged": true,
736
+
"isQueued": false,
736
737
"needsRebase": false,
737
738
"pr": {
738
739
"number": 42,
@@ -746,6 +747,7 @@ gh stack view --json
746
747
"base": "abc1234...",
747
748
"isCurrent": true,
748
749
"isMerged": false,
750
+
"isQueued": false,
749
751
"needsRebase": false,
750
752
"pr": {
751
753
"number": 43,
@@ -763,8 +765,9 @@ Fields per branch:
763
765
-`base` — parent branch's HEAD SHA at last sync
764
766
-`isCurrent` — whether this is the checked-out branch
765
767
-`isMerged` — whether the PR has been merged
768
+
-`isQueued` — whether the PR is queued for merge (in a merge queue)
766
769
-`needsRebase` — whether the base branch is not an ancestor (non-linear history)
767
-
-`pr` — PR metadata (omitted if no PR exists). `state` is `"OPEN"`or `"MERGED"`.
770
+
-`pr` — PR metadata (omitted if no PR exists). `state` is `"OPEN"`, `"MERGED"`, or `"QUEUED"`.
768
771
769
772
---
770
773
@@ -779,6 +782,7 @@ gh stack down # Move down one branch (closer to trunk)
779
782
gh stack down 2 # Move down two branches
780
783
gh stack top # Jump to the top of the stack (furthest from trunk)
781
784
gh stack bottom # Jump to the bottom (first non-merged branch above trunk)
785
+
gh stack trunk # Jump to the trunk branch (e.g. main)
782
786
```
783
787
784
788
Navigation clamps to stack bounds. Merged branches are skipped when navigating from active branches.
@@ -787,23 +791,29 @@ Navigation clamps to stack bounds. Merged branches are skipped when navigating f
787
791
788
792
### Check out a stack — `gh stack checkout`
789
793
790
-
Check out a stack from a pull request number or branch name. **Always provide an argument** — running `gh stack checkout` without arguments triggers an interactive selection menu.
794
+
Check out a stack by stack number, pull request number, PR URL, or branch name. **Always provide an argument** — running `gh stack checkout` without arguments triggers an interactive selection menu.
When a PR number is provided (e.g. `123`), the command fetches the stack on GitHub, pulls the branches, and sets up the stack locally. If the stack already exists locally and matches, it switches to the branch.
814
+
A bare number is resolved as a **stack number first** (the identifier shown in the GitHub stack UI); if no stack has that number it is tried as a PR number, then a branch name. When a stack or PR number (or PR URL) is provided, the command fetches the stack on GitHub, pulls the branches, and sets up the stack locally. If the stack already exists locally and matches, it switches to the branch.
805
815
806
-
> **⚠️ Agent warning:** If the local and remote stacks have different branch compositions, this command triggers an interactive conflict-resolution prompt that cannot be bypassed with a flag. To avoid this: run `gh stack unstack` first to remove the conflicting local stack, then retry `gh stack checkout <pr-number>`.
816
+
> **⚠️ Agent warning:** If the local and remote stacks have different branch compositions, this command triggers an interactive conflict-resolution prompt that cannot be bypassed with a flag. To avoid this: run `gh stack unstack --local` first to remove the conflicting local tracking state (this keeps the stack on GitHub intact), then retry `gh stack checkout <pr-number>`.
807
817
808
818
When a branch name is provided, the command resolves it against locally tracked stacks only. This is always safe for non-interactive use.
809
819
@@ -813,6 +823,8 @@ When a branch name is provided, the command resolves it against locally tracked
813
823
814
824
Tear down a stack so you can restructure it — remove a branch, reorder branches, rename branches, or make other large changes. After unstacking, use `gh stack init` to re-create the stack with the desired structure.
815
825
826
+
Unstacking only removes the stack grouping (on GitHub and/or locally); it never deletes the underlying pull requests or branches.
827
+
816
828
With no argument, the command targets the active stack — the one containing the currently checked out branch — unstacking it on GitHub and removing local tracking.
817
829
818
830
Provide a stack number to unstack a specific stack on GitHub. This works from anywhere in the repository, whether or not the stack is checked out locally — the number is unstacked directly through the GitHub API (like `gh stack link`, no local tracking required). If the stack is also tracked locally, its local tracking is removed as well.
# Tear down the current stack (locally and on GitHub), then rebuild
837
+
# Tear down the current stack — removes local tracking and the GitHub grouping (PRs are NOT deleted), then rebuild
826
838
gh stack unstack
827
839
gh stack init --base main branch-2 branch-1 branch-3 # reordered
828
840
@@ -860,13 +872,14 @@ gh stack unstack --local
860
872
| 6 | Disambiguation required | A branch belongs to multiple stacks. Run `gh stack checkout <specific-branch>` to switch to a non-shared branch first |
861
873
| 7 | Rebase already in progress | Run `gh stack rebase --continue` (after resolving conflicts) or `gh stack rebase --abort` to start over |
862
874
| 8 | Stack is locked | Another `gh stack` process is writing the stack file. Wait and retry — the lock times out after 5 seconds |
863
-
| 9 | Stacked PRs unavailable | The repository does not have stacked PRs enabled. `submit` will offer to create regular (unstacked) PRs in interactive mode |
875
+
| 9 | Stacked PRs unavailable | The repository does not have stacked PRs enabled. Tell the user that stacks must be enabled on the repository first |
876
+
| 10 | Modify recovery required | A `gh stack modify` session was interrupted. This skill does not use `modify`, so agents should not produce this; if the repo is left in this state, run `gh stack modify --abort` to restore the pre-modify state |
864
877
865
878
## Known limitations
866
879
867
880
1.**Stacks are strictly linear.** Branching stacks (multiple children on a single parent) are not supported. Each branch has exactly one parent and at most one child. If you need parallel workstreams, use separate stacks.
868
881
2.**Stack disambiguation cannot be bypassed.** If the current branch is the trunk of multiple stacks, commands error with code 6. Check out a non-shared branch first.
869
-
3.**Multiple remotes require `--remote` or config.** If more than one remote is configured, pass `--remote <name>`or set `remote.pushDefault` in git config before running `push`, `sync`, or `rebase`.
882
+
3.**Multiple remotes require `--remote` or config.** If more than one remote is configured, set `remote.pushDefault` in git config, or pass `--remote <name>`to the commands that accept it (`push`, `submit`, `sync`, `rebase`, `link`). `checkout`, `modify`, and `trunk` have no `--remote` flag and rely on `remote.pushDefault`.
870
883
4.**Merging PRs:** Merging Stacked PRs from the CLI is not supported yet. Direct users to open the PR URL in a browser to merge PRs.
871
-
5.**Remote stack checkout requires a PR number.**`checkout` with a branch name only works with locally tracked stacks. Use a PR number (e.g. `gh stack checkout 123`) to pull stacks from GitHub.
884
+
5.**Remote stack checkout requires a stack or PR number.**`checkout` with a branch name only works with locally tracked stacks. Use a stack number or PR number (e.g. `gh stack checkout 7` or `gh stack checkout 123`) to pull a stack from GitHub.
872
885
6.**PR title and body are auto-generated.** There is no flag to set a custom PR title or body during `submit`. The title and body are generated from commit messages plus a footer. Use `gh pr edit` to modify PR title and body after creation.
0 commit comments