Excited to release this more broadly so anyone can start stacking: https://gh.io/stacks
Would love to hear any feedback, especially with the UI and CLI. We've got a lot more updates to the PR experience in store!
Also happy to answer questions about the design decisions we made. There's a bunch happening behind the scenes, and it's one of the largest launches in GitHub history covering almost every service from Actions and protection rules to the CLI and mobile apps.
You can merge one by one, but if you're using squash and merge, you need a re-approval for each PR in the stack if you require reviews. This makes you lose out on arguably the biggest gain of stacked PRs.
The command line tooling (gh stack) helps to make things slightly less manual, but you still need to be very aware of how git rebase works, the tooling just helps automate it across multiple branches. For example, just running the "gh stack rebase" commands that the UI suggests won't work if your local branches are not in sync with the remote ones, and the tooling won't point that out to you.
I do find the stack UI quite nice. It's quite minimal compared to standalone PRs, but it's enough to show the relationship between them.
(My comments all assume you already have a good reason to stack PRs. This tooling just help to make the workflow easier, it does not give any new capabilities)
What's the benefit of this type of stacked PRs over a well-curated set of commits, and reviewing per commit?
I think the bigger problem is that big AI PR's need a different way of reviewing. For example, the order in which the diff's are shown can make a big difference in how easy the commits are to read (e.g., function definition change first, then all call sites, then the tests).
Or maybe we should go to a system where diffs & comments are intertwined, a bit like how "Literate Programming" intertwines code and prose.
Literate diffs / literate pull requests... I haven't found anything like that yet.
> What's the benefit of this type of stacked PRs over a well-curated set of commits, and reviewing per commit?
For the people who work with stacked diffs (in phab/otherwise) this is exactly what they'd consider reviewing a well-curated set of commits one-by-one.
One distinction is that cognitively a unit of review (a PR, a diff) remains a single bound change. Comments are focused on that change and the PR does not grow with size of the feature
Another distinction is the ability to focus each part of the stack to a particular audience. One change may require review from an external team, another may be just your team mate, a third might be the consuming team. By focusing the stack to the different reviewers you can avoid ambiguity about "what a person is signing off on" in the stack.
aside: one thing that would be great for github reviews is the adoption of change ids such that comments persist across reviews with a rebase workflow.
IMO, in a team settings, improving the review policies and speed has a much better benefit. A PR is supposed to be a proposal for some change, adding more proposals on top of something that is not reviewed is a bit icky.
> . By focusing the stack to the different reviewers you can avoid ambiguity about "what a person is signing off on" in the stack.
That can be easily done with comments. If the PR are orthogonal, they could have been split. And if they're not, I would really like to know how the part that I'm reviewing interacts with the rest of the changes.
With stacking you can continue working on a longer change while creating reviewable diffs. Merged diffs can be rebased on your HEAD. For teams that support stacked diffs you don't usually even need to manage branches and work directly off trunk and rebase changes as they come in
It’s the “well-curated” part. Many folks treat commits like video game save points, and find providing any kind of message burdensome (e.g. “fix bug”, “do work”). This alone is fine, but then they can’t be bothered to go back and clean it up with `git rebase -i`, so you end up with a mountain of trash in your git log if you don’t turn on mandatory squash and merge. For these folks, the PR becomes the commit. Stacked PRs is revolutionary because it’s as though these developers can finally have multiple commits which comprise a change.
I've had that same "what's the point" thought every time I've read about stacked PRs, but recently had an (obvious) epiphany. The benefit is you get CI for each commit! I've always hated fixup/typo/fix tests commits and toyed with having a CI check that enforced ci passing on each commit but this drops that need.
> I've always hated fixup/typo/fix tests commits and toyed with having a CI check that enforced ci passing on each commit but this drops that need.
Can't you run your CI locally? I know it's not feasible for some codebase, but at least the linting, formatting, unit tests, some integration tests should be able to be done locally.
Started using the gh stack CLI when I first heard of this feature & really liked it - great tooling. Then got approved for the preview & found the corresponding web UI features incredibly underwhelming.
Pre-approval the CLI tooling effectively enables easier automations around splitting a task into multiple atomic PRs - really great locally but then when you push they just show up as independent unlinked PRs.
Post-approval... they still show up as independent PRs. There's a small nav drop down up top listing the other PRs in the stack but that's it. Literally no meaningful UI changes.
The dropdown also allows you to perform a limited subset if the CLI functionality but this is similar to the ability to edit files in the UI - an optional extra casual use feature that won't be a part of dev workflows: the CLI (or IDE plugins I guess) would be the primary way to perform these actions.
It all left me wondering what the big deal with the preview not being a general release - it's extremely minor optional UI. The stacks cli has been general release since this was announced.
Really excited to try this. After using Graphite it's been very hard going back to stack-less GitHub. Hopefully this can make the stacked PR workflow more common and give people an easier alternative to mammoth PRs.
I'd recommend git-spice, it's very easy to use and powerful, and of course open-source. I've tried graphite but found that they made it too convoluted for what it is.
I will second git-spice. It does exactly what you want and, importantly, no more than that. There's no upsell to anything else; it's "just" a good tool that knows its purpose and boundaries.
I feel like many people (and industry in general) complicate things unnecessary.
Stacked pull requests break large changes into small, reviewable pull requests.
That's how pull requests are supposed to be, no? If yours aren't that - you ought to rewrite them.
With stacks, you can independently review and check each pull request, then merge everything together in one click.
Why would I want to do that instead merging (and deploying/testing) separately, which gives me more reliability?
No more opening a single large pull request that takes forever to review, or splitting work across multiple branches you have to keep manually rebasing.
Well, it doesn't seem like a simplification over dreaded "manual rebasing". And the target branch still moves, doesn't it? So, how are you "saved" from rebasing?
It's like responsibility is shifted from the author to the tool. That has been tried before, and every time it seem to consistently produce the similarly shaped mess in a different area of a process, but with an added bonus of the tool's own problems and restrictions.
> With stacks, you can independently review and check each pull request, then merge everything together in one click.
Consider:
"With pull requests, you can independently review and check each commit inside the pull request, and then merge the entire pull request in one click."
Pull requests are stacked commits. This does not have to recurse; you don't need stacked pull requests, not to mention stacked pull request stacks.
A commit can already contain changes to multiple files. In many cases, even a complex change can be just one commit. A sequence of multiple commits handles all the remaining cases.
Stacked PRs sound like a use case for someone who never wants a PR to be a container for multiple commits, such that if a unit of work is best done as three commits, they want them in separate PRs. Oh, but now they are not related together, the way a stack of commits is related under one PR, so we need a meta-PR to contain PRs or something.
This could be a consequence of commits being sort of second class citizens in the GitHub UI compared to PRs. If you want a commit to be treated as PR, on the same level, you must create a PR with nothing but that commit.
Here's a common flow where I find stacked PRs are useful:
- I want to build feature X
- Ah, but it would work better if I refactored the module first
- I refactor then build feature X
- There's then some additional (and optional) cleanup work
As a reviewer I wouldn't want to see all this in a single PR, and the changes depend on each other so I can't open multiple independent PRs. Manual rebasing is fine but navigating the GitHub UI is then annoying, I have to mentally keep track of where I am in the stack.
Those could just be individual commits on a branch. Why does it need to be a stacked PR? That concept really only exists within the interfaces of these kinds of tools.
I certainly don't want to see that in a one commit. A PR has one more more commits, though.
The commits in a PR are already a stack of patches, and so PRs are already "stacked" as they are.
If feature X depends on the refactoring (cannot be rebased on the un-refactored upstream), it's part of the change; you can't just merge the feature and not the refactoring.
If the two are separable that way then, sure, it makes sense to ask for them to be separate PRs.
A refactor and then a feature implemented on that refactor is tightly coupled by definition. It would not make sense to implement the feature and refactor independently, because you’d be wasting time implementing a feature that you would have to refactor again.
I thought 'stacking' PRs was useful in two circumstances.
1. The PRs are across different related repos, so they literally can't be combined into one PR.
2. You want to keep producing work while the first PR is in review. So you stack subsequent PRs onto the same branch. Basically just pipelining.
But this feature doesn't seem to hit either use case, and instead just seems to be a different form of stacking commits into a single PR. The standard advice has always been to make atomic and meaningful commits (using e.g. rebase to tell a nice story for the reviewer). And reviewers can go through commit by commit if they like.
One of the nice things about jujutsu related to this is that when you update a branch, it rebases other branches started off of that branch. I often switch to jj if I want to split my work for easy reviewing, and it works great colocated with a clone created with git.
I get your point, but it kind of is AI related. The size of PRs since AI has made it much harder to review a diff. Stacking the PRs seems like a response to this problem.
We were benefiting from stacked pull requests in Phabricator for a decade before "AI" was a thing. Having well scoped commits that can be individually actioned by distinct sets of reviewers has always been extremely useful.
Been using it over the last week. Only complaint I had was that `gh stack rebase` was struggling rebasing after squash merges but I got a response that the rebasing had been improved so I'm looking forward to trying that out.
Lately I've seen a lot of people complaining about GitHub downtime, performance and overall quality.
Happy to see something in the right direction. I think they've woken up a bit. Still surprising how slow things can move at big companies.
Companies like Linear, Vercel, Zed and Cursor all seem to be looking at GitHub more aggressively though. I do suspect there will be more competition shortly.
I have been using it for a while and it has been useful.
One feature that I am still missing is to be able to stack PR across repositories. In other words, I want this stack to contains some PRs to the backend, some to the front, and some to ArgoCD in some specific order.
Both GitHub and GitLab have recently released new stacked MR tech: I guess everyone is submitting giant AI-authored PRs these days, and there's a real need to break them up into human-reviewable chunks.
Both are an improvement (GH's seems a little better, with their one-button merge that GL lacks) ... bit both are so incredibly "meh".
When are we going to see the major hosts give tools designed to help facilitate human code review? Simple example: lets say I want to leave notes in my PR (MR on GitLab). I can use the review comments to do so, but then I have a million comments to resolve at the end before I can merge, my comments look just like the reviewer comments (with extra UI for replying that's unecessary), etc.
It'd be so easy to just have a "sign post" feature to let authors annotate their code before reviewers review it ... and nobody offers this, or any other features focused on actually helping humans review. It's all just new command line features that save a bit of rebasing (which Claude can do just fine on its own).
Excited to release this more broadly so anyone can start stacking: https://gh.io/stacks
Would love to hear any feedback, especially with the UI and CLI. We've got a lot more updates to the PR experience in store!
Also happy to answer questions about the design decisions we made. There's a bunch happening behind the scenes, and it's one of the largest launches in GitHub history covering almost every service from Actions and protection rules to the CLI and mobile apps.
For example, merging an entire stack is completely broken in many cases: https://github.com/github/gh-stack/discussions/212
You can merge one by one, but if you're using squash and merge, you need a re-approval for each PR in the stack if you require reviews. This makes you lose out on arguably the biggest gain of stacked PRs.
The command line tooling (gh stack) helps to make things slightly less manual, but you still need to be very aware of how git rebase works, the tooling just helps automate it across multiple branches. For example, just running the "gh stack rebase" commands that the UI suggests won't work if your local branches are not in sync with the remote ones, and the tooling won't point that out to you.
I do find the stack UI quite nice. It's quite minimal compared to standalone PRs, but it's enough to show the relationship between them.
(My comments all assume you already have a good reason to stack PRs. This tooling just help to make the workflow easier, it does not give any new capabilities)
I think the bigger problem is that big AI PR's need a different way of reviewing. For example, the order in which the diff's are shown can make a big difference in how easy the commits are to read (e.g., function definition change first, then all call sites, then the tests).
Or maybe we should go to a system where diffs & comments are intertwined, a bit like how "Literate Programming" intertwines code and prose.
Literate diffs / literate pull requests... I haven't found anything like that yet.
For the people who work with stacked diffs (in phab/otherwise) this is exactly what they'd consider reviewing a well-curated set of commits one-by-one.
One distinction is that cognitively a unit of review (a PR, a diff) remains a single bound change. Comments are focused on that change and the PR does not grow with size of the feature
Another distinction is the ability to focus each part of the stack to a particular audience. One change may require review from an external team, another may be just your team mate, a third might be the consuming team. By focusing the stack to the different reviewers you can avoid ambiguity about "what a person is signing off on" in the stack.
aside: one thing that would be great for github reviews is the adoption of change ids such that comments persist across reviews with a rebase workflow.
> . By focusing the stack to the different reviewers you can avoid ambiguity about "what a person is signing off on" in the stack.
That can be easily done with comments. If the PR are orthogonal, they could have been split. And if they're not, I would really like to know how the part that I'm reviewing interacts with the rest of the changes.
Can't you run your CI locally? I know it's not feasible for some codebase, but at least the linting, formatting, unit tests, some integration tests should be able to be done locally.
Pre-approval the CLI tooling effectively enables easier automations around splitting a task into multiple atomic PRs - really great locally but then when you push they just show up as independent unlinked PRs.
Post-approval... they still show up as independent PRs. There's a small nav drop down up top listing the other PRs in the stack but that's it. Literally no meaningful UI changes.
The dropdown also allows you to perform a limited subset if the CLI functionality but this is similar to the ability to edit files in the UI - an optional extra casual use feature that won't be a part of dev workflows: the CLI (or IDE plugins I guess) would be the primary way to perform these actions.
It all left me wondering what the big deal with the preview not being a general release - it's extremely minor optional UI. The stacks cli has been general release since this was announced.
Whimsy is fine but that change made me super suspicious about what I was looking at.
It's like responsibility is shifted from the author to the tool. That has been tried before, and every time it seem to consistently produce the similarly shaped mess in a different area of a process, but with an added bonus of the tool's own problems and restrictions.
> With stacks, you can independently review and check each pull request, then merge everything together in one click.
Consider:
"With pull requests, you can independently review and check each commit inside the pull request, and then merge the entire pull request in one click."
Pull requests are stacked commits. This does not have to recurse; you don't need stacked pull requests, not to mention stacked pull request stacks.
A commit can already contain changes to multiple files. In many cases, even a complex change can be just one commit. A sequence of multiple commits handles all the remaining cases.
Stacked PRs sound like a use case for someone who never wants a PR to be a container for multiple commits, such that if a unit of work is best done as three commits, they want them in separate PRs. Oh, but now they are not related together, the way a stack of commits is related under one PR, so we need a meta-PR to contain PRs or something.
This could be a consequence of commits being sort of second class citizens in the GitHub UI compared to PRs. If you want a commit to be treated as PR, on the same level, you must create a PR with nothing but that commit.
- I want to build feature X
- Ah, but it would work better if I refactored the module first
- I refactor then build feature X
- There's then some additional (and optional) cleanup work
As a reviewer I wouldn't want to see all this in a single PR, and the changes depend on each other so I can't open multiple independent PRs. Manual rebasing is fine but navigating the GitHub UI is then annoying, I have to mentally keep track of where I am in the stack.
The commits in a PR are already a stack of patches, and so PRs are already "stacked" as they are.
If feature X depends on the refactoring (cannot be rebased on the un-refactored upstream), it's part of the change; you can't just merge the feature and not the refactoring.
If the two are separable that way then, sure, it makes sense to ask for them to be separate PRs.
1. The PRs are across different related repos, so they literally can't be combined into one PR.
2. You want to keep producing work while the first PR is in review. So you stack subsequent PRs onto the same branch. Basically just pipelining.
But this feature doesn't seem to hit either use case, and instead just seems to be a different form of stacking commits into a single PR. The standard advice has always been to make atomic and meaningful commits (using e.g. rebase to tell a nice story for the reviewer). And reviewers can go through commit by commit if they like.
What am I missing?
Happy to see something in the right direction. I think they've woken up a bit. Still surprising how slow things can move at big companies.
Companies like Linear, Vercel, Zed and Cursor all seem to be looking at GitHub more aggressively though. I do suspect there will be more competition shortly.
Both are an improvement (GH's seems a little better, with their one-button merge that GL lacks) ... bit both are so incredibly "meh".
When are we going to see the major hosts give tools designed to help facilitate human code review? Simple example: lets say I want to leave notes in my PR (MR on GitLab). I can use the review comments to do so, but then I have a million comments to resolve at the end before I can merge, my comments look just like the reviewer comments (with extra UI for replying that's unecessary), etc.
It'd be so easy to just have a "sign post" feature to let authors annotate their code before reviewers review it ... and nobody offers this, or any other features focused on actually helping humans review. It's all just new command line features that save a bit of rebasing (which Claude can do just fine on its own).
...but if the end result is more popularity of 'stacked' logical changes, yay anyway?