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 :)
I liked that. I don't have a lot of good things to say about GitHub these days -- Microsoft has not been a kind owner -- so I found that moment of silliness encouraging.
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
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.
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.
We use GitHub's APIs. We did build a version before GitHub supported it, but it required using our credentials to push directly to the main branch. That wasn't acceptable to most of our customers, so we ended up not shipping it and waiting for GitHub support.
Using the GitHub APIs means you still preserve history and commit messages they way people expect (merges through the queue and direct merges behave the same), and it lets users guarantee that the only code our mergequeue merges is the code that was in the PR.
> 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.
The feature is half baked. Just today I had to spend ~1hr untangling a mess it created. And there was no way to reorder the Stack without discarding PRs that already had many comments. I'm not an intentional an early adopter, someone on the team clicked the tooltip.
> 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.
> 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.
But most of those solutions don't have the number of integrations and rules executions that GH has and that's where the challenge lies.
Again, it's by no means trivial. But in the last years we as an industry made private space travel viable, created self driving cars and made chatbots that can explain humor. Not being able to do stacked PRs in this day and age by the prime company in this area is just .. well you got the point.
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.
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.
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.
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.
Not sure if it makes you feel better, but it seems there's at least a few startups trying to get a jujutsu-native forge going, by people who have seen and used the way Google's (and other big tech's) systems work.
That's really cool!
I tried getting on board with ERSC, but the timezone difference proved too much :(. At least it gave me the kick to try and build my own company, though!
It was definitely also the case before Microsoft, but I can't imagine it has improved since the acquisition. I try to avoid the site nowadays, it's randomly extremely slow and I would much rather spend my energy elsewhere anyway.
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.
> 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.
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.
How long until support gets added for repos with merge queues? I'd love to use this at $WORK and so would my coworkers, but we can't turn off the merge queue so we can't use stacked PRs until they can mix.
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.
JJ, Gerrit, codebutler, and I think a couple of others have all basically agreed upon a syntax for change IDs and they are converging their prior ad-hoc formats into one; but last time I checked, the request to the upstream git team of "please don't silently drop the change-id header during rebase or amend" was met with bike-shedding about all the other hypothetical benefits that alternative formats could hypothetically provide, so universal support for the header as used in practice today is still missing D:
(I would love to be proven wrong if there's been some progress that I didn't get the memo about ^^)
This is roughly the current state of things as I know about it, that said I haven't read a lot of git's mailing list lately so it's possible that there have been some other developments.
Yes, we handle this both in the CLI and server using git rebase --onto
git rebase --onto <new_commit_sha_generated_by_squash> <original_commit_sha_from_tip_of_merged_branch> <branch_name>
So for ex in this scenario:
PR1: main <- A, B (branch1)
PR2: main <- A, B, C, D (branch2)
PR3: main <- A, B, C, D, E, F (branch3)
When PR 1 and 2 are squash merged, main now looks like:
S1 (squash of A+B), S2 (squash of C+D)
Then we run the following:
git rebase --onto S2 D branch3
Which rewrites branch3 to:
S1, S2, E, F
This operation moves the unique commits from the unmerged branch and replays them on top of the newly squashed commits on the base branch, avoiding any merge conflicts.
Everyone will have their own way of structuring stacks, but I've found it great for the agent to plan a stack structure that mirrors the work to be done.
Stacked PRs can be created via the UI, API, or CLI.
You can also run a combination of these. For ex, use another tool like jj to develop locally, push up the branches, and use the gh CLI to batch create a stack of n PRs, without touching local state.
> So, if I have three patches in the stack, and I want to merge the bottom two, I'd merge one, wait for tests to run on the other, merge the second vs. merge just those two in one step
As we have it designed currently, you would have to wait for CI to pass on the bottom two and then you can merge the bottom two in one step. The top of the stack would then get rebased, which will likely trigger another CI run.
Thanks for the callout - we'll update those docs to make it clear multiple PRs can be merged at once.