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)
We're rolling out a series of bug fixes for the issues with squash merging.
There's an internal system we have called CPRMC (Create Pull Request Merge Commit) that is used to evaluate whether a PR is "ready" to merge. This covers everything from mergeability (checking for merge conflicts) to rule evaluations (ensuring that approvals match the potential commit that will be created by merge) and more.
This becomes particularly difficult when squash merging a stack of multiple PRs because we have to calculate a series of squashed commits, then associate those back to the rules/reviews. This is relatively easy for the first PR, but for the second PR onwards this gets more complicated because the ancestor commits are squashed and don't exist on the branch as-is. And I won't get into how much more complicated it gets for multi-parent situations lol.
It's something we need to fix and it's the top priority for the team. Our numbers show that 99% of stack merges go through successfully, but we need to get that much higher.
Thank you for being an early user in the preview and bearing with us while we work out these issues!
Can you make sure there is good API support for stacks?
We use a custom merge queue and we want it to be able to land multiple PRs from a stack at once as separate PRs. Last I checked you had to land a single PR, rebase the stack, land the next and so on. This is very expensive in CI time (and wall clock time), vs simply testing part or all of a stack in parallel then declaring those merged. In essence a robot needs the ability to say “squash merge these 3 stacked PRs”, after the queue does its thing.
Yes that was one of our top priorities. For one, there's a fully public API for all stack operations. So if you don't want to use the `gh stack` CLI, you can build your own: https://docs.github.com/en/rest/pulls/stacks
The legacy API was fully synchronous, and since stacks of multiple PRs can often take more than 10s (our global timeout), we had to move to async.
We've had some folks already use this to integrate stacks into their merge queues. The great part is you can land multiple PRs in one atomic operation, and then there's one push to main with all your commits from multiple PRs. So instead of having to rerun the build/deploy for each, it can trigger for the last commit that contains all of the changes.
> There's an internal system we have called CPRMC (Create Pull Request Merge Commit) that is used to evaluate whether a PR is "ready" to merge. This covers everything from mergeability (checking for merge conflicts) to rule evaluations (ensuring that approvals match the potential commit that will be created by merge) and more.
By the way could there be a way to disable that when doing integrations externally? It seems to be quite costly (which makes sense), and the pull/ refs kinda bloat the reflist.
I’m sure that external integration is not exactly beloved internally but there’s really just a small handful of big annoyances which would make it so much nicer and more comfortable.
> This becomes particularly difficult when squash merging a stack of multiple PRs
I acknowledge that it is not trivial.
But this is 2026. Many people have solved this in in-house solutions. Every place I have worked at in the last 10 years had solutions in place. Some had wrinkles but it all worked in the end. Github sees itself as the leading provider of solutions in that space and has MSFT backing. Just saying that it's difficult is not good enough, quite frankly. People have been complaining about GH support for this for a long time.
> 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.
I'm struggling to imagine what it offers at all if that doesn't work! Is it just a way of manually marking another MR as a dependency in the UI so that it shows up with a red X if the other one isn't merged yet?
It's been >4 years since I've been out of Facebook and now have to use Github, and to this day I miss phabricator and landing stacked changes. When I first left and had to work with github I hadn't realized that this, to me, very basic, workflow is _not_ a feature!
Stacked PRs are so hard to implement for software not natively designed for them. Gitlab has been struggling with them too, despite 2.5 years since the MVP (https://gitlab.com/gitlab-org/cli/-/work_items/7473) . It doesn't help they want to do it without making any significant change outside the CLI, or that most developpers just... don't get it.
So many things on Github are now broken or utterly unusable, that this comment is not wrong. I mean even the code viewer/display is utterly broken and doesn't even perform standard text highlighting correctly. The folding marks often make no sense or are inconsistent. If one wants to see all forks of a repo, one has to go through "insights", I think few would suspect it to be located, and it doesn't show _all_ forks, according to the number displayed next to the fork button. The list of UI issues goes on and on. But then there are also the reliability issues, things being down every 2 weeks, or is it every week by now? Difficult to keep up with it really.
That's interesting, I get pushback when I suggest anything different and for devs under 30 I've had to remind them that git and github aren't the same thing. This is not to cast aspersions on them, just the state of things in the places I've worked.
Microsoft seems to be running the classic embrace, extend, extinguish playbook on github/git though. When it becomes impractical to join a team's workflow without github specific tooling then everyone will be forced to use gh.
We just today ran into a bug where if the branch a stacked PR points to is deleted, it can just stay stuck in "merging" without any additional feedback. I directly looked at the GH status page, because who knows, maybe the PR subsystem has a partial outage again, but no, it was just a bug in the stacked PR feature.
If you thought git was complex, wait until you get your 5 deep stacked PR from that nice coworker! Jokes aside this is really an anti-feature. Now coworkers can blow off your PR for much longer.
I dislike them reinforcing the component approach to delivering work through their examples, like the top screenshot showing "database schema changes", "api changes" and "frontend implementation" as separate branches in a stack.
So really, one does consider full stack a single feature, but unless they are reviewed in one go — which defeats the purpose of stacked branches and pull requests — you can end up landing one and a later review in branches higher in the stack needing changes in the lower branches even if they were already reviewed.
When you instead focus on full use-case per branch, but scope them down, it is much less likely you will need to change branches lower in the stack after they are reviewed.
Another obvious use-case is to do a pre-emptive refactor, though I actually prefer doing a post-refactor after the new use-case has been merged in — it's much easier to know the target best approach when you've got your use-cases right in front of you (or you may hit a similar problem as above).
FWIW, I remember fondly using bzr-pipeline plugin to bzr VCS ~15 years ago to do exactly this.
Thanks for mentioning this. It seemed odd to me, too, so I spent some time trying to work it out. As a reviewer, I'm not sure how I'm supposed to assess database or API changes without knowing how they're intended to be used. And deploying them independently seems odd, too, especially if you need to roll it all back.
I think in my ideal world there would be a clean history and I could review a PR commit-by-commit. But, you can't just approve a single commit, so there's a tooling problem there. And most CI runs on an entire push rather than individual commits. And increasingly I see devs using git as an offsite backup for whatever change they just made, rather than breaking commits up into logical chunks. In that workflow, squashed merges make the most sense.
It's probably flawed, but the mental model I came up with is each stacked PR collapses into what would have been an individual commit in a clean PR, with the advantage of being able to be reviewed separately from the other changes and forced to clear CI. And then the whole stack becomes what would have been a clean PR in the old model. That, I can kinda see the benefit of. But, merging only part of the stack into trunk is the mental hurdle I can't clear; it'd be like merging only some commits from a PR. It kinda reminds me of when projects used CVS.
I've really only seen stacked PRs used on projects where history is little more than an audit log. I'm keen to see how this gets employed by open source projects. I think there's a disconnect and it's likely I'm not going to really get it until I see it.
Ok, then how do you approve/take the first 2 commits and not the last one? Or how do you insert a commit in between 2 commits or address feedback on a given commit?
The person making the change is now going to have to run multiple confusing interactive rebases and git shenanigans, the rewrite the history of the PR branch on every feedback, then you have to re-review all the commits again because they are all different.
It’s possible of course to push all that complexity on the tooling. Have GitHub and git provide tooling for doing all that within the context of a single branch/PR. But why is that better? Multiple branches are easier to manage in git, and as long as they don’t conflict on the merge. Obviously if a feedback on PR#1 causes a conflict in PR#2 which causes a conflict in PR#3 it’s still tedious, but it’s a lot more doable than managing interactive rebases on every feedback comment.
At Facebook (i left >4 years ago) we used Phabricator where shipping stacked changes like this was table stakes. I still miss it. Some few random points, not really organized, i'm sure i'm forgetting bunch more benefits:
* I often used it as a way to make reviews significantly easier for the reviewer. If I split something more complex into smaller units where the small change seems obviously correct, it's much more likely i'll get a faster accept than with a very large change.
* Critically, once a unit of the stack has been approved, the approval will still stay with rebases of the whole stack.
* You can keep building up a stacs and once you think you have enough for whatever you are doing, ship the whole stack.
* Suppose you have a 'hole' in the reviews and you're missing a review for a middle part of the stack. You can still merge the bottom part up to where all are reviewed.
* Let's assume you're the reviewer: smaller changes is much easier to review. Also, each part of the stack builds incrementally on the previous one. With your example, suppose you're reviewing 'api changes' part of the stack, but it has failing tests because something is broken with the lower 'db schema changes' change - but otherwise, the 'api changes' diff looks fine - you can then accept it and this part of the stack is already reviewed. The author can now whenever fix their bottom-most change (db schema change) to have tests passing, and get someone to review that (perhaps someone completely different more familiar with db), and then rebase the 'api changes' diff, and _it will not_ require review because you haven't changed anything, just updated the diff underneath it. In this way you parallelized your approvals. Right now at work, using github, I have to serialize my PRs and can't effectively get things reviewed until the previous PR is approved.
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.
I apologize for being somewhat direct but what prior art did you engage with? Why are you making people create a branch for each change in a stack? Why do developers have to create new commits when iterating on the PR? Where is the proper support for interdiffs? What about change IDs?
The fundamental issue with GitHub -- really, its original sin -- is that the review model is wrong. It encourages a new commit + merge workflow, which is simply worse than an amend + rebase workflow. Basically every other review system in existence -- Gerrit, Phabricator, what Google and Meta have internally, the LKML -- works around stacks where people amend and rebase their commits when changing them. All of these have some notion of a "diff", with "versions" that are each tracked separately, and the ability in the review tool to do diffs between those versions. My hope with stacked PRs was that for once GitHub would use this as an opportunity to modernize its review system and bring it in line with all of these other ones. But sadly that just doesn't seem like it's on the cards.
About 4.5 years ago they had an internal prototype for changing PRs to be diff based instead of commit based. I even saw some screenshots of it! I assume the change was too drastic, or had too many corner cases so it was dropped. There is a lot of complexity in there system around PR status checks that I could see possibly having issues.
The optimistic person in me thinks now that have a major feature which rebases and amends all the time, they will dust that off and get it shipped. Like you said, is shows a fundamental miss-understanding of the problem.
I use `spr` which translates a local rebase + amend workflow into a GH-friendly new-commit + merge on the remote (which is then squashed). They are kind of equivalent from a 30k foot view but the dev experience when working with source control locally is dramatically different. And in particular I regularly have stacks of dozens of commits in flight -- if each commit were a series of commits then I would probably lose it.
Mostly. You can't do "show me this commit in the stack before and after the force push" though iirc. And you can't comment on the derived diff, even though that's what you'll be reading during re-review to see what changed.
GitHub constantly feels like features get requested with a one-sentence description, and then people who have never used any other major code review systems go build it without any further assistance or feedback, and eventually it just escapes containment and nobody tells the authors that there's a gigantic pile of bug feedback threads until almost a year later. Ten things get fixed, then another feature breaks out and focus shifts.
GitHub has a chance to get a generation of developers on to better coding practices. LLMs make it more feasible than ever to maintain high-quality patch series/stacked diffs — they can take care of all the mundane things like rebase conflicts for you. If I were in charge I would take this responsibility very seriously.
I guess the next best thing would be to port spr to this. (Probably time to start looking at this to be honest!) This makes me quite sad.
That is nowhere close to the experience Gerrit and Phabricator have, where you can diff two arbitrary versions in history. Comments on previous versions also get lost along the way.
Am I right this is only available through the CLI?
If so it’s a no go for me and my team. Which is too bad because it looks quite useful.
An addition ability I would love, which is a MUCH bigger feature and I recognize that, would be multi-repo stacks.
My company doesn’t use a monorepo, and I like that. But as we’ve been breaking monoliths sometimes a logical feature touches multiple repos.
Being able to have them all in a stack, each building on the previous logically though in different repos, would be amazing.
Maybe it should have a different name. PR Trains? PR Chains? IDK. But being able to have multiple projects in one logical review is the one benefit of a monorepo I’d like, and if I could get it a different way I’d love it.
I was using my usual stacked PR approach without the CLI and it detected the stack. So I think the CLI just does the heavy lifting for you (although I prefer to stick to vanilla git rather than learning a new tool).
Is support for cross-fork stacked PRs coming in the near future? I was surprised that didn't come before the feature entered public preview, as it seems rather important for the feature to be useful on public repositories.
Yes it will be coming! The reason it's taking a bit longer is because of the automated rebase that happens after you merge part of a stack. There are some legitimate security concerns because of this so multi-fork stacks (a stack which includes multiple different forks) are probably out of the question for now.
We will support a stack that is fully contained within a single fork, where the entire stack targets the original repo.
For example, a contributor who has a fork (user/buzz) of the original repo (org/buzz) could create the following stack:
haha, what if you add a filter that hides merge commits?
i appreciate that you are trying to make it possible for people who vibe code solutions to problems to get code merged by people who have made GitHub their lifestyle. but surely you see how, in my framing there, the people who are worried about how their history "looks" are the problem
I like it based on initial testing today. I already use my own local UI for managing stacked PRs so I can see the dependencies as a tree view and the review + CI status for each, it would be good to also have those in the GH web UI. Maybe I missed it but it looks like merging just the bottom of the stack in the web UI might not be supported? Happy to share the workflow / code, it would be nice if it was supported within GitHub's native tools.
> Also happy to answer questions about the design decisions we made.
Why did you choose extra pull requests as the division of work instead of building out a decent UI for reviewing/applying/reworking at the commit level? I assume there's some extra insight that made you ignore the mailing list "series of patches" workflow that inspired this whole thing and go with "series of series of patches" instead.
I'm trying to understand what you mean, because it's not obvious to me at all. If you read LKML you'll see stacked PRs has been the norm for years. I'm assuming you want the `gh stack` porcelain into the git cli? We'd first need to add PRs as a porcelain to the git cli for it to make any sense, right?
Gerrit manages stacked changes with standard git tooling, except for the tiny change-id hook. Similar stable change identifier is also what enables Jujutsu to do its magic. Standardizing around something like this would be greatly beneficial, instead a ”gh” CLI is now needed to push a commit.
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.
But couldnt you just create a PR2 that targets your PR1 branch?
What does stack contribute that multiple PRs targeting each other dont?
i.e. like this where each one targets prior
PR1 db_migrations
PR2 backend_base
PR3 adds_frontend_scoobydoodle
PR4 adds_some_landing_page_thingy
PR5 probably_have_to_fix_something
Or is stacks just a feature built to make this type of PR stacking easier to review?
> Or is stacks just a feature built to make this type of PR stacking easier to review?
Pretty much, yes. It’s just a UI to make it clear that those 5 PRs are liked (stacked) and gives some tooling around reviewing, merging and managing them, reduce redundant CI runs if desired, etc
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.
The PRs may be orthogonal but still be dependent. Feature X depends on improvement Y which also needs bugfix Z. You might go and implement X in a branch, tweaking the codebase as you go, but split the branch apart for review. You put X/Y/Z up, but X contains Y and Z, which means you can't request reviews for X without Y and Z merging, or else have a bunch of extra code that gets in the way.
Let's say that Z has an error (some assumption that does not hold), and needed to be reverted. How does that impact X's viability? I wouldn't trust any reviews of X after that.
I strongly believe that PR should be compared to the main branch, and not rely on unmerged code. Unless you merge everything together in one go. And in the latter case, everything should be reviewed together.
If the tooling allows rollbacking X, Y and Z as a set, it could make sense ?
I'm also on the "compare to the main branch" camp in general, but will sometimes end up with a set of X,Y,Z branches that have different purposes but all depend on X.
More often than not, the base dependency is a set of constants or additional class/methods that could be released with no impact (no reference in live code) but still need a somewhat lenghty review process. Reverts would be happening on the higher level PRs, which hopefully are independent.
This articulates a source of unease I was having trouble pinpointing. Encouraging piling up changes like this puts pressure on the reviewer to approve things as-is because "i've already built Y and Z on top of X so changing X now is a pain".
In my opinion there's already too much of a bias toward stamping PRs, and organizations that maintain high standards do it partly by resisting that bias in key parts of the codebase so people can push back on things that are poorly engineered or hard to maintain.
> What's the benefit of this type of stacked PRs over a well-curated set of commits, and reviewing per commit?
What I can see is that you can easily append commits to e.g. the first PR in a stack, which would insert them into the middle of sequence of commits.
This will require rebasing and fixing the subsequent PRs in a stack the same way you'd need to rebase and fix the subsequent commits in a mega-PR. But it makes the right thing easy (keeping all the commits to the foundation of the change together) rather than makin the wrong thing easy (appending fixup commits across the entire change in a random order so that the actual foundational change is lost).
Keeping all the foundational commits together also keeps all the discussion over the foundational change together.
You could argue that you'd want to only do the foundational PR and stop, but doing the whole stack of PRs gives the reviewers more information about where you're going, and allows work to continue asynchronously.
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.
There is real value in having all the messy commit history, especially now with AI, but you do need some kind of description on them that indicates what they are.
One use I have got from it is asking an agent to go through the git history and categories the mistakes/bugs, then turn the common ones into CI checks or AGENTS.md rules.
A well curated history just hides a lot of valuable info.
This is it, but also, because there was no way of asking a reviewer to review a single commit and then merge only that commit out of 2+ commits without a lot of ceremony, work streams had to be completely orthogonal to parallelize anything . Now I can fully develop a sequence of 20 changes (each a single commit) and start getting reviews and merging while still progressing towards the goal. I’ve been doing this for 2years with graphite and more before that manually or in other systems/cultures that actually can review a commit/patch and merge that thing.
Honestly all GitHub needed to do was make reviewing and merging commit(s) from a PR possible and that would also been neat.
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
I don't have experience with the stacked PR workflow and often find myself asking the same questions you are.
As far as I can tell, the biggest benefit of stacked PRs over just making a coherent series of commits, is that it might make it easier to start work on your second PR before you merge the first one?
With human-in-the-loop coding, that sounds like it could lead to a lot of wasted work if the first PR gets substantial feedback. But with agentic coding, I can imagine how it might be desirable to keep the agent chugging while the first PR is under review.
Interested in learning more about it and generally agree that AI is stressing the current review paradigms a lot of us are accustomed to.
For me it's hard to imagine not starting on the second PR after submitting the first one, regardless of AI or stacked PRs. For focused work I find it important to avoid context switching, stay in the zone and keep everything in my head. Wasted work in comparison feels less significant to me.
If review is fast I'd be switching back and forth between tasks throughout the day. If review is slow I might end up implementing a feature over the course of two weeks rather than two days. With reviewers in different time zones, limited time or doing their own focused work, it adds a lot of latency going back and forth for every PR rather than iterating on a stack of PRs.
Personally I find the biggest benefit is that it lets both the author and reviewers work at the pace that works for them, with reduced context switching and latency.
If you make good commits and each of them is a valuable unit of work; having tooling that can manage rebasing them and creating a reviewable PR for each is super valuable for maintaining momentum and making reviews easier.
You can’t merge one commit at a time in a PR. In a stack, if the first 4 parts of a feature are good to go and there’s a problem with the 5th, the whole thing doesn’t need to be blocked.
The issue you’d have then is the CI might not be green after the 4th commit but it is after the 5th. A single PR will hide that, so you’d need a way to run the CI on the subset of commits you want to extract. It’s also much easier to isolate those blocking comments on the 5th commit if it’s in its own PR and not mixed with all the review comments on the other ones.
I don’t really see it as diverging much from the underlying git tool TBH - it’s still just git branches pointing at each other.
It isn't arbitrary. A branch is the unit of change. You can stack branches on top of each other and merge them one at a time. You can also keep adding to the end of the stack as needed.
I understand that GitHub kinda ate the world on this, but using a branch PR as the basic unit of change seems like an arbitrary choice to me.
Torvalds invented Git for work on the Linux kernel, and the basic unit of change there is commits over email. It's not uncommon for them to take some commits but reject others.
Which isn't meant to say "pull requests are obviously wrong and commits over email are obviously correct", but rather to point out that the idea of a take-it-or-leave-it branch isn't some kind of natural unit of contribution
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.
Conceptually continuous integration is generally integrating 2+ different lineages of code together which is more common with multiple developers although I suppose it's becoming more relevant with agents creating a bunch of worktrees with different things.
In practice, CI has taken the same path as "DevOps Engineer" ie most people just mean "automated test server"
The opposite of CI is more-or-less merge windows or merge-fest like Linux where everyone mails in their changes and someone manually integrates.
> Conceptually continuous integration is generally integrating 2+ different lineages of code together
> In practice, CI [often means] "automated test server"
Could you say more? I use "CI" to refer to the automated processes that run tests and (maybe) deploy code as it is merged to some blessed branch. It's what continually integrates the new code into the existing code. What am I missing?
> You can't have mac/windows/linux/whatever all locally simultanously.
Why can't you? That's what VMs are for. And even then, most cross-platform codebases have an abstraction layer that rarely changes. So even testing on one platform can raise your confidence very high.
> Also, it is much harder to enforce "everyone must run each commit through the CI equivalent properly"
Again why? I wouldn't care about the dev's local branch. But what is send to the main repo can be easily scripted to run the CI on every commit. You just send the result back with each commit that fails. They can replicate the same workflow on their local workspace as a pre-push process.
You can't run MacOS in a VM on non-Mac hardware without violating Apple's EULA.
> But what is send to the main repo can be easily scripted to run the CI on every commit.
Sure, this could work. I didn't say it was impossible, just more difficult. You have to build all of this support on top of the system that already does it for you: have your forge run CI on every commit.
Heh, it's a fun reminder that different people work on different things.
Sure, I could load up my build machine with mac/windows/linux/android, with multiple versions of each. Emulating x86+x86_64+arm32+arm64+aarch64+... is also doable, sort of.
But considering that the real CI runs several thousand hours of tests total across all platforms, I think I won't.
Also, my Electron-based IDE needs those 10s of GB to edit text. How can you possibly edit a 1KB text file with less than 1GB of RAM?
Not to mention clangd that needs to do its ultra-important work Right Now so I can invalidate it all with my next edit. That's probably the biggest RAM hog of them all.
I’ve been using stacked prs for many years, AI did not change anything in that area. The advantage is that you can control what lands in the trunk independently of what a particular review contains, and that you can commit freely without having to later go back and do archeology on past commits to make them look reviewable. The unit of commit and the unit of review is not the same and you shouldn’t try to make them so, they have entirely different purposes.
I would say that it makes it easier to design a PR and then go back and update that PR as things evolve. For instance, you might decide you need one table so your first PR in the stack adds that table. But then you finish up with 2 or 3 more PRs and you get reviewed and you and your colleagues decide to add a 2nd table. Now you get to go back to that first PR, add the 2nd table and then you get to cleanly review that 2nd table. Then each PR in the stack also gets a clean small addition to handle the table, that can be reviewed in its own context with smaller diffs.
So the idea is you can much more cleanly isolate changes for large features.
> What's the benefit of this type of stacked PRs over a well-curated set of commits, and reviewing per commit?
Even if the reviewer does the review commit-by-commit, all the comments and discussions will be on the same PR leading to multiple ongoing conversations about different topics that would be split if the PR are stacked. Also, all the new commits addressing the comments with spoil this commit-by-commit design, as the previous commits will be outdated and the new changes will be on top of those. I think it's beneficial for new changes to be a separate commit and not rewriting history, to not force the reviewers to re-read everything but just the latest changes.
1. Github's UI doesn't really support reviewing individual commits in a big PR.
2. It also can't merge subsets of commits from a single PR. E.g. if you have two commits, A and B, where B depends on A... sure you can make a PR containing A and B, but if A gets approved and B doesn't, then you can't merge A.
3. The thing you want to do with a set of commits and reviewing each commit IS stacked PRs.
This is one of the biggest changes to hit GitHub in many years. I'm really glad to see something like this deployed to one of the largest forges in the world, hopefully it will expose a lot of developers to workflows that they didn't even know about before.
If you buy the idea that stacking produces better software, then this also has the opportunity to really help out quite a few people.
Stack management: automatically rebasing all dependent PRs on any downstack change.
Ability to view & navigate the stack in the reviewer UI.
Ability to merge a whole stack with one command.
Looking at the way GitHub are selling this “feature”, I feel like some of the engineers who are going to be excited about this feature for “reviewability” reasons are, in particular, those who’ve forgotten that they should be splitting changes into multiple logical commits inside a PR. And instead of that they’re now going to use multiple, single commit branches and stack them because stacked PRs are a “new” “feature”.
And the upshot for the LLM providers is that they get to charge for n reviews, instead of one.
I think plenty of people explained the difference between stacked PRs and individual commits in 1 PR. You’re not wrong, but it’s just a matter of path of least resistance. There is no way to leave a comment on a particular commit in a PR. Also all commits addressing PR feedback get tucked at the bottom of the commit list. Unless you do some crazy git gymnastics and rewrite the PR history and confuse everyone. With stacked PRs you also (as a maintainer or a reviewer) have the option to merge some and not others. Like here are 3 stacked PRs, one for provisioning some AWS or Azure resources that I’ll need, one for implementing the APIs using those resources, and one for updating the UI to use the new APIs. You can then say “let’s get the 2 backend PRs in and hold off on the UI as we’re changing that entire view”. You can’t do that with multiple commits in a PR without asking the person to redo the PR, then you’re back to git-foo.
Yes, GitHub could have made the UI allow a “per commit” comments somehow, then allow you to select the set of commits to include in the merge somehow, then write a blog post on how to manage “Address PR comments #1” commits. But the stacked PRs solve all that. Not to mention how people treat commits as their own internal save states. I always enable “squash and merge” option because I think it makes a lot more sense to have 1 commit on main per PR where all the context of the change is either in the commit message or the linked PR.
Also LLM providers charge per token. Charging per “work unit” is still not a solved problem. You can’t charge per “review” when your cost is per token. Just like airlines can’t charge “per ticket”, they have to charge differently depending on the destination. Unless you invent some bs arbitrage to lure users and eventually bait and switch on them.
You can read each individual commit and review the PR as a whole. This is the way many people design and review PRs.
You don’t need to merge those changes progressively. If you do, you go through exactly the same process of creating a separate branch and PR. The only difference is that GH has now added some UI and automation for rebasing and merging the PRs. In the past we would have explained the chaining in the PR and rebased manually.
You don’t need CI to run on each commit.
You only lose your commit history if you squash merge, many people don’t, and you don’t have to either.
The arguments come from angle that doesn’t appear to be aware that stacked PRs were a thing before GH made these UX improvements.
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 a 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. So then, what would have been a single PR with four commits that you could merge with one click is now four PRs. Which you want to be able to merge them with one click.
> 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
Except you can’t really do that on GitHub, the “unit if review” is the PR so reviewing commits is adhoc, inconsistent, and awkward, and tracking their changes as they get fixed up is a pain. “Splatting” that as PRs is not the nicest way to do it green field, but it’s an evolution that makes sense in GitHub’s model.
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.
They don't. But reviewing individual commits in the GitHub UI is hard.
A set of stacked PRs is exactly the same as a line of commits. The only difference is the UI, but the UI is the important bit here because lack of UI is what's stopping folk from doing that today.
Even when I've developed my changes as a stack of commits, I'll feed them to my team one commit (and one PR) at a time so they're easier to review — and I discovered that GitHub had turned on stacked commits UI because for one particular project I'd manually created a set of PRs in advance (with the right bases) and GitHub offered to create a stack out of them.
> They don't. But reviewing individual commits in the GitHub UI is hard.
So instead of solving that problem, GitHub developed tooling around a workaround for that problem (targeting a PR at another branch that also has a PR).
Expanding reviews to allow per-commit reviews avoids the need for managing additional branches and all the headache that comes with it.
Indeed. But lots of people have never even heard of Gerrit :P.
And the implementation feels very much like it sits in the UI layer, rather than further down the stack.
I'm not trying to claim stacking PRs in this way is the best way (it's not). But it does add an extra affordance for those who want it without burdening those who don't with the need to understand why someone would prefer it.
And there are also plenty of ways that people have been working around GitHub's (and to a lesser extent, git's) lack of tooling for working on changes in this way. I'm sure they have customers clamouring for the feature; whether they'll be happy with what they get remains to be seen.
(Very happy jujutsu user here, my tooling makes it really easy to create stacked commits with a stable identifier that maps really easily to branches and then onwards to running `gh stack`, but what GitHub have delivered is definitely still lacking)
I’m a pretty clean committee. About every graphite stack I’ve worked on for the past 2years has been single commit per PR. The tooling managing all the rebasing and PR bases is great.
The sad fact of life is that too many developers are used to pushing PRs with unprincipled commits, and relying on squash merges.
The approach that GitHub chose can show those people almost immediate benefits, which is surely the better path towards adoption than trying to reeducate everyone to adopt a development flow based on clean rebases.
And for those of us who do prefer clean rebases, the thing they built is still useful.
A bunch of details aside, the major conceptual thing that the email based flow has which is still missing in GitHub's data model is the ability to have a discussion on the stack as a whole.
Yeah, I think it's largely a UI issue! I really want a UI that lets me review distinct changes that are dependent on each other, and handle comments/changes neatly within that structure. I've found GitHub quite lacking there historically.
Also, if you're the mchristen I know, then I think we've had this discussion before haha! Hope you're well :)
They could but they don't belong together. A PR should be about one thing. Refactoring one module for another's sake should be done in another PR. If not for reviewing, for revertability, and future debuggability.
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.
This is literally the point of stacked PRs. You implement the refactor in branch A, then branch B is created on top of that so you can implement your feature. Then you make separate PRs, one for merging branch A into main, and another for merging branch B into A. The GitHub feature just provides a nicer UX when interacting with such PRs by clearly showing dependency and allowing you to merge a stack together.
I don't mind rebasing, so that's not really an issue.
The problem I sometimes have is when I queue up 4 or 5 PRs in the afternoon and expect someone to take a look in the morning.
The diff of A into master looks OK, but then the diff of B looks like AB, and the diff of C looks like ABC - each PR has changes that will have already been merged once earlier PRs have been accepted.
My way around it was to raise E as a PR into D, raise D as a PR into C, etc. Then once approved, I change their destinations back to master for the actual merges.
It really confuses reviewers though, even though it's meant to make it so they only see the appropriate changes.
This is stacking but with getting no help from the platform tooling or UI. Your ready and stacking feels great. I’m a 2 year user of graphite and it really makes work a lot more fun not managing all the PR, bases, etc. make good commits, split each into a branch:PR, record faster, async progress while getting reviews, etc. it’s good stuff
We've been using the pancake emoji internally so we thought it was a fun easter egg. It'll only be up for a few hours and then will go back to the regular icons :)
Remember when the Internet was a culture? Now you attempt the most tame possible attempt at that culture and people go into the Issue tracker to throw their little fit.
Funnily enough the two features that I've missed from phabricator are Stacked Diffs and the per-user opt-in whimsy mode, maybe GitHub can copy the latter next? :D
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.
Yes, and in fact, JJ is much more than that. One of the other features I use quite heavily is that, in JJ, you can essentially check out multiple branches at the same time by just creating a local merge. JJ will keep your local merge updated as you rebase the branches it builds on. I have written about it here: https://sarthakag.bearblog.dev/from-git-to-jj-jujutsu/
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 haven't used git-town, but from a cursory look it appears to be a various collection of gitops improvements for day to day things, including some for stacking.
git-spice is specifically targeted to be useful for PR stacking and doesn't require you to do anything differently from normal git operations that you likely use already. It has a bunch of really nice flows and doesn't try to step outside the bounds of what is needed to easily stack PRs
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.
I hear you. We had to start with something a bit more minimal, but we are working on a much broader revamp for the PR UI. Part of that will include a persistent view of the stack so you always know you're working with a stack and easily navigate between the layers without a ton of clicks.
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.
> 2. You want to keep producing work while the first PR is in review. So you stack subsequent PRs onto the same branch.
Instead of using the same branch, make new branches from that parent and commit there.
The cool thing about that approach is that (at least in git-tower app) is when you edit a parent branch after pr comments, all those new commits will be automatically “restacked” on descended branch (children branches will be rebased on new state or parent, incorporating the hew fixes)
When will this support "trees" of pull requests, with dependent changes? In my experience with stacked changes (from Google), it is often the case that changes do not stack up as a linear history. I imagine that would especially be the case these days with parallel coding agents.
You ideally need a directed graph where descendants can have multiple parents (which JJ supports). If you can't, then the linear tree is just as good I think.
Say you do change A, add a protocol buffer API definition, then implement the server logic (B) and the front end code (C) so that both depend on A but not each other. That can be in a tree. But now you want to add an integration test (D) that depends on B and C. The tree doesn't help you there, and you were better off making it a linear chain by arbitrarily picking one of B or C to be dependant on the other so that you have a code state with all of A,B and C applied to create D on top of.
Coordinating 2 people working within a single linear stack is unnecessary overhead, even harder for humans to manage. It's easier to let them work off of a shared point individually.
As someone who previously used GitHub a lot, and now works with stacked changelists (PRs) a lot, I'm not sure this really changes much.
If there's an expectation that you might merge a whole stack, I think you're aiming for the wrong thing. And it seems like landing the whole stack is the biggest push GitHub are making here. Part of the point is independently reviewable and independently mergable. If you're going to merge in one go then just put everything in one PR and review commit by commit in that PR. The commit by commit review flow used to suck, but since ~2021 it has been fine.
I feel like GitHub have built what users (who haven't used a true stacking system) asked for, not what they actually need to change their workflow for the better.
A great implementation would be asking hard questions like: what's the role of a single commit? Should PRs be single commit only? What's the real benefit here? How do you encourage smaller units of review (because it doesn't look like this does).
I would love to see more interactions from dev side in GH discussions rather than answering on HN. I think not responding anything there pushes the image of github not caring for the community
I’d still love a way to be able to rewrite commits at merge time, via Actions or otherwise.
The most obvious case is something like adding a Reviewed-By/Signed-off-by trailer based on reviewers, but there’s also a decent number of big projects that want more semantically meaningful commit identifiers (think more revision, in a numeric sense).
It seems like making merges async should make it a lot more possible to implement that!
I personally see no benefit using this. For large changes I often completely work locally until it's done. I commit everything logically and when everything is done I push and make one PR. The commits are not fully done as they work towards the main goal of the PR. If the team argues before the start of the feature that the individual commits are needed we split the ticket. This stacking sounds a lot like shit you need for shit made by LLM's
The stacked PR pattern long predates LLMs. Yes LLMs make them more common and frequently steer you in that direction. But it’s by no means a new “LLM” thing.
In the scenario you described of your team splitting the tickets, this gives you a UI to manage the PRs of the multiple tickets so you are no longer blocked on merging PR#1 before you can proceed to PR#2. Yes you might have to deal with conflicts, but you would have had to deal with that regardless.
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.
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.
Meh. Stacked PRs (where a PR is already a stack of commits, and reviewers can perhaps communicate with each other to coordinate scope/responsibility) are a bit like tab groups in the browser when tabs, multiple windows, and workspaces already existed for maintaining organization. This new feature clearly scratches an itch for some users but creates more complexity (yes, even if you don't interact with it) for people already comfortable with the status quo.
It definitely isn't. People have wanted this for many years. It's an obvious workflow. There's been a feature request since at least 2020 and I'm sure there were earlier ones: https://github.com/cli/cli/issues/2693
The issue I have with stacked PRs isn't merging, but rather, when I change branch A, and I'm working on branch C, I then need to merge A into B and then B into C just to continue working. Collapsing/merging them at the end is the easy part.
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.
And we solve this by splitting into 2 PRs that still merge at the same time. Oh, super useful!
Only if your reviews are so shallow that you don’t try to reason about the state of PR B merged to PR A, which would then be merged to main, and your real problem is just GitHub UI failing to handle a giant PR, which we all know that this feature is attempting to help with.
Probably a few years too late on this. Its for a time when humans still reviewed PR's. For better or worse, that is a thing of the past. The review step has shifted heavily left and newer re-imagination of Git (like Origin) will almost certainly not have a concept of a "PR" let alone stacking them
It's good to have this feature, but it is still up to the individual developers to separate the PR work in a way that can be merged "all or some and in which order". It can make organizing, reviewing and rebasing easier but a PR with repeat, broken or overriding code can screw up just the same. I guess what I mean is, don't expect it to just sort out multiple PRs that wouldn't have worked together without it.
I remember having tried these on Gitlab a few years ago. One PR depending on another, depending on another ... It didn't ultimately make for a good experience. Partly that was due to Gitlab's interface, but also it wasn't necessary to complicate PRs even more.
This is a huge feature if implemented well. Going from big organizations with their own custom-built versions of PR stacking back to vanilla GitHub was a huge productivity hit for me.
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).
The case where I need stacked PRs is when I have a ton of changes and I want to upstream them. I have so many changes that I have probably written code in this order:
1. feature1 work
2. feature2 work
3. architecture rework
4. docs
5. feature3 work
6. optimization
7. docs
8. feature4 work
9. security fixes
10. optimization
11. docs
12. last pass security fixes
By the time I want to upstream, I probably want to reorder my commits and generate on PR per theme (arch, feature1 + docs + optimization, feature2+docs + optimization, etc) before I submit a bunch of PRs.
GitHub stacked PRs solve none of my problems. Stacked PRs doesn't take care of the reordering of commits, it doesn't take care of rebasing changes, it adds very little on top of what I was already able to do by saying "this is PR 1 out of 7, this is PR2 out of 7 and build on top of the branch that I used for PR1/7, etc".
> it adds very little on top of what I was already able to do by saying "this is PR 1 out of 7, this is PR2 out of 7 and build on top of the branch that I used for PR1/7, etc".
That's literally all it's supposed to do. Make that dev flow less awful so you don't have to say "by the way this PR depends on #123, I will change the target branch when that is merged" and nonsense like that.
Well, then it provides so little they could have not done anything at all as well. Useful stacked PRs would be something that uses AI to split my large branch/PR into smaller PRs for upstream to review. Claude does that for me.
They've provided a skill with their stacking CLI to provide guidance to any coding agent and the Copilot harness now ships with a pr-stack command to do exactly what you're saying for PR splitting FYI: https://twitter.com/_JeremyMoseley/status/208219039710799469...
It's not "so little". I've wanted this for ages. Trying to submit a chain of PRs is a horrible experience without support for it. This is nothing to do with AI.
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.
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)
There's an internal system we have called CPRMC (Create Pull Request Merge Commit) that is used to evaluate whether a PR is "ready" to merge. This covers everything from mergeability (checking for merge conflicts) to rule evaluations (ensuring that approvals match the potential commit that will be created by merge) and more.
This becomes particularly difficult when squash merging a stack of multiple PRs because we have to calculate a series of squashed commits, then associate those back to the rules/reviews. This is relatively easy for the first PR, but for the second PR onwards this gets more complicated because the ancestor commits are squashed and don't exist on the branch as-is. And I won't get into how much more complicated it gets for multi-parent situations lol.
It's something we need to fix and it's the top priority for the team. Our numbers show that 99% of stack merges go through successfully, but we need to get that much higher.
Thank you for being an early user in the preview and bearing with us while we work out these issues!
We use a custom merge queue and we want it to be able to land multiple PRs from a stack at once as separate PRs. Last I checked you had to land a single PR, rebase the stack, land the next and so on. This is very expensive in CI time (and wall clock time), vs simply testing part or all of a stack in parallel then declaring those merged. In essence a robot needs the ability to say “squash merge these 3 stacked PRs”, after the queue does its thing.
For merging, we have an API but had to move it to a new async method: https://github.github.io/gh-stack/reference/merge-api/
The legacy API was fully synchronous, and since stacks of multiple PRs can often take more than 10s (our global timeout), we had to move to async.
We've had some folks already use this to integrate stacks into their merge queues. The great part is you can land multiple PRs in one atomic operation, and then there's one push to main with all your commits from multiple PRs. So instead of having to rerun the build/deploy for each, it can trigger for the last commit that contains all of the changes.
Also what about external merges? Is there a way to sanely interact with stacks when merging locally or via external tooling?
They do indeed have APIs you can use in your mergequeue, I'm happy to share notes on how we built it so you can add it to your mergequeue.
By the way could there be a way to disable that when doing integrations externally? It seems to be quite costly (which makes sense), and the pull/ refs kinda bloat the reflist.
I’m sure that external integration is not exactly beloved internally but there’s really just a small handful of big annoyances which would make it so much nicer and more comfortable.
I acknowledge that it is not trivial.
But this is 2026. Many people have solved this in in-house solutions. Every place I have worked at in the last 10 years had solutions in place. Some had wrinkles but it all worked in the end. Github sees itself as the leading provider of solutions in that space and has MSFT backing. Just saying that it's difficult is not good enough, quite frankly. People have been complaining about GH support for this for a long time.
> 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.
I'm struggling to imagine what it offers at all if that doesn't work! Is it just a way of manually marking another MR as a dependency in the UI so that it shows up with a red X if the other one isn't merged yet?
Ultimately they have become a monopoly so it is kind of expected.
Even though I live in a western country, just one of my clients after all these years of being self-employed, uses GitHub.
Nobody else would ever use it. And why would they? Especially for proprietary applications.
Microsoft seems to be running the classic embrace, extend, extinguish playbook on github/git though. When it becomes impractical to join a team's workflow without github specific tooling then everyone will be forced to use gh.
So really, one does consider full stack a single feature, but unless they are reviewed in one go — which defeats the purpose of stacked branches and pull requests — you can end up landing one and a later review in branches higher in the stack needing changes in the lower branches even if they were already reviewed.
When you instead focus on full use-case per branch, but scope them down, it is much less likely you will need to change branches lower in the stack after they are reviewed.
Another obvious use-case is to do a pre-emptive refactor, though I actually prefer doing a post-refactor after the new use-case has been merged in — it's much easier to know the target best approach when you've got your use-cases right in front of you (or you may hit a similar problem as above).
FWIW, I remember fondly using bzr-pipeline plugin to bzr VCS ~15 years ago to do exactly this.
I think in my ideal world there would be a clean history and I could review a PR commit-by-commit. But, you can't just approve a single commit, so there's a tooling problem there. And most CI runs on an entire push rather than individual commits. And increasingly I see devs using git as an offsite backup for whatever change they just made, rather than breaking commits up into logical chunks. In that workflow, squashed merges make the most sense.
It's probably flawed, but the mental model I came up with is each stacked PR collapses into what would have been an individual commit in a clean PR, with the advantage of being able to be reviewed separately from the other changes and forced to clear CI. And then the whole stack becomes what would have been a clean PR in the old model. That, I can kinda see the benefit of. But, merging only part of the stack into trunk is the mental hurdle I can't clear; it'd be like merging only some commits from a PR. It kinda reminds me of when projects used CVS.
I've really only seen stacked PRs used on projects where history is little more than an audit log. I'm keen to see how this gets employed by open source projects. I think there's a disconnect and it's likely I'm not going to really get it until I see it.
The person making the change is now going to have to run multiple confusing interactive rebases and git shenanigans, the rewrite the history of the PR branch on every feedback, then you have to re-review all the commits again because they are all different.
It’s possible of course to push all that complexity on the tooling. Have GitHub and git provide tooling for doing all that within the context of a single branch/PR. But why is that better? Multiple branches are easier to manage in git, and as long as they don’t conflict on the merge. Obviously if a feedback on PR#1 causes a conflict in PR#2 which causes a conflict in PR#3 it’s still tedious, but it’s a lot more doable than managing interactive rebases on every feedback comment.
* I often used it as a way to make reviews significantly easier for the reviewer. If I split something more complex into smaller units where the small change seems obviously correct, it's much more likely i'll get a faster accept than with a very large change.
* Critically, once a unit of the stack has been approved, the approval will still stay with rebases of the whole stack.
* You can keep building up a stacs and once you think you have enough for whatever you are doing, ship the whole stack.
* Suppose you have a 'hole' in the reviews and you're missing a review for a middle part of the stack. You can still merge the bottom part up to where all are reviewed.
* Let's assume you're the reviewer: smaller changes is much easier to review. Also, each part of the stack builds incrementally on the previous one. With your example, suppose you're reviewing 'api changes' part of the stack, but it has failing tests because something is broken with the lower 'db schema changes' change - but otherwise, the 'api changes' diff looks fine - you can then accept it and this part of the stack is already reviewed. The author can now whenever fix their bottom-most change (db schema change) to have tests passing, and get someone to review that (perhaps someone completely different more familiar with db), and then rebase the 'api changes' diff, and _it will not_ require review because you haven't changed anything, just updated the diff underneath it. In this way you parallelized your approvals. Right now at work, using github, I have to serialize my PRs and can't effectively get things reviewed until the previous PR is approved.
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.
The fundamental issue with GitHub -- really, its original sin -- is that the review model is wrong. It encourages a new commit + merge workflow, which is simply worse than an amend + rebase workflow. Basically every other review system in existence -- Gerrit, Phabricator, what Google and Meta have internally, the LKML -- works around stacks where people amend and rebase their commits when changing them. All of these have some notion of a "diff", with "versions" that are each tracked separately, and the ability in the review tool to do diffs between those versions. My hope with stacked PRs was that for once GitHub would use this as an opportunity to modernize its review system and bring it in line with all of these other ones. But sadly that just doesn't seem like it's on the cards.
The optimistic person in me thinks now that have a major feature which rebases and amends all the time, they will dust that off and get it shipped. Like you said, is shows a fundamental miss-understanding of the problem.
GitHub constantly feels like features get requested with a one-sentence description, and then people who have never used any other major code review systems go build it without any further assistance or feedback, and eventually it just escapes containment and nobody tells the authors that there's a gigantic pile of bug feedback threads until almost a year later. Ten things get fixed, then another feature breaks out and focus shifts.
I guess the next best thing would be to port spr to this. (Probably time to start looking at this to be honest!) This makes me quite sad.
Allowing two different workflows – even within the same project – just shows the lack of strategy for how this should work.
Re-educating when and when not force-push is a holy sin is also a barrier to alignment.
There’s enough ways you can match up commits, with plenty of prior art in this space.
Am I right this is only available through the CLI?
If so it’s a no go for me and my team. Which is too bad because it looks quite useful.
An addition ability I would love, which is a MUCH bigger feature and I recognize that, would be multi-repo stacks.
My company doesn’t use a monorepo, and I like that. But as we’ve been breaking monoliths sometimes a logical feature touches multiple repos.
Being able to have them all in a stack, each building on the previous logically though in different repos, would be amazing.
Maybe it should have a different name. PR Trains? PR Chains? IDK. But being able to have multiple projects in one logical review is the one benefit of a monorepo I’d like, and if I could get it a different way I’d love it.
We worked with Sameen over the last month to add support for GitHub stacks into our mergequeue, and I'm excited to announce support for it today: https://trunk.io/blog/trunk-merge-queue-now-supports-github-...
We will support a stack that is fully contained within a single fork, where the entire stack targets the original repo.
For example, a contributor who has a fork (user/buzz) of the original repo (org/buzz) could create the following stack:
``` frontend → PR #3 (base: user/buzz:api-endpoints) api-endpoints → PR #2 (base: user/buzz:auth-layer) auth-layer → PR #1 (base: org/buzz:main) org/buzz:main (trunk) ```
i appreciate that you are trying to make it possible for people who vibe code solutions to problems to get code merged by people who have made GitHub their lifestyle. but surely you see how, in my framing there, the people who are worried about how their history "looks" are the problem
Why did you choose extra pull requests as the division of work instead of building out a decent UI for reviewing/applying/reworking at the commit level? I assume there's some extra insight that made you ignore the mailing list "series of patches" workflow that inspired this whole thing and go with "series of series of patches" instead.
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.
i.e. like this where each one targets prior PR1 db_migrations PR2 backend_base PR3 adds_frontend_scoobydoodle PR4 adds_some_landing_page_thingy PR5 probably_have_to_fix_something
Or is stacks just a feature built to make this type of PR stacking easier to review?
Pretty much, yes. It’s just a UI to make it clear that those 5 PRs are liked (stacked) and gives some tooling around reviewing, merging and managing them, reduce redundant CI runs if desired, etc
> . 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.
I strongly believe that PR should be compared to the main branch, and not rely on unmerged code. Unless you merge everything together in one go. And in the latter case, everything should be reviewed together.
I'm also on the "compare to the main branch" camp in general, but will sometimes end up with a set of X,Y,Z branches that have different purposes but all depend on X.
More often than not, the base dependency is a set of constants or additional class/methods that could be released with no impact (no reference in live code) but still need a somewhat lenghty review process. Reverts would be happening on the higher level PRs, which hopefully are independent.
In my opinion there's already too much of a bias toward stamping PRs, and organizations that maintain high standards do it partly by resisting that bias in key parts of the codebase so people can push back on things that are poorly engineered or hard to maintain.
Comments are ad-hoc and don't scale, relying on the author to interpret and adhere to the extent of the reviewers approval.
> 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.
you are free to look up, down, and around the stack; nobody is hiding the code from you. But in many cases this is just unnecessary.
What I can see is that you can easily append commits to e.g. the first PR in a stack, which would insert them into the middle of sequence of commits.
This will require rebasing and fixing the subsequent PRs in a stack the same way you'd need to rebase and fix the subsequent commits in a mega-PR. But it makes the right thing easy (keeping all the commits to the foundation of the change together) rather than makin the wrong thing easy (appending fixup commits across the entire change in a random order so that the actual foundational change is lost).
Keeping all the foundational commits together also keeps all the discussion over the foundational change together.
You could argue that you'd want to only do the foundational PR and stop, but doing the whole stack of PRs gives the reviewers more information about where you're going, and allows work to continue asynchronously.
One use I have got from it is asking an agent to go through the git history and categories the mistakes/bugs, then turn the common ones into CI checks or AGENTS.md rules.
A well curated history just hides a lot of valuable info.
Honestly all GitHub needed to do was make reviewing and merging commit(s) from a PR possible and that would also been neat.
or "skjdnfks" and "fsdfs" commits.
As far as I can tell, the biggest benefit of stacked PRs over just making a coherent series of commits, is that it might make it easier to start work on your second PR before you merge the first one?
With human-in-the-loop coding, that sounds like it could lead to a lot of wasted work if the first PR gets substantial feedback. But with agentic coding, I can imagine how it might be desirable to keep the agent chugging while the first PR is under review.
Interested in learning more about it and generally agree that AI is stressing the current review paradigms a lot of us are accustomed to.
If review is fast I'd be switching back and forth between tasks throughout the day. If review is slow I might end up implementing a feature over the course of two weeks rather than two days. With reviewers in different time zones, limited time or doing their own focused work, it adds a lot of latency going back and forth for every PR rather than iterating on a stack of PRs.
Personally I find the biggest benefit is that it lets both the author and reviewers work at the pace that works for them, with reduced context switching and latency.
It kinda seems like they're duplicating the "unit of change" arbitrarily, rather than just fixing the way a PR works.
I think the reason I find that a bit icky is it seems like it's diverging GitHub from the underlying git tool, which I trust a lot more.
I don’t really see it as diverging much from the underlying git tool TBH - it’s still just git branches pointing at each other.
Torvalds invented Git for work on the Linux kernel, and the basic unit of change there is commits over email. It's not uncommon for them to take some commits but reject others.
Which isn't meant to say "pull requests are obviously wrong and commits over email are obviously correct", but rather to point out that the idea of a take-it-or-leave-it branch isn't some kind of natural unit of contribution
https://lkml.iu.edu/hypermail/linux/kernel/1402.2/00508.html
https://lkml.indiana.edu/2011.2/05416.html
https://lkml.iu.edu/2409.0/00960.html
https://lkml.iu.edu/hypermail/linux/kernel/2510.3/01369.html
Sure you can. The command is `git merge`
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.
If you mean automated tests and linters, sure.
Conceptually continuous integration is generally integrating 2+ different lineages of code together which is more common with multiple developers although I suppose it's becoming more relevant with agents creating a bunch of worktrees with different things.
In practice, CI has taken the same path as "DevOps Engineer" ie most people just mean "automated test server"
The opposite of CI is more-or-less merge windows or merge-fest like Linux where everyone mails in their changes and someone manually integrates.
> In practice, CI [often means] "automated test server"
Could you say more? I use "CI" to refer to the automated processes that run tests and (maybe) deploy code as it is merged to some blessed branch. It's what continually integrates the new code into the existing code. What am I missing?
Not every project requires this, but for those that do, it's impossible.
Also, it is much harder to enforce "everyone must run each commit through the CI equivalent properly" than it is when it's on your forge.
Why can't you? That's what VMs are for. And even then, most cross-platform codebases have an abstraction layer that rarely changes. So even testing on one platform can raise your confidence very high.
> Also, it is much harder to enforce "everyone must run each commit through the CI equivalent properly"
Again why? I wouldn't care about the dev's local branch. But what is send to the main repo can be easily scripted to run the CI on every commit. You just send the result back with each commit that fails. They can replicate the same workflow on their local workspace as a pre-push process.
> But what is send to the main repo can be easily scripted to run the CI on every commit.
Sure, this could work. I didn't say it was impossible, just more difficult. You have to build all of this support on top of the system that already does it for you: have your forge run CI on every commit.
Sure, I could load up my build machine with mac/windows/linux/android, with multiple versions of each. Emulating x86+x86_64+arm32+arm64+aarch64+... is also doable, sort of.
But considering that the real CI runs several thousand hours of tests total across all platforms, I think I won't.
Also, my Electron-based IDE needs those 10s of GB to edit text. How can you possibly edit a 1KB text file with less than 1GB of RAM?
Not to mention clangd that needs to do its ultra-important work Right Now so I can invalidate it all with my next edit. That's probably the biggest RAM hog of them all.
So the idea is you can much more cleanly isolate changes for large features.
Even if the reviewer does the review commit-by-commit, all the comments and discussions will be on the same PR leading to multiple ongoing conversations about different topics that would be split if the PR are stacked. Also, all the new commits addressing the comments with spoil this commit-by-commit design, as the previous commits will be outdated and the new changes will be on top of those. I think it's beneficial for new changes to be a separate commit and not rewriting history, to not force the reviewers to re-read everything but just the latest changes.
2. It also can't merge subsets of commits from a single PR. E.g. if you have two commits, A and B, where B depends on A... sure you can make a PR containing A and B, but if A gets approved and B doesn't, then you can't merge A.
3. The thing you want to do with a set of commits and reviewing each commit IS stacked PRs.
This is nothing to do with AI.
If you buy the idea that stacking produces better software, then this also has the opportunity to really help out quite a few people.
And the upshot for the LLM providers is that they get to charge for n reviews, instead of one.
Yes, GitHub could have made the UI allow a “per commit” comments somehow, then allow you to select the set of commits to include in the merge somehow, then write a blog post on how to manage “Address PR comments #1” commits. But the stacked PRs solve all that. Not to mention how people treat commits as their own internal save states. I always enable “squash and merge” option because I think it makes a lot more sense to have 1 commit on main per PR where all the context of the change is either in the commit message or the linked PR.
Also LLM providers charge per token. Charging per “work unit” is still not a solved problem. You can’t charge per “review” when your cost is per token. Just like airlines can’t charge “per ticket”, they have to charge differently depending on the destination. Unless you invent some bs arbitrage to lure users and eventually bait and switch on them.
1. The whole review interface isn't set up for reviewing individual commits.
2. You can't merge changes progressively.
3. CI doesn't run on each commit.
4. If you have linear history (good idea IMO) you'll lose your nice commit history when you merge it.
This is much better.
You don’t need to merge those changes progressively. If you do, you go through exactly the same process of creating a separate branch and PR. The only difference is that GH has now added some UI and automation for rebasing and merging the PRs. In the past we would have explained the chaining in the PR and rebased manually.
You don’t need CI to run on each commit.
You only lose your commit history if you squash merge, many people don’t, and you don’t have to either.
The arguments come from angle that doesn’t appear to be aware that stacked PRs were a thing before GH made these UX improvements.
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 a 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. So then, what would have been a single PR with four commits that you could merge with one click is now four PRs. Which you want to be able to merge them with one click.
Except you can’t really do that on GitHub, the “unit if review” is the PR so reviewing commits is adhoc, inconsistent, and awkward, and tracking their changes as they get fixed up is a pain. “Splatting” that as PRs is not the nicest way to do it green field, but it’s an evolution that makes sense in GitHub’s model.
- 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.
>Do PR refactoring module A >Do PR with feature X + cleanup >Maybe PR with additional work if bigger
A set of stacked PRs is exactly the same as a line of commits. The only difference is the UI, but the UI is the important bit here because lack of UI is what's stopping folk from doing that today.
Even when I've developed my changes as a stack of commits, I'll feed them to my team one commit (and one PR) at a time so they're easier to review — and I discovered that GitHub had turned on stacked commits UI because for one particular project I'd manually created a set of PRs in advance (with the right bases) and GitHub offered to create a stack out of them.
So instead of solving that problem, GitHub developed tooling around a workaround for that problem (targeting a PR at another branch that also has a PR).
Expanding reviews to allow per-commit reviews avoids the need for managing additional branches and all the headache that comes with it.
And the implementation feels very much like it sits in the UI layer, rather than further down the stack.
I'm not trying to claim stacking PRs in this way is the best way (it's not). But it does add an extra affordance for those who want it without burdening those who don't with the need to understand why someone would prefer it.
And there are also plenty of ways that people have been working around GitHub's (and to a lesser extent, git's) lack of tooling for working on changes in this way. I'm sure they have customers clamouring for the feature; whether they'll be happy with what they get remains to be seen.
(Very happy jujutsu user here, my tooling makes it really easy to create stacked commits with a stable identifier that maps really easily to branches and then onwards to running `gh stack`, but what GitHub have delivered is definitely still lacking)
The approach that GitHub chose can show those people almost immediate benefits, which is surely the better path towards adoption than trying to reeducate everyone to adopt a development flow based on clean rebases.
And for those of us who do prefer clean rebases, the thing they built is still useful.
A bunch of details aside, the major conceptual thing that the email based flow has which is still missing in GitHub's data model is the ability to have a discussion on the stack as a whole.
Also, if you're the mchristen I know, then I think we've had this discussion before haha! Hope you're well :)
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.
The problem I sometimes have is when I queue up 4 or 5 PRs in the afternoon and expect someone to take a look in the morning.
The diff of A into master looks OK, but then the diff of B looks like AB, and the diff of C looks like ABC - each PR has changes that will have already been merged once earlier PRs have been accepted.
My way around it was to raise E as a PR into D, raise D as a PR into C, etc. Then once approved, I change their destinations back to master for the actual merges.
It really confuses reviewers though, even though it's meant to make it so they only see the appropriate changes.
Whimsy is fine but that change made me super suspicious about what I was looking at.
If one wants to keep it to vanilla git.
git-spice is specifically targeted to be useful for PR stacking and doesn't require you to do anything differently from normal git operations that you likely use already. It has a bunch of really nice flows and doesn't try to step outside the bounds of what is needed to easily stack PRs
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.
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?
This would be such a insanely useful features for a small subset of power users that they will never deliver.
Instead of using the same branch, make new branches from that parent and commit there.
The cool thing about that approach is that (at least in git-tower app) is when you edit a parent branch after pr comments, all those new commits will be automatically “restacked” on descended branch (children branches will be rebased on new state or parent, incorporating the hew fixes)
Say you do change A, add a protocol buffer API definition, then implement the server logic (B) and the front end code (C) so that both depend on A but not each other. That can be in a tree. But now you want to add an integration test (D) that depends on B and C. The tree doesn't help you there, and you were better off making it a linear chain by arbitrarily picking one of B or C to be dependant on the other so that you have a code state with all of A,B and C applied to create D on top of.
Plus it's vendor lock in.
Give it time. Soon you'll only be able to push using Github's CLI.
If there's an expectation that you might merge a whole stack, I think you're aiming for the wrong thing. And it seems like landing the whole stack is the biggest push GitHub are making here. Part of the point is independently reviewable and independently mergable. If you're going to merge in one go then just put everything in one PR and review commit by commit in that PR. The commit by commit review flow used to suck, but since ~2021 it has been fine.
I feel like GitHub have built what users (who haven't used a true stacking system) asked for, not what they actually need to change their workflow for the better.
A great implementation would be asking hard questions like: what's the role of a single commit? Should PRs be single commit only? What's the real benefit here? How do you encourage smaller units of review (because it doesn't look like this does).
The most obvious case is something like adding a Reviewed-By/Signed-off-by trailer based on reviewers, but there’s also a decent number of big projects that want more semantically meaningful commit identifiers (think more revision, in a numeric sense).
It seems like making merges async should make it a lot more possible to implement that!
In the scenario you described of your team splitting the tickets, this gives you a UI to manage the PRs of the multiple tickets so you are no longer blocked on merging PR#1 before you can proceed to PR#2. Yes you might have to deal with conflicts, but you would have had to deal with that regardless.
And we solve this by splitting into 2 PRs that still merge at the same time. Oh, super useful!
Only if your reviews are so shallow that you don’t try to reason about the state of PR B merged to PR A, which would then be merged to main, and your real problem is just GitHub UI failing to handle a giant PR, which we all know that this feature is attempting to help with.
The underlying stacked PR workflow is unchanged:
1. Create branch B from branch A.
2. Open PR A against main.
3. Open PR B against branch A.
4. Repeat for additional layers.
but note line 111:
> This section describes what to do if you're in a Jujutsu (jj) repository. If the user is not using jj, good luck and try your best.
(The whole skill kind of assumes jj. I think you'd need to make a git version if you actually wanted to use it.)
When you click merge, does a 3 stack PR show up as 1 PR in the Dx metrics or 3?
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).
The case where I need stacked PRs is when I have a ton of changes and I want to upstream them. I have so many changes that I have probably written code in this order: 1. feature1 work 2. feature2 work 3. architecture rework 4. docs 5. feature3 work 6. optimization 7. docs 8. feature4 work 9. security fixes 10. optimization 11. docs 12. last pass security fixes
By the time I want to upstream, I probably want to reorder my commits and generate on PR per theme (arch, feature1 + docs + optimization, feature2+docs + optimization, etc) before I submit a bunch of PRs.
GitHub stacked PRs solve none of my problems. Stacked PRs doesn't take care of the reordering of commits, it doesn't take care of rebasing changes, it adds very little on top of what I was already able to do by saying "this is PR 1 out of 7, this is PR2 out of 7 and build on top of the branch that I used for PR1/7, etc".
Hugely disappointing, bordering useless.
That's literally all it's supposed to do. Make that dev flow less awful so you don't have to say "by the way this PR depends on #123, I will change the target branch when that is merged" and nonsense like that.
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.
...but if the end result is more popularity of 'stacked' logical changes, yay anyway?
I do it all the time.
It’s just merging branches.
Fix. Your. Culture.