GitHub Stacks in Jujutsu | Alan Norbauer
GitHub Stacks in Jujutsu
This article is part of a series on<br>Stacks in Jujutsu . Other articles in<br>the series:
GitHub Stacks in Jujutsu
Stacks in Jujutsu
GitHub released it’s<br>stacked pull request (PR) feature<br>into public preview on 2026-07-30. It mainly targets git users but<br>has documented support for other, git-compatible version control<br>systems like Jujutsu (jj).
This is a primer for using GitHub stacks with jj.
Prerequisites
Install CLIs
You need the git (instructions) and jj (instructions) CLIs installed.
You need the gh GitHub CLI installed (instructions).
Install the stacking extension with<br>gh extension install github/gh-stack
This article was written/tested against:
jj v0.43.0
git v2.52.0
gh v2.96.0
github/gh-stack v0.1.0
Configure jj
I will be re-using some jj aliases and revset aliases we<br>defined in the previous article,<br>Stacks in Jujutsu.
Bonus: Learn jj’s bookmark aliases
GitHub’s Stacked PRs require every PR to have a<br>jj bookmark (git branch), so you’ll be creating a<br>lot of these. UI tools in the future will surely automate<br>creating branch names under the covers, but for now, learn the<br>jj aliases for easily managing bookmarks:
Command<br>Description
jj b l<br>list bookmarks
jj b s -r
Create (or move) a bookmark to the given commit
jj b a
Advance the nearest bookmark to the current commit<br>(like jj tug)
jj b --help<br>Docs with the aliases for all the commands
💡 Aside: Did you know that you can improve the default<br>jj bookmark advance (jj b a)<br>behavior by customizing the revset it uses? If you’re on a<br>new, empty commit ABOVE a commit with code, you probably<br>want to advance the bookmark to the code commit below you.<br>You can accomplish this with:
~/.config/jj/config.toml
[revset-aliases."closest_pushable(to)"]
definition = 'heads(::to & mutable() & ~empty() & description(regex:".+"))'
doc = "Closest mutable, non-empty, described commits at or behind to"
[revsets]
bookmark-advance-to = "closest_pushable(@)"
jj makes it super easy to customize behavior by overriding<br>the built-in bookmark-advance-to revset to<br>whatever you want.
Manual Workflows
The gh stack CLI has a bunch of subcommands, most<br>of which manage or consume local tracking of the stack (e.g.<br>init, view). In a jj repo you will<br>only use the few subcommands that manage the remote stack on<br>GitHub (e.g. link, push), as follows:
Create a stack
Create a bookmark for each commit in your stack:
Terminal window
# go to the bottom of your stack using our revset alias
jj edit -r "stack_bottom()"
# give commit a name
jj b c
# go to the next commit
jj next --edit
# give commit a name
jj b c
# ... repeat for each commit in stack
jj next --editjj b c '
Upload your bookmarks to GitHub, create draft PRs for<br>each, and link them all into a stack:
Using our<br>stack alias:
Terminal window
gh stack link $(jj sb -r "stack()")
Or, using a jj revision range:
Terminal window
gh stack link $(jj sb -r commit1::commitN)
Or, since jj sb defaults to your<br>substack, you can go to the<br>top<br>(where your stack and substack are the same thing) and<br>then link the entire stack:
Terminal window
jj top --edit
gh stack link $(jj sb)
This last one is probably the easiest to remember.
Add a new commit to the TOP of the<br>stack
Assuming the new commit is change id abc:
Make sure you’re editing your new commit:
Terminal window
jj edit -r abc
Create a bookmark for the new, current commit:
Terminal window
jj b c
If you’ve modified any of the downstack commits, you need to<br>push the updates (since jj git push will do a<br>--force-with-lease push, but<br>gh stack link won’t):
Terminal window
jj git push -r "stack()"
Re-run link with all stack bookmarks:
Terminal window
gh stack link $(jj sb)
The existing PRs (for everything downstack) will be skipped<br>and the new branch will get a new draft PR and will be<br>linked into the stack.
Add a new commit to the BOTTOM or<br>MIDDLE of the stack
You can’t add to the middle of a stack (you’ll get an error:<br>“Cannot update stack: new PRs must be added to the top of the<br>existing stack”), so you have to delete your stack and<br>recreate it. Assuming the new commit is change id<br>abc:
Go to the GitHub web UI and remove the stack:
Create a bookmark for the new commit:
Terminal window
jj b c -r abc
Since you’ve modified the rebased, upstack commits, re-push<br>everything:
Terminal window
jj git push -r "stack()"
Re-run link with all stack bookmarks, including the new one:
Terminal window
jj top --edit
gh stack link $(jj sb)
the existing PRs will be skipped, and the new branch will<br>get a new draft PR and will be linked into the stack
Remove a commit from the stack
You have to delete your stack and recreate it. Assuming the<br>commit to remove is change id abc:
Go to the GitHub web UI and remove the stack:
Make sure you’re at the top of the stack:
Terminal window
jj top --edit
Abandon the commit if you haven’t already:
Terminal window
jj abandon -r...