Skip to content

gh stack

gh stack is a GitHub CLI ⧉ extension for managing a PR stack. It opens one PR per branch of the stack, similar in spirit to stack-pr but driven through the gh tool.

Cheat sheet

To Run
Open PRs for the stack, as drafts gh stack submit --auto
Open PRs for the stack, choosing titles and draft state gh stack submit
Update the PRs after changing branches gh stack push
Pick up changes on main gh stack rebase, then gh stack push
Update the branches above one you changed gh stack rebase --upstack from that branch, then gh stack push
Carry on after resolving rebase conflicts Stage the files, then gh stack rebase --continue
See the stack's branches and their PRs gh stack view

Usage

Each PR in a stack has its own local branch, and each branch builds on the one below it. The commands below are the ones you need to get those branches onto GitHub as PRs and keep them up to date.

Opening the PRs with submit

gh stack submit pushes every branch of the stack to GitHub and opens a PR for each branch that does not have one yet. It also points each PR at the branch below it, so every PR only shows its own changes, and groups the PRs into a stack on GitHub.

Before opening the PRs, it shows a screen listing the new PRs, where you can edit each one's title and description and untick any you do not want yet. Each PR there has a "CREATE AS" toggle that decides whether it is opened as a draft or as ready for review. The default is ready for review.

To skip that screen, pass --auto. The PRs then get generated titles and are opened as drafts, unless you also pass --open. Usually you'll want to run gh stack submit --auto initially.

Updating the PRs with push

Once the PRs exist, gh stack push is all you need after changing the branches. It only force-pushes the branches and leaves the PRs themselves alone.

Running submit again instead is also fine. It changes nothing about existing PRs, except that --open marks them all ready for review. But it opens a PR for every branch that has none, so untick any branch you added that is not ready yet.

Keeping the branches on top of each other with rebase

Changing a branch does not change the branches above it. They still build on the old version of it until you rebase them. Until then, the PR directly above shows "This stack has conflicts that must be resolved" on GitHub.

gh stack rebase fetches the latest main and rebases the whole stack onto it, branch by branch. It does this no matter which of the stack's branches you are on. Use it to pick up changes on main.

gh stack rebase --upstack skips main and the branches below you, and rebases only your current branch and the ones above it. Use it after changing a branch in the middle of the stack, and run it from that branch, not from the top of the stack.

If a rebase stops on conflicts, resolve them, stage the files and run gh stack rebase --continue. Then run gh stack push to update the PRs.

Limitations

Local main must match origin/main

gh stack works out what each branch adds by comparing the bottom branch against your local main, not the one on GitHub. If you made the stack's commits on main before moving them onto their own branches, the bottom branch looks like it adds nothing. Its PR is then titled after the branch name, and gh stack view, which lists the stack's branches and their PRs, marks it as needing a rebase. Reset your local main to origin/main before running gh stack submit.

Stacking a stack on top of another stack

gh stack cannot always stack one stack directly on top of another. If the base of your stack is the tip of another stack, the tool cannot tell where one stack ends and the next begins.

Consider two stacks where second-stack-1 is meant to build on first-stack-3:

* second-stack-3
* second-stack-2
* second-stack-1  first-stack-3
* first-stack-2
* first-stack-1
* main

You have two ways around this:

  • Re-create one of the stacks.
  • Keep two branches pointing at the same commit, so each stack has its own base to track.

This does not block day-to-day use.

Both workarounds are cheap. The limitation only affects the rarer case of stacking a stack on top of another.