GitHub Stacked PRs
82 points by jado
82 points by jado
Oh look they've discovered patch series
Patch series but with a branch per patch that you have to rebase every time you edit the one at the bottom :-/
is that how they did it? ...oh dear.
A stack of PRs seems like a pretty logical way to build stacked PRs.
And keeping branches as the reference points means you don't need to inject additional non-standard metadata into git, and you should be able to use git rebase --update-refs to update your entire stack all at once using standard git.
Okay, good, I'm not the only one who's surprised by this being a big announcement.
I’m not, the lack of support for stacking, and the annoyance of trying to do dependent PRs on GitHub, has been a pretty regular complaint for a while now. And it is a pretty big UX update, not to mention the tooling fo make it feel nice at the cli level.
I’ve not looked at the details yet, I wonder if gh is supporting the change-id standard which was starting to gain steam, and how well (or not) it’ll work with jj.
Yeah, I don't get the "this is dumb" mentality. This basically formalizes an approach to break down larger engineering efforts into logical chunks. Plenty of people already informally do this...they just added structure around it. Jujutsu exists already for this because people do it. Gitbutler already exists and received a good chunk of seed funding recently because people see value in the idea.
jj is in fact explicitly called out in the FAQ: https://github.github.com/gh-stack/faq/#will-this-work-with-a-different-tool-for-stacking
(I have been using the internal preview of the feature, and I use jujutsu myself; it works as you'd hope)
jj is in fact explicitly called out in the FAQ
Since jj is compatible with git, that it would work if you emulate git was a given. I wouldn't say that's working "well" if it doesn't leverage any of github's support for change stability.
it works as you'd hope
As I think was obvious from my comment, I'd hope it would work off of change-ids, which doesn't seem to be the case since your link shows the creation of a bookmark for each change.
The gh stack CLI sounds essential for people using git, but I hope it doesn't become required, as people using things like jj/sl should be able to work with stacks. gs submit/gs push being the interface to github is fine, but gs init and gs add being the interface to branch management should be optional.
Looks like it should work with jj and other tooling:
https://github.github.com/gh-stack/faq/#do-i-need-to-use-the-github-cli
https://github.github.com/gh-stack/faq/#will-this-work-with-a-different-tool-for-stacking
Can not confirm, myself.
this is counterintuitive. the tool requires that you create N branches to stack your work. this is frustrating because if I have a 10 patch series, I am not going to make 10 branches.
Tools can just automate this. The graphite gui, for example, autogenerates branch names based on the commit message/pr title.
It’s not ideal but also not a big deal.
this is frustrating because if I have a 10 patch series, I am not going to make 10 branches.
Why? That's trivial to do by hand, and can be automated by a few lines of shell.
Naming things is one of the two hard problems in computer science and you just asked me to name ten branches. If I'm doing it by hand, there's going to be ten branches named havarti, machego, lorraine, roquefort, etc. If it's being automated by a script, then it's ten branches named fix_pointers_834, fix_pointers_835, fix_pointers_836, fix_pointers_837, etc. In both cases, the names are useless, so why are we requiring them?
To head off the obvious question, I didn't squash the ten fix_pointers commits down into a single commit because I didn't want to give the reviewers another PR that touches a thousand files. After all, it feels like the whole point of stacked PRs is making it easier to break the work into smaller parts.
In both cases, the names are useless
The names are meaningless, which is different than them being useless.
so why are we requiring them?
It's really not hard to figure out: first because github PRs work off of refs so this lowers the blast radius of implementing this feature, and second using refs means github can track the evolution of each PR through their respective refs instead of having to use non-standard git extensions when you rebase, update, and push your stack.
Maybe github will support change-id eventually, and git will as well, but right now neither do (and from what I remember of it being proposed on the git mailing list the latter seems pretty unlikely).
github.github.com? What were they thinking?
It's the pages domain for the github org: https://github.com/github/
Then they should be using .io for consistency with other orgs/users.
I honestly have no idea how anyone can be productive without stacked patches. I'm sure they can, but I often wrangle multiple branches each of which have 1-10 stacked patches of somewhat interrelated changes to code owned by different teams. I live in git rebase -i so that I can reorder and update patches.
I'm told jj makes a lot of this easier, and one of these days I'm going to spend the time to learn how to do it.
jj makes it super easy to just jump in the middle of a patch series and change something: it will automatically rebase everything on top of it and that is so, so convenient! On the other hand, until recently it didn't have anything very convenient to just reorder commits (jj rebase can do it but it is a bit awkward to use for this purpose imho); this is now fixed by jj arrange, which provides exactly a git rebase -i-style interface, is available since jj 0.39 released in March 2026.
Note: for people that still use git and struggle to clean history when they have a tree of branches on top of each other, note that the somewhat-recent --rebase-merges option of git rebase -i allows to do this more conveniently than before (it was implemented in 2018). The UI is a bit awkward (you have to go to the top of the tree even if you want to act on a commit deep down), but very powerful, git style.
There's also jjui where you can reorder the commits in a different, visual way. Also very convenient.
I'm sure jjui is nice, but personally I prefer to have the "official" tool have a good interface if possible, so I prefer to stick to it and push it to improve. I don't like the git state of things where people recommend a myriad of on-the-side UIs and this decreases incentives to agree on improving the UI of the tool itself. Clearly the jj caretakers are happy to continuously improve the UI, and in particular jj arrange introduces focused TUI workflow in the core tool. I think we should support this, so I prefer to avoid side-UIs.
Sounds like you'd have a lovely time with jj. You can have the combination of multiple stacks checked out simultaneously, make a change, and have that change automatically absorbed into the right revision. Or pick squash targets yourself, not hard.
Killer features on top of killer features. Constantly in a state of harmonious interactive rebase, operation log to move back and forth in history, and great stack management throughout.
Ecosystem needs some editor support but yeah no notes give it a shot.
I usually have a mega merge of 5 or so stacks open working on features with huge review latency, or some personal repo tweaks that I need to stay productive locally regardless of what branch I have checked out for feature work. Can leave such things "in the background" so to speak and still have the ease of "just commit everything and push it" without fussing with stash.
I didn't know really what I was missing not using them until I tried jujutsu. People already sort of do this on big efforts anyway but that comes with a lot of manual branch management that this just solves. Not sure whether I like gitbutler or jujutsu more yet but both have made my workflow better.
Finally!! Hope this also acts as a workaround for the issue where, if you click on a rebased PR from the notifications view, it says "cannot find those commits", because it's trying to generate a diff from when you last viewed the PR (missing commits) to the current; stacked PR tracking should be more properly recording the "commit history" without those commits actually being linked to each other in a git branch.
Seems unlikely given GitHub has had working links in the discussions tab for years yet this is still unaddressed. And there’s similarly still no way to disable these useless notifications either.
Oh joy, yet another bug in notifications / navigation. I wonder what's actually going on inside GH - are none of their devs using that view? Is it frozen forever? How is it getting worse over years, not better?
Eh it’s not a new bug, it’s been there forever: when using email notifications you can disable pr push notifications but if you use the web ui you can’t. It’s been that way since I started using GitHub.
Nice, if you work on a project where PRs take more than a week to merge there is a tension between keeping PRs scoped and getting a feature or refactoring done. Starts to feel like playing a game of Gridlock. Will be making use of these.
unfortunately i don't know what the PR # 1 should be until i get to the end
This happens to me too, but there's still value in splitting a fully-implemented change up into a sequence of smaller changes.
Reviewing becomes easier since each PR in the stack has a narrower focus and touches less code.
Splitting the change up acts as a kind of code-review pass. On a number of occasions, it was only when I tried to break a change up into a stack of PRs that I realized I'd unintentionally introduced coupling between components. Smaller PRs also make it easier to spot when you're missing test coverage.
I'm so over Github that I can't even be bothered to read this even though I was hoping for such a feature for a long time. I don't believe in anyway that they'll make something even remotely good enough.
How does patch evolution (my complaints) work? My notes:
Due to the difficulties in comparing revisions and the lack of confidence in preserving inline comments, some recommendations suggest adopting less flexible and less preferred workflows, which involve only appending new commits and discouraging rebases.
Force-pushing is sometimes discouraged to ensure review context remains intact (llvm discussion). If we use this tool, do we accept that we can freely force push commits?
So, pull request for each commit? This almost feels like pair programming at that point. Not to say that I am against the idea though.
While you can do this, it's more useful to think of it as an easy way to develop multiple things depending on each other in parallel. Eg. you can create a stack with separate PRs for design docs, frontend and backend changes without introducing temporary state where your main/master/trunk() isn't usable
I was hoping this wouldn't require linear history though, but according to the FAQ it does.
I wonder whether you could create 2 stacked PRs that share a common base PR. That'd allow to more naturally open PRs from local jj branches that use the mega-merge workflow / parallelize commit features.
Cautiously optimistic: The problem is hardly the automation of rebasing 10 remote branches at once when GitHub's UI doesn't understand rebasing the slightest, making it instantly impossible to review. I hope this can be improved next.
Compare the stacked workflow with Gerrit, which does see what you did:
git range-diff for code review when the author is rebasing.The CLI is nowhere near jujutsu or GitButler, but it's still nice that they have UI support for stacked PRs.
Can someone explain how this is different than the approach of treating every commit in a pr a sequence of changes that should be read and reviewed in order? It takes discipline and a lot of rebasing, but some of us have been doing this for a long time. Does this give a better ux?
Does this give a better ux?
That seems quite obvious from the screenshots? You can comment on each PR in the stack individually, currently this is impossible outside of line comments (so reviewing, say, commit messages is absolute garbage). It also allows tracking the evolution of each commit rather than just seeing the head of the PR has changed, and it allows merging the stack progressively as the design gels, rather than have to merge the entire thing at once. And because they're separate PRs CI will run on each individually, which avoids the issue of middle commits being broken and only the last one passing CI, whereas CI usually doesn't run on individual commits. You also get a cool view of the entire stack's CI.
Hell, it even allows more easly abandoning the tail of the stack, so that you can merge a new improved API but then you can either drop or delay the rewriting of half the codebase to use that API everywhere. But because you can have the motivating changes as a very visible demonstration, it is much easier to justify a new API or refactoring.
Is it also available for enterprise edition?
Enterprise still hasn't gotten things like commenting on unchanged lines. I think by this point we'll get stacked PRs by 2030.
I feel this is cool and useful for people in the unfortunate situation where they’re not using trunk-based development and/or PRs just live too long. It’s taking an unnecessarily complicated situation and making it tolerable instead of reducing the inessential complexity.