Skip to content

Commit d1df702

Browse files
committed
update readme
1 parent 4e06c00 commit d1df702

1 file changed

Lines changed: 310 additions & 1 deletion

File tree

README.md

Lines changed: 310 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,311 @@
11
# gh-stack
2-
A GitHub CLI extension to manage stacked branches and PRs
2+
3+
A GitHub CLI extension for managing stacked branches and pull requests.
4+
5+
Stacked PRs break large changes into a chain of small, reviewable pull requests that build on each other. `gh stack` automates the tedious parts — creating branches, keeping them rebased, setting correct PR base branches, and navigating between layers.
6+
7+
## Installation
8+
9+
```sh
10+
gh extension install githubnext/gh-stack
11+
```
12+
13+
Requires the [GitHub CLI](https://cli.github.com/) (`gh`) v2.0+.
14+
15+
## Quick start
16+
17+
```sh
18+
# Start a new stack from the default branch
19+
gh stack init
20+
21+
# Create the first branch and start working
22+
gh stack add auth-layer
23+
# ... make commits ...
24+
25+
# Add another branch on top
26+
gh stack add api-endpoints
27+
# ... make commits ...
28+
29+
# Push all branches and create/update PRs
30+
gh stack push
31+
32+
# View the stack
33+
gh stack view
34+
```
35+
36+
## How it works
37+
38+
A **stack** is an ordered list of branches where each branch builds on the one below it. The bottom of the stack is based on a **trunk** branch (typically `main`).
39+
40+
```
41+
main (trunk)
42+
└── auth-layer → PR #1 (base: main)
43+
└── api-endpoints → PR #2 (base: auth-layer)
44+
```
45+
46+
When you push, `gh stack` creates one PR per branch. Each PR's base is set to the branch below it in the stack (**branch-chaining**), so reviewers see only the diff for that layer.
47+
48+
### Local tracking
49+
50+
Stack metadata is stored in `.git/gh-stacks` (a JSON file, not committed to the repo). This tracks which branches belong to which stack and their ordering. Rebase state during interrupted updates is stored separately in `.git/gh-stacks-rebase-state`.
51+
52+
## Commands
53+
54+
### `gh stack init`
55+
56+
Initialize a new stack in the current repository.
57+
58+
```
59+
gh stack init [branches...] [flags]
60+
```
61+
62+
Creates an entry in local tracking to define a stack. In interactive mode (no arguments), prompts you to name branches and offers to use the current branch as the first layer.
63+
64+
| Flag | Description |
65+
|------|-------------|
66+
| `-b, --base <branch>` | Trunk branch for the stack (defaults to the repository's default branch) |
67+
| `-a, --adopt` | Adopt existing branches into a stack instead of creating new ones |
68+
69+
**Examples:**
70+
71+
```sh
72+
# Interactive — prompts for branch names
73+
gh stack init
74+
75+
# Non-interactive — specify branches upfront
76+
gh stack init feature-auth feature-api feature-ui
77+
78+
# Use a different trunk branch
79+
gh stack init --base develop feature-auth
80+
81+
# Adopt existing branches
82+
gh stack init --adopt feature-auth feature-api
83+
```
84+
85+
### `gh stack add`
86+
87+
Add a new branch on top of the current stack.
88+
89+
```
90+
gh stack add [branch]
91+
```
92+
93+
Creates a new branch at the current HEAD, adds it to the top of the stack, and checks it out. Must be run while on the topmost branch of a stack. If no branch name is given, prompts for one.
94+
95+
**Examples:**
96+
97+
```sh
98+
gh stack add api-routes
99+
gh stack add # prompts for name
100+
```
101+
102+
### `gh stack checkout`
103+
104+
Discover and check out an entire stack from a pull request or branch.
105+
106+
```
107+
gh stack checkout <pr-or-branch> [flags]
108+
```
109+
110+
Accepts a PR number, `#123`, a PR URL, or a branch name. Traces the chain of PRs to discover the full stack, fetches all branches, and saves the stack to local tracking.
111+
112+
| Flag | Description |
113+
|------|-------------|
114+
| `--no-switch` | Fetch and track the stack without switching to the target branch |
115+
116+
**Examples:**
117+
118+
```sh
119+
gh stack checkout 42
120+
gh stack checkout '#42'
121+
gh stack checkout feature-auth
122+
gh stack checkout https://github.com/owner/repo/pull/42
123+
```
124+
125+
### `gh stack update`
126+
127+
Pull from remote and do a cascading rebase across the stack.
128+
129+
```
130+
gh stack update [branch] [flags]
131+
```
132+
133+
Ensures each branch in the stack has the tip of the previous layer in its history. Rebases branches in order from trunk upward. If a rebase conflict occurs, pauses and lets you resolve it, then continue with `--continue`.
134+
135+
| Flag | Description |
136+
|------|-------------|
137+
| `--downstack` | Only update branches from trunk to the current branch |
138+
| `--upstack` | Only update branches from the current branch to the top |
139+
| `--continue` | Continue the update after resolving a rebase conflict |
140+
| `--abort` | Abort the update and restore all branches to their pre-update state |
141+
142+
**Examples:**
143+
144+
```sh
145+
# Update the entire stack
146+
gh stack update
147+
148+
# Update only branches below the current one
149+
gh stack update --downstack
150+
151+
# After resolving a conflict
152+
gh stack update --continue
153+
154+
# Give up and restore everything
155+
gh stack update --abort
156+
```
157+
158+
### `gh stack push`
159+
160+
Push all branches in the current stack and create or update pull requests.
161+
162+
```
163+
gh stack push [flags]
164+
```
165+
166+
Pushes every branch to the remote, then for each branch either creates a new PR (with the correct base branch) or updates the base of an existing PR if it has changed.
167+
168+
| Flag | Description |
169+
|------|-------------|
170+
| `-f, --force` | Force-push branches |
171+
| `--draft` | Create new PRs as drafts |
172+
| `-n, --dry-run` | Show what would be pushed without actually pushing |
173+
174+
**Examples:**
175+
176+
```sh
177+
gh stack push
178+
gh stack push --force
179+
gh stack push --draft
180+
gh stack push --dry-run
181+
```
182+
183+
### `gh stack view`
184+
185+
View the current stack.
186+
187+
```
188+
gh stack view [flags]
189+
```
190+
191+
Shows all branches in the stack, their ordering, PR status, and recent commits. Aliases: `status`, `list`, `ls`.
192+
193+
| Flag | Description |
194+
|------|-------------|
195+
| `-s, --short` | Compact output (branch names only) |
196+
| `-w, --web` | Open all associated PRs in the browser |
197+
198+
**Examples:**
199+
200+
```sh
201+
gh stack view
202+
gh stack view --short
203+
gh stack view --web
204+
gh stack ls # alias
205+
```
206+
207+
### `gh stack delete`
208+
209+
Remove a stack from local tracking, and optionally clean up branches and PRs.
210+
211+
```
212+
gh stack delete [branch] [flags]
213+
```
214+
215+
If no branch is specified, uses the current branch to find the stack.
216+
217+
| Flag | Description |
218+
|------|-------------|
219+
| `--close-prs` | Close associated pull requests on GitHub |
220+
| `--remote` | Delete remote branches |
221+
| `--local` | Delete local branches |
222+
| `-y, --yes` | Skip confirmation prompts |
223+
224+
**Examples:**
225+
226+
```sh
227+
# Just stop tracking the stack
228+
gh stack delete
229+
230+
# Full cleanup
231+
gh stack delete --close-prs --remote --local --yes
232+
```
233+
234+
### Navigation
235+
236+
Move between branches in the current stack without having to remember branch names.
237+
238+
```sh
239+
gh stack up [n] # Move up n branches (default 1)
240+
gh stack down [n] # Move down n branches (default 1)
241+
gh stack top # Jump to the top of the stack
242+
gh stack bottom # Jump to the bottom of the stack
243+
```
244+
245+
**Examples:**
246+
247+
```sh
248+
gh stack up # move up one layer
249+
gh stack up 3 # move up three layers
250+
gh stack down
251+
gh stack top
252+
gh stack bottom
253+
```
254+
255+
### `gh stack feedback`
256+
257+
Share feedback about gh-stack.
258+
259+
```
260+
gh stack feedback [message] [flags]
261+
```
262+
263+
| Flag | Description |
264+
|------|-------------|
265+
| `--anonymous` | Submit feedback anonymously |
266+
267+
### `gh stack merge`
268+
269+
Merge the bottom PR in a stack. **Not yet available** — use `gh pr merge` manually for now.
270+
271+
### Placeholder commands
272+
273+
The following commands are planned but not yet implemented. Running them prints a notice and suggests using `gh stack feedback` to share your interest.
274+
275+
`remove` · `modify` · `reorder` · `move` · `fold` · `squash` · `rename` · `split`
276+
277+
## Typical workflow
278+
279+
```sh
280+
# 1. Start a stack
281+
gh stack init
282+
gh stack add auth-middleware
283+
284+
# 2. Work on the first layer
285+
# ... write code, make commits ...
286+
287+
# 3. Add the next layer
288+
gh stack add api-routes
289+
# ... write code, make commits ...
290+
291+
# 4. Push everything and create PRs
292+
gh stack push
293+
294+
# 5. Reviewer requests changes on the first PR
295+
gh stack bottom
296+
# ... make changes, commit ...
297+
298+
# 6. Rebase the rest of the stack on top of your fix
299+
gh stack update
300+
301+
# 7. Force-push the updated stack
302+
gh stack push --force
303+
304+
# 8. When the first PR is merged, update the stack
305+
gh stack update
306+
gh stack push
307+
```
308+
309+
## License
310+
311+
See [LICENSE](LICENSE) for details.

0 commit comments

Comments
 (0)