gh-aw
Agent quick links Hello fellow agent! Welcome to GitHub Agentic Workflows = Actions + Agent + Safety. Here are some pointers to get you started in using this tool.
A GitHub CLI extension for managing stacked branches and pull requests. Stacked PRs break large changes into a chain of small, reviewable pull requests that build on each other.
$ npx -y skills add github/gh-stack --agent claude-code
Repo: github/gh-stack
What's inside
A GitHub CLI extension for managing stacked branches and pull requests.
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.
gh extension install github/gh-stack
Requires the GitHub CLI (gh) v2.0+.
Install the gh-stack skill so your AI coding agent knows how to work with stacked PRs and the gh stack CLI:
gh skill install github/gh-stack
# Start a new stack (creates and checks out the first branch)
gh stack init
# ... make commits on the first branch ...
# Add another branch on top
gh stack add api-endpoints
# ... make commits ...
# Push all branches
gh stack push
# View the stack
gh stack view
# Open a stack of PRs
gh stack submit
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).
frontend → PR #3 (base: api-endpoints) ← top
api-endpoints → PR #2 (base: auth-layer)
auth-layer → PR #1 (base: main) ← bottom
─────────────
main (trunk)
The bottom of the stack is the branch closest to the trunk, and the top is the branch furthest from it. Each branch inherits from the one below it. Navigation commands (up, down, top, bottom) follow this model: up moves away from trunk, down moves toward it.
When you submit, gh stack creates one PR per branch and links them together as a Stack on GitHub. Each PR's base is set to the branch below it in the stack, so reviewers see only the diff for that layer.
Stack metadata is stored in .git/gh-stack (a JSON file, not committed to the repo). This tracks which branches belong to which stack and their ordering. Rebase state during interrupted rebases is stored separately in .git/gh-stack-rebase-state.
gh stack initInitialize a new stack in the current repository.
gh stack init [flags] [branches...]
Initializes a new stack locally. In interactive mode (no arguments), prompts for a branch name and offers to use the current branch as the first layer.
When explicit branch names are given, existing branches are adopted automatically and any missing branches are created. The trunk defaults to the repository's default branch unless overridden with --base.
Enables git rerere automatically so that conflict resolutions are remembered across rebases.
| Flag | Description |
|---|---|
-b, --base <branch> | Trunk branch for the stack (defaults to the repository's default branch) |
Examples:
# Interactive — prompts for branch names
gh stack init
# Non-interactive — specify branches upfront
gh stack init feature-auth feature-api feature-ui
# Use a different trunk branch
gh stack init --base develop feature-auth
# Adopt existing branches into a stack
gh stack init feature-auth feature-api
gh stack addAdd a new branch on top of the current stack.
gh stack add [flags] [branch]
For an existing stack, 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.
When run interactively from a branch that is not part of a stack, add offers to initialize a new stack instead. The supplied or auto-generated branch name becomes the first layer; without one, the standard init prompts are used.
You can optionally stage changes and create a commit as part of the add flow. When -m is provided without an explicit branch name, the branch name is auto-generated in date+slug format (e.g., 03-24-add_login).
| Flag | Description |
|---|---|
-A, --all | Stage all changes (including untracked files); requires -m |
-u, --update | Stage changes to tracked files only; requires -m |
-m, --message <string> | Create a commit with this message before creating the branch |
Note:
-Aand-uare mutually exclusive.
Examples:
# Create a branch by name
gh stack add api-routes
# Prompt for a branch name interactively
gh stack add
# Stage all changes, commit, and auto-generate the branch name
gh stack add -Am "Add login endpoint"
# Stage only tracked files, commit, and auto-generate the branch name
gh stack add -um "Fix auth bug"
# Commit already-staged changes and auto-generate the branch name
gh stack add -m "Add user model"
# Stage all changes, commit, and use an explicit branch name
gh stack add -Am "Add tests" test-layer
# Stage only tracked files, commit, and use an explicit branch name
gh stack add -um "Update docs" docs-layer
# Commit already-staged changes and use an explicit branch name
gh stack add -m "Refactor utils" cleanup-layer
gh stack checkoutCheck out a stack by its stack number, a pull request number, a PR URL, or a branch name.
gh stack checkout [<stack-number> | <pr-number> | <pr-url> | <branch>]
A bare number is interpreted first as a stack or PR number (repo-scoped identifiers shown in the GitHub UI). If nothing matches the number, it is tried as a branch name.
When a remote stack is referenced, 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. If the local and remote stacks have different compositions, you'll be prompted to resolve the conflict.
When a branch name is provided, the command checks locally tracked stacks first. If the branch is not tracked locally, it looks for the branch on remote stacks and pulls down the matching stack. If more than one stack matches, use a stack or PR number to choose one explicitly.
When run without arguments in an interactive terminal, first checks whether the current branch belongs to a stack on remote that is not tracked locally, and offers to check it out. If there is no unique match or you decline, it opens a searchable picker listing every stack available to you — both the stacks tracked locally and the stacks that exist only on GitHub. Each row shows the stack number, its bottom and top branch, base branch, a status bar summarizing how many of its pull requests are merged, open, closed, or not yet pushed, and whether the stack is available locally or only on the remote. Filter with the All / Local / Remote tabs or type / to search; fully merged stacks are omitted. Selecting a remote-only stack clones it locally before switching to it.
Examples:
# Check out a stack by its stack number
gh stack checkout 7
# Check out a stack by PR number
gh stack checkout 42
# Check out a stack by PR URL
gh stack checkout https://github.com/owner/repo/pull/42
# Check out a stack by branch name
gh stack checkout feature-auth
# Interactive — pick from all available stacks (local and remote)
gh stack checkout
gh stack rebasePull from remote and do a cascading rebase across the stack.
gh stack rebase [flags] [branch]
Fetches the latest changes from origin, then ensures each branch in the stack has the tip of the previous layer in its commit history. Rebases branches in order from trunk upward. If a branch's PR has been merged, the rebase automatically switches to --onto mode to correctly replay commits on top of the merge target.
If a rebase conflict occurs, the operation pauses and prints the conflicted files with line numbers. Resolve the conflicts, stage with git add, and continue with --continue. To undo the entire rebase, use --abort to restore all branches to their pre-rebase state.
| Flag | Description |
|---|---|
--downstack | Only rebase branches from trunk to the current branch |
--upstack | Only rebase branches from the current branch to the top |
--no-trunk | Skip trunk — only rebase stack branches onto each other (no fetch, no trunk rebase) |
--continue | Continue the rebase after resolving conflicts |
--abort | Abort the rebase and restore all branches to their pre-rebase state |
--remote <name> | Remote to fetch from (defaults to auto-detected remote) |
--committer-date-is-author-date | Set the committer date to the author date during rebase. Alias: --preserve-dates |
| Argument | Description |
|---|---|
[branch] | Target branch (defaults to the current branch) |
Examples:
# Rebase the entire stack
gh stack rebase
# Only rebase branches below the current one
gh stack rebase --downstack
# Only rebase branches above the current one
gh stack rebase --upstack
# Rebase stack branches without pulling from or rebasing with trunk
gh stack rebase --no-trunk
# After resolving a conflict
gh stack rebase --continue
# Abort rebase and restore everything
gh stack rebase --abort
# Rebase and preserve committer date as author date
gh stack rebase --committer-date-is-author-date
gh stack modifyInteractively restructure the current stack.
gh stack modify [flags]
Opens a terminal UI for restructuring a stack. You can drop, fold, insert, rename, and reorder branches. All the changes are staged during the preview and applied at once on save.
If the stack of PRs has been created on GitHub, run gh stack submit afterwards to push the changes and recreate the stack.
| Flag | Description |
|---|---|
--continue | Continue after resolving conflicts |
--abort | Abort the modify session and restore the stack to its pre-modify state |
Operations:
x): Remove a branch and its commits from the stack. Local branch and associated PR are preserved.d): Absorb a branch's commits into the branch below (toward trunk). Folded branch removed from stack.u): Absorb a branch's commits into the branch above (away from trunk). Folded branch removed from stack.i/I): Insert a new empty branch into the stack. i inserts below the cursor; I inserts above.Shift+↓/Shift+↑): Move a branch down (toward trunk) or up (away from trunk) in the stack.r): Rename a branch locally and in the stack metadata.z): Undo the last staged action.Keybindings:
| Key | Action |
|---|---|
↓/↑ or j/k | Navigate branch list |
f | View files changed |
c | View commits |
x | Drop branch |
r | Rename branch |
i/I | Insert branch below/above |
d/u | Fold branch down/up |
Shift+↓/Shift+↑ | Move branch down/up |
z | Undo last action |
Ctrl+S | Apply all changes |
q/Esc | Cancel and exit |
? | Help |
Preconditions:
Examples:
# Open the modify TUI
gh stack modify
# Continue after resolving a conflict
gh stack modify --continue
# Abort and restore to the previous state
gh stack modify --abort
gh stack syncFetch, rebase, push, and sync PR state in a single command.
gh stack sync [flags]
Performs a synchronization of the entire stack:
origin.Agent quick links Hello fellow agent! Welcome to GitHub Agentic Workflows = Actions + Agent + Safety. Here are some pointers to get you started in using this tool.
A community-created collection of custom agents, instructions, skills, hooks, workflows, and plugins to supercharge your GitHub Copilot experience.
FAQ
gh-stack is a Claude Code plugin with 1 hand-picked skill for development work, indexed on Flowy. Install it with the command on its page. It includes gh-stack. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.
Is this plugin yours?
Claim it with GitHubSubmit a pluginPromote it