I might be missing something, but what I need is not "stacked PR" but a proper UI and interface to manage single commit:
- merge some commits independently when partial work is ready.
- mark some commit as reviewed.
- UI to do interactive rebase and and squash and edit individual commits. (I can do that well from the command line, but not when using the GitHub interface, and somehow not everyone from my team is familiar with that)
- ability to attach a comment to a specific commit, or to the commit message.
- better way to visualize what change over time in each forced push/revision (diff of diff)
Git itself already has the concept of commit. Why put this "stacked PR" abstraction on top of it?
Or is there a difference I don't see?
mikeocool 57 seconds ago [-]
Constantly rewriting git history with squashes, rebases, manual changes, and force pushes has always seemed like leaving a loaded gun pointed at your foot to me.
Especially since you get all of the same advantages with plain old stream on consciousness commits and branch merges using:
git merge --no-ff
git log --first-parent
git bisect --first-parent
tcoff91 34 minutes ago [-]
It's basically trying to bring the stacked diff workflow pioneered by Phabricator to GitHub.
The idea is that it allows you to better handle working on top of stuff that's not merged yet, and makes it easier for reviewers to review pieces of a larger stack of work independently.
It's really useful in larger corporate environments.
I've used stacked PRs when doing things like upgrading react-native in a monorepo. It required a massive amount of changes, and would be really hard to review as a single pull request. It has to be landed all at once, it's all or nothing. But being able to review it as smaller independent PRs is helpful.
Stacking PRs is also useful even when you don't need to merge the entire stack at once.
jrochkind1 10 minutes ago [-]
I'm not in a large corporate environment, but that also means we're not always a well oiled machine, and sometimes i am writing faster than the reviewer can review for a period of time -- and i really need the stacking then too.
js2 29 minutes ago [-]
> stacked diff workflow pioneered by Phabricator
Ahem, pioneered by gerrit. But actually, I'm almost certain even that wasn't original art. I think gerrit just brought it to git.
To my knowledge, stacked diffs were first done in the Linux kernel as stacks of patches sent over email. From there they spread to Google and Facebook. (Source: I worked on Facebook's source control team from 2012-2018 and did a lot of work to enable stacked diffs there.)
eptcyka 22 minutes ago [-]
What if main/master moves in between reviews?
jrochkind1 10 minutes ago [-]
Before this feature when you were doing it manually, it was a huge problem. One of the points of this feature, is it automates rebasing the whole stack.
tcoff91 18 minutes ago [-]
Rebase the stack onto main.
xixixao 29 minutes ago [-]
Workflows can vary, but what I like:
PR/MR is an "atomic" change (ideally the smallest change that can be landed separately - smallest makes it easier to review, bisect and revert)
Individual commits (or what "versions" are in Phabricator) are used for the evolution of the PR/MR to achieve that change.
But really I have 2 use cases for the commits:
1. the PR/MR is still too big, so I split it into individual commits (I know they will land together)
2. I keep the history of the evolution of the PR/MR in the commits ("changed foo to bar cause its a better approach")
zzyzxd 2 minutes ago [-]
One mistake I see across many organizations is that sometimes they overthink how much order should matter.
Sure, your application has a dependency on that database, but it doesn't necessarily mean you can't deploy the application before having a database. Just make it acceptable for your application to stay in a crashloop until your database is online.
adamwk 1 hours ago [-]
As someone who used phabricator and mercurial, using GitHub and git again feels like going back to the stone ages. Hopefully this and jujutsu can recreate stacked-diff flow of phabricator.
It’s not just nice for monorepos. It makes both reviewing and working on long-running feature projects so much nicer. It encourages smaller PRs or diffs so that reviews are quick and easy to do in between builds (whereas long pull requests take a big chunk of time).
smallmancontrov 38 minutes ago [-]
I'm so glad git won the dvcs war. There was a solid decade where mercurial kept promoting itself as "faster than git*†‡" and every time I tried it wound up being dog slow (always) or broken (some of the time). Git is fugly but it's fast, reliable, and fugly and I can work with that.
steveklabnik 12 minutes ago [-]
What is kind of funny here is that you're right locally. At the same time, the larger tech companies (Meta and Google, specifically) ended up building off of hg and not git because (at the time, especially) git cannot scale up to their use cases. So while the git CLI was super fast, and the hg CLI was slow, "performance" means more than just CLI speed.
I was never a fan of hg either, but now I can use jj, and get some of those benefits without actually using it directly.
eqvinox 4 minutes ago [-]
I remember using darcs, but the repos I was using it with were so small as to performance really not mattering…
raincole 15 minutes ago [-]
This matches my experience 100%. I was about to write a similar comment before I see yours.
forrestthewoods 18 minutes ago [-]
Mercurial has a strictly superior API. The issue is solely that OG Mercurial was written in Python.
Git is super mid. It’s a shame that Git and GitHub are so dominant that VCS tooling has stagnated. It could be so so so much better!
outworlder 5 minutes ago [-]
> The issue is solely that OG Mercurial was written in Python.
Are we back to "programming language X is slow" assertions? I thought those had died long ago.
Better algorithms win over 'better' programming languages every single time. Git is really simple and efficient. You could reimplement it in Python and I doubt it would see any significant slowness. Heck, git was originally implemented as a handful of low level binaries stitched together with shell scripts.
worldsayshi 12 minutes ago [-]
Maybe forgejo has a shot?
awesome_dude 13 minutes ago [-]
Whatever your opinion on one tool or another might be - it does seem weird that the "market" has been captured by what you are saying is a lesser product.
IOW, what do you know that nobody else does?
guelo 3 minutes ago [-]
Network effects and marketing can easily prevent better tools from winning.
esafak 6 minutes ago [-]
That worse is better, and some people don't know better or care.
jrochkind1 11 minutes ago [-]
Welcome to VHS and Betamax. the superior product does not always win the market.
Leynos 21 minutes ago [-]
I just used it because I preferred the UX.
kardianos 1 hours ago [-]
I continue to use gerrit explicitly because I cannot stand github reviews. Yes, in theory, make changes small. But if I'm doing larger work (like updating a vendored dep, that I still review), reviewing files is... not great... in github.
tcoff91 1 hours ago [-]
Most editors have some kind of way to review github PRs in your editor. VSCode has a great one. I use octo.nvim since I use neovim.
nine_k 23 minutes ago [-]
Can these tools e.g. do per-commit review? I mean, it's not the UI what's the problem (though it's not ideal), it's the whole idea of commenting the entire PR at once, partly ignoring the fact that the code in it changes with more commits pushed.
Phabricator and even Gerrit are significantly nicer.
calebio 18 minutes ago [-]
I miss the Phabricator review UI so much.
montag 1 minutes ago [-]
Me too. And I'm speaking from using it at Rdio 15 years ago.
Nothing since (Gerrit, Reviewboard, Github, Critique) has measured up...
bsimpson 1 hours ago [-]
Finally!
I never understood the PR=branch model GitHub defaulted to. Stacked commits (ala Phabricator/Gerrit) always jived more with how my brain reasons about changes.
Glad to see this option. I guess I'll have to install their CLI thing now.
ezekg 1 hours ago [-]
My only complaint off the bat is the reliance on the GH CLI, which I don't use either. But maybe by the time it's GA they'll have added UI support.
I must have missed that. Amazing! From a reviewer's POV, this will be so nice to at the very least remove diff noise for PRs built on top of another PR. I usually refrain from reviewing child PRs until the parent is merged and the child can be rebased, for the sole reason that the diffs are hard to review i.r.t. what came from where.
ZeWaka 1 hours ago [-]
It seems partially exposed in the UI with that dropdown. There's an 'add' and 'unstack' button.
Probably relies on some internal metadata.
akersten 32 minutes ago [-]
Does it fix the current UX issue with Squash & Merge?
Right now I manually do "stacked PRs" like this:
main <- PR A <- PR B (PR B's merge target branch is PR A) <- PR C, etc.
If PR B merges first, PR A can merge to main no problems. If PR A merges to main first, fixing PR B is a nightmare. The GitHub UI automatically changes the "target" branch of the PR to main, but instantly conflicts spawn from nowhere. Try to rebase it and you're going to be manually looking at every non-conflicting change that ever happened on that branch, for no apparent reason (yes, the reason is that PR A merging to main created a new merge commit at the head of main, and git just can't handle that or whatever).
So I don't really need a new UI for this, I need the tool to Just Work in a way that makes sense to anyone who wasn't Linus in 1998 when the gospel of rebase was delivered from On High to us unwashed Gentry through his fingertips..
xixixao 25 minutes ago [-]
Conflicts spawn most likely because PR A was squashed, and once you squash Git doesn't know that PR B's ancestors commits are the same thing as the squashed commit on main.
No idea if this feature fixes this.
Edit: Hopefully `gh stack sync` does the rebasing correctly (rebase --onto with the PR A's last commit as base)
akersten 7 minutes ago [-]
> Conflicts spawn most likely because PR A was squashed, and once you squash Git doesn't know that PR B's ancestors commits are the same thing as the squashed commit on main.
Yeah, and I kind of see how git gets confused because the squashed commits essentially disappear. But I don't know why the rebase can't be smart when it sees that file content between the eventual destination commit (the squash) is the same as the tip of the branch (instead of rebasing one commit at a time).
gregoryl 23 minutes ago [-]
If I'm following correctly, the conflicts arise from other commits made to main already - you've implicitly caught branch A up to main, and now you need catch branch B up to main, for a clean merge.
I don't see how there is any other way to achieve this cleanly, it's not a git thing, it's a logic thing right?
akersten 10 minutes ago [-]
I've no issue with the logic of needing to update feature branches before merging, that's pretty bread and butter. The specific issue with this workflow is that the "update branch" button for PR B is grayed out because there are these hallucinated conflicts due to the new squash commit.
The update branch button works normally when I don't stack the PRs, so I don't know. It just feels like a half baked feature that GitHub automatically changes the PR target branch in this scenario but doesn't automatically do whatever it takes for a 'git merge origin/main' to work.
Smaug123 14 minutes ago [-]
No, it's a Git thing arising from squash commits. There are workflows to make it work (I've linked the cleanest one I know that works without force pushing), but ultimately they're basically all hacks. https://www.patrickstevens.co.uk/posts/2023-10-18-squash-sta...
27 minutes ago [-]
sameenkarim 24 minutes ago [-]
Hey from the GitHub Stacked PRs team!
We're in private preview and rolling out to folks on the waitlist in the coming weeks: https://gh.io/stacksbeta
Would welcome any feedback on the spec, CLI, workflows, etc.
calebio 15 minutes ago [-]
Any idea if/when this would be coming to GHE? I know the release cycle is way different but curious about your thoughts.
WhyNotHugo 8 minutes ago [-]
I really don't get the point of stacked PRs.
Just using git, you'd send a set of patches, which can be reviewed, tested and applied individually.
The PR workflow makes a patch series an undivisible set of changes, which must be reviewed, tested and applied in unison.
And stacked PRs tries to work around this issue, but the issue is how PRs are implemented in the first place.
What you really want is the ability to review individual commits/patches again, rather than work on entire bundles at once. Stacked PRs seems like a second layer of abstraction to work around issues with the first layer of abstractions.
cleverdash 1 hours ago [-]
As a solo dev I rarely need stacked PRs, but the underlying problem, keeping PRs small and reviewable, is real even when you're your own reviewer. I've found that forcing myself to break work into small branches before I start (rather than retroactively splitting a giant branch) is the actual discipline. The tooling just makes it less painful when you don't.
Curious whether this changes anything for the AI-assisted workflow. Right now I let Claude Code work on a feature branch and it naturally produces one big diff. Stacked PRs could be interesting if agents learned to split their own work into logical chunks.
ameliaquining 54 minutes ago [-]
The tooling for that already exists, since a PR can consist of multiple Git commits and you can look at them separately in the UI. I don't know whether agents are any good at navigating that, but if not, they won't do any better with stacked PRs. Stacked PRs do create some new affordances for the review process, but that seems different from what you're looking for.
Arainach 49 minutes ago [-]
Looking at multiple commits is not a good workflow:
* It amounts to doing N code reviews at once rather than a few small reviews which can be done individually
* Github doesn't have any good UI to move between commits or to look at multiple at once. I have to find them, open them in separate tabs, etc.
* Github's overall UX for reviewing changes, quickly seeing a list of all comments, etc. is just awful. Gerrit is miles ahead. Microsoft's internal tooling was better 16 years ago.
* The more commits you have to read through at once the harder it is to keep track of the state of things.
tcoff91 28 minutes ago [-]
It's crazy that you're getting downvoted for this take.
This isn't reddit people. You're not supposed to downvote just because you disagree. Downvotes are for people who are being assholes, spamming, etc...
If you disagree with a take, reply with a rebuttal. Don't just click downvote.
steveklabnik 11 minutes ago [-]
Historically, hn etiquette is that it's fine to downvote for disagreement. This came from pg himself.
That said, while he hasn't posted here for a long time, this is still in the guidelines:
> Please don't post comments saying that HN is turning into Reddit. It's a semi-noob illusion, as old as the hills.
>It amounts to doing N code reviews at once rather than a few small reviews which can be done individually
I truly do not comprehend this view. How is reviewing N commits different from/having to do less reviews reviewing N separate pull requests? It's the same constant.
Arainach 33 minutes ago [-]
Small reviews allow moving faster for both the author and reviewer.
A chain of commits:
* Does not go out for review until the author has written all of them
* Cannot be submitted even in partial form until the reviewer has read all of them
Reviewing a chain of commits, as the reviewer I have to review them all. For 10 commits, this means setting aside an hour or whatever - something I will put off until there's a gap in my schedule.
For stacked commits, they can go out for review when each commit is ready. I can review a small CL very quick and will generally do so almost as soon as I get the notification. The author is immediately unblocked. Any feedback I have can be addressed immediately before the author keeps building on top of it.
tcoff91 30 minutes ago [-]
Let's compare 2 approaches to delivering commits A, B, C.
Single PR with commits A, B, C: You must merge all commits or no commits. If you don't approve of all the commits, then none of the commits are approved.
3 stacked PRs: I approve PR A and B, and request changes on PR C. The developer of this stack is on vacation. We can incrementally deliver value by merging PRs A and B since those particular changes are blocking some other engineer's work, and we can wait until dev is back to fix PR C.
steveklabnik 43 minutes ago [-]
I have had a lot of success with Claude and jj, telling it to take the stack of work it's done and build me a new stack on top of trunk that's centered around ease of reviewing.
4b11b4 33 minutes ago [-]
I once threatened Claude have to learn JJ after doing some crazy git rebase gymnastics. The problem is clearly that I don't know jj
adamwk 52 minutes ago [-]
Maybe there’s a git trick I don’t know, but I’ve found making small branches off each other painful. I run into trouble when I update an earlier branch and all the dependent branches get out of sync with it. When those earlier branches get rebased into master it becomes a pain to update my in-progress branches as well
leleat 4 minutes ago [-]
If I understood you correctly, you want to propagate changes in a branch to other branches that depend on it? Then --update-refs is for you[1]. That way, you only need to update the "latest" branch.
Stacking branches for any extended period of time is definitely a poor mixing of the concepts of branches and commits. If you have a set of changes you need to keep in order, but you also need to maintain multiple silos where you can cleanly allow the code to diverge, that divergence constitutes the failure of your efforts to keep the changes in order.
Until you can make it effortless, maintaining a substantial commit structure and constantly rebasing to add changes to the proper commit quickly turns into more effort than just waiting to the end and manually editing a monster diff into multiple sensible commits. But we take the challenge and tell ourselves we can do better if we're proactive.
dbbk 58 minutes ago [-]
If you visit the webpage it gives you integration instructions for agents
robertwt7 41 minutes ago [-]
There’s a startup callled Graphite dedicated to stacked PRs. I have been using them for a while now I always wonder why github doesn’t implement something similar to this. I probaly will try and switch to GitHub to see if it works flawlessly
ghthor 1 minutes ago [-]
Yep, very happy with graphite at work.
ninkendo 17 minutes ago [-]
> a chain of small, focused pull requests that build on each other — each one independently reviewable.
I have never understood what this even means.
Either changes are orthogonal (and can be merged independently), or they’re not. If they are, they can each be their own PR. If they’re not, why do you want to review them independently?
If you reject change A and approve change B, nothing can merge, because B needs A to proceed. If you approve change A and reject change B, then the feature is only half done.
Is it just about people wanting to separate logical chunks of a change so they can avoid get distracted by other changes? Because that seems like something you can already do by just breaking a PR into commits and letting people look at one of those at a time.
I’ve tried my best to give stacked-diff proponents the benefit of the doubt but none of it actually makes sense to me.
steveklabnik 3 minutes ago [-]
The canonical example here is a feature for a website that requires both backend and frontend work. The frontend depends on the backend, but the backend does not depend on the frontend. This means that the first commit is "independent" in the sense that it can land without the second, but the second is not, hence, a stack. The root of the stack can always be landed independently of what is on top of it, while the rest of the stack is dependent.
> If they’re not, why do you want to review them independently?
For this example, you may want review from both a backend engineer and a frontend engineer. That said, see this too though:
> that seems like something you can already do by just breaking a PR into commits and letting people look at one of those at a time.
If you do this in a PR, both get assigned to review the whole thing. Each person sees the code that they don't care about, because they're grouped together. Notifications go to all parties instead of the parties who care about each section. Both reviews can proceed independently.
> If you approve change A and reject change B, then the feature is only half done.
It depends on what you mean by "the feature." Seen as one huge feature, then yes, it's true that it's not finished until both land. But seen as two separate but related features, it's fine to land the independent change before the dependent one: one feature is finished, but the other is not.
charcircuit 2 minutes ago [-]
>If you reject change A and approve change B, nothing can merge
The feature is also half done in this case. The author can fix up the concerns the reviewer had in A and then both can be merged at the same time.
fweimer 59 minutes ago [-]
I find this puzzling. It does not seem to allow to stack PRs on top of other people's PRs?
This API leaves a comment, on the commit; not quite the same thing since in GH, several operations are tied to PRs and not to commits.
inerte 34 minutes ago [-]
Looks interesting, but it seems you need to know the final shape of the stack before you start creating Pull Requests. So it's useful if you create Pull Request A, then immediately start working on something that builds on top of A, create a Pull Request for that (while A is still a PR), then you can do A->B->C
Here's something that would be useful: To break down an already big PR into multiples that make up a stack. So people can create a stack and add layers, but somehow re-order them (including adding something new at the first position).
tcoff91 25 minutes ago [-]
It looks like in the UI if you base a PR on another branch you can just check a box to make it a stack. So I don't think you have to know the full shape of the stack in advance unless you're using the cli.
I use jj to stack branches so i'll just be using the UI to do github pr stacks.
atq2119 22 minutes ago [-]
People have been building stacked PR workflows on top of GitHub for a while now. It's great to see that the message seems to have finally landed at GitHub, but what is actually new here in GitHub itself (i.e., not counting the gh CLI tool)?
There seems to be a native stack navigation widget on the PR page, which is certainly a welcome addition.
The most important question though is whether they finally fixed or are going to fix the issues that prevent submitting stacked PRs from forks. I don't see any indication about that on the linked page.
ZeWaka 1 hours ago [-]
Seems to mainly be useful for monorepos as currently designed. Or, to replace a long-lived feature/refactor branch.
YesThatTom2 1 hours ago [-]
Whatbmakes you say that? Devs use stacked PRs in small and large repos today.
ZeWaka 52 minutes ago [-]
Their examples show combined backend and frontend changes on the same monorepo in different PRs.
As far as splitting work into different PRs that need coordinated merging, I've only ever encountered that when it's a long lived refactor / feature.
Hamuko 53 minutes ago [-]
I think the only thing I miss from GitLab was being able to make merge requests depend on other merge requests, even across repositories. So I could make a backend repository MR depend on a library repository MR, and even enable auto-merge that’d fire when the backend MR was reviewed and the dependency was also merged.
jrochkind1 19 minutes ago [-]
Well, I have been waiting for this for YEARS.
Every time I try to do it manually, I wind up screwing everthing up.
Very interested ot check it out.
eqvinox 7 minutes ago [-]
> How It Works
> The gh stack CLI handles the local workflow […]
That's not "how it works", that's "how you['re supposed to] use it"… for "how it works" I would've expected something like "the git branches are named foo1 foo2 and foo3 and we recognize that lorem ipsum dolor sit amet…"
…which, if you click the overview link, it says "The CLI is not required to use Stacked PRs — the underlying git operations are standard. But it makes the workflow simpler, and you can create Stacked PRs from the CLI instead of the UI." … erm … how about actually explaining what the git ops are? A link, maybe? Is it just the PRs having common history?
…ffs…
(In case it's not obvious: I couldn't care less for using a GH specific CLI tool.)
topaztee 1 hours ago [-]
how is this different than viewing a PR one commit at a time?
nickcw 48 minutes ago [-]
I think it is conceptually the same but multiple PRs gives you the tools to manage the commits properly which GitHub is missing. You can't do the equivalent of `git rebase -i` in the GitHub UI to squash a fixup into a previous commit. Having each change in it's own PR enables that workflow using the existing GitHub UI.
simplyluke 1 hours ago [-]
Split into individual PRs, which works better for how a lot of companies do code review.
masklinn 29 minutes ago [-]
Stacked PRs track changes through updates and can be integrated progressively as they get validated.
They also allow reviewing commits individually, which is very frustrating to do without dedicated support (unless you devolve back to mailing list patch stacks).
Macha 53 minutes ago [-]
Each commit can be merged independently as they're reviewed.
CharlieDigital 41 minutes ago [-]
I don't think this is it. The main driver is that several operations in GH are scoped around a PR, not a commit. So the reason you need stacked PRs is that the layer of tooling above `git` is designed to work on logical groups of commits called a PR.
4b11b4 29 minutes ago [-]
Right, the argument against: "how is this any different than splitting into single commits?" is simply: In general you want just one level above a commit which is the PR
Hamuko 51 minutes ago [-]
One of the advertised features of this is being able to merge all the PRs at once. Which would also be the case for multiple commits in a single PR.
Arainach 48 minutes ago [-]
That's possible but not mandatory. In the current UX you can only approve/submit all or none.
44 minutes ago [-]
stephbook 44 minutes ago [-]
Commits are immutable and you never know which feedback goes stale when you add another commit.
I'm not a huge fan, since stacked PRs mean the underlying issues don't get addressed (reviews clearly taking too long, too much content in there), but it seems they want something that works for their customers, right now, as they work in real life.
IshKebab 19 minutes ago [-]
CI runs on each PR, you get a whole PR message and discussion/review interface for each PR. Each PR can itself consist of multiple commits. You can have stacked PRs from different authors (though from another comment it sounds like they may not have implemented that).
It's a big improvement (assuming they've done it right).
K0IN 40 minutes ago [-]
Wow i really need this, we had a refactor our monorepo (dotnet 8 -> 10 and angular 19 -> 21) which resulted in many small changes (like refactoring to signals, moving components to standalone) and we try to group changes into commits by what was fixed, but this had the downside of some commits beeing huge while others small, this would have helped us alot grouping commits together and having cleaner commit messages.
pbrowne011 1 hours ago [-]
Interesting to see how their CLI compares with GitLab's CLI interface for stacked diffs (the only support they offer at the moment): https://docs.gitlab.com/user/project/merge_requests/stacked_.... Most things are the same (up/down/top/bottom vs. next/prev/first/last, init vs. create), but both feel quite limiting. I've heard of other systems such as Gerrit that offer better native support, but have not tried out any for myself.
jamietanna 1 hours ago [-]
Very much looking forward to getting this on Renovate - we require squash-merge via Merge Queue (with no per-PR override available in GitHub, despite asking) and so when I've got multiple changes, it's a lot of wrangling and rebasing
If this works as smoothly as it sounds, that'll significantly reduce the overhead!
chao- 1 hours ago [-]
Even though moments where I would reach for it are rare, this is a very welcome feature. In times when I could have used it, it was not difficult to emulate via more branches, consistent naming, referencing the PRs, etc. Not difficult, but definitely tedious, and always left me feeling less organized than I like to feel.
mc-serious 30 minutes ago [-]
great, I'll directly compare it to graphite.com - the main point really is the user interface in my opinion. Still a bit sceptical whether github can out-deliver here, but happy to be proven wrong!
Has anyone already tried that was a graphite user before?
baq 49 minutes ago [-]
Just when I’ve gotten used to having 3 or more PRs in parallel with a local octopus working tree with jj. Maybe my colleagues will see the light at least.
ghighi7878 36 minutes ago [-]
What's difference between stacked PRs and merge trains in gitlab?
masklinn 32 minutes ago [-]
Merge trains are an integration method. In GitHub that’s called merge queues.
Stacked PRs are a development method, for managing changes which are separate but dependent on one another (stacked).
The two are orthogonal they can be used together or independently (or not at all).
Yes, except with a proper UI. Also while you could do this on GitHub before in the same way that that Gitlab feature works, it didn't work cross-repo so in practice it wasn't an option for most open source code.
I can't remember if Gitlab has the same limitations but I do remember trying to use Gitlab's stacked diffs and finding them to not work very well. Can't remember why tbh.
sailorganymede 1 hours ago [-]
Thank goodness. It was a pain to do this manually
scottfits 22 minutes ago [-]
cherry picking is so fragile, this is at least a step in the right direction
ChrisArchitect 16 minutes ago [-]
Aside:
> This is a docs site that was made to share the spec and CLI for private preview customers that ended up getting picked up. This will move to GitHub docs once it’s in public preview.
Wondering how all of those startups that implement this for GitHub feel right now.
whalesalad 1 hours ago [-]
At first I thought this was a user submitted project due to the subdomain of github.com but then realize the subdomain is also github. Is this an official channel for this sort of thing? Surprised this isn't on the official blog.
ameliaquining 53 minutes ago [-]
It's in private preview. Probably they'll put it in the main docs and such once it's open to everyone.
There’s a special case where certain official orgs can continue to use github.com instead of github.io for their Pages domain, and that’s how you end up with:
Should Pages owned by this user be regarded as “Official GitHub properties”?
def github_owned_pages?
GitHub.github_owned_pages.include?(login)
end
# Orgs/users that are owned by GitHub and should be allowed to use
# `github.com` URLs.
#
# Returns an Array of String User/Organization logins.
...
ZeWaka 1 hours ago [-]
It's their 'GitHub' org GitHub Pages domain - it's just .com instead of .io (not to be confused with their gh.io link shortener)
enraged_camel 47 minutes ago [-]
The biggest challenge for us are PRs that need to be coordinated across multiple repos. API + client for example. It doesn't sound like stacked PRs solve that problem, right? Description specifically states single repo.
masklinn 26 minutes ago [-]
They do not no. Afaik GitHub has little to nothing that is cross repository.
DesiLurker 37 minutes ago [-]
what happened to the old gerrit reviews, I loved its handling on incremental patchsets. github is primitive by comparison.
inetknght 1 hours ago [-]
Cool. Now let me do it across multiple repos. I often end up with 10 or 20 PRs across a half dozen repos that need to be merged in specific order.
whalesalad 1 hours ago [-]
For sure. If you are in a monorepo this solution works but if you have distinct microservice repositories it would help to coordinate pr #827 on repo-A and pr #1092 on repo-B are related and need to ship in a certain order.
ZeWaka 1 hours ago [-]
Exact problem we've run into at work. We've ended up having to write external merge coordination in order to not break our dev deployments.
throwaway9980 1 hours ago [-]
Who hurt you?
dpcx 1 hours ago [-]
Their manager who suggested that everything be a microservice, but everything depends on each other.
50 minutes ago [-]
simplyluke 1 hours ago [-]
Microservices, by the sound of the original comment
Arbortheus 1 hours ago [-]
Microservices without a monorepo is hell
Yokohiii 44 minutes ago [-]
They've opted for critical damage.
ameliaquining 1 hours ago [-]
How would that work? Commits in different repos aren't ordered relative to one another. I suppose you could have a "don't let me merge this PR until after this other PR is merged" feature, but you could do that with a GitHub Action; it doesn't really need dedicated backend or UI support.
TZubiri 52 minutes ago [-]
github.github.com? Not the first time github does something highly weird with their domains (like publishing docs from a subdomain of their public github pages service)
I think they have a culture of circumventing 'official' channels and whoever is in charge of a thing is whoever publishes the thing.
I think it's a great way to train users to get phished by github impostors, if tomorrow we see an official download from official.github.com or even official-downloads.github.io, sure it's phishy, but it's also something that github does.
It's also 100% the kind of issues that, if it happens, the user will be blamed.
I would recommend github to stop doing this stuff and have a centralized domain to publish official communications and downloads from. Github.github.com? Come on, get serious.
TL;DR: DO NOT DOWNLOAD ANYTHING from this site, (especially not npm/npx/pnpm/bun/npjndsa) stuff. It's a Github Pages site, just on a subdomain that looks official, theoretically it might be no different from an attacker to obtain access to dksabdkshab.github.com than github.github.com. Even if it is official, would you trust the intern or whoever managed to get a subdomain to not get supply chained? github.github.com just think about it.
If only there were some way to logically break up large pull requests into smaller pieces... Some way of creating a checkpoint with a diff including your changes, and some kind of message explaining the context behind the change... some way to "commit" a change to the record of the repository...
landr0id 1 hours ago [-]
Part of the idea behind stacked PRs is to keep your commits focused and with isolated changes that are meaningful.
A stacked PR allows you to construct a sequence of PRs in a way that allows you to iterate on and merge the isolated commits, but blocks merging items higher in the stack until the foundational changes are merged.
jaredsohn 1 hours ago [-]
There are tools that use LLMs to do this.
I've done this manually by building a big feature branch and asking an LLM to extract out functionality for a portion of it.
For the former, it would seem to split based on frontend/backend, etc. rather than what semantically makes the most sense and for the latter it would include changes I don't want and forget some I do want. But I haven't tried this a lot.
bombcar 1 hours ago [-]
So much effort has been spent beating git until it's just CVS with bells on.
steveklabnik 41 minutes ago [-]
The stacked diffs flow is much closer to the kernel flow for git than the traditional GitHub PR flow is.
Hamuko 1 hours ago [-]
Yeah, I feel like just being able to review a PR commit-by-commit with a nice interface would just suffice.
ezekg 1 hours ago [-]
Not really. Without seeing the entire changeset for a PR, you'd have to mentally keep track of what the current state of everything is unless you're a commit minimalist and presquash.
aunderscored 45 minutes ago [-]
How does that differ from this where you need to keep track of state and the whole change in the stack?
ezekg 34 minutes ago [-]
If we're speaking strictly code review, because you can actually make sense of the changeset for the child PR by not including its unmerged parent's changeset.
benatkin 1 hours ago [-]
For me that would mean avoiding tiny commits, and I wouldn't want to do that
pertymcpert 1 hours ago [-]
What might that be?
bob1029 56 minutes ago [-]
I feel like we already have enough abstractions in this space. Having any constraints at all in your tools is actually a good thing. PRs on top of ordinary git was a good step. This seems like one too many.
Yokohiii 49 minutes ago [-]
I honestly don't even get the PR addiction. Github has shaped devs workflows way too much. My best experience with git was when I realized that I can just have an blatantly simple workflow and explain it even to the junior-est dev in a few minutes. The reliance on github is somehow telling me that people stopped thinking about things they can actually control.
siva7 1 hours ago [-]
What a time to be alive. Stacked PRs are now a native feature of Github, even with first-class support for your ai agents. Vibeslop your whole Jira Backlog. Don't fear the merge anymore. Just make any feature branch a long-lived branch by stacking one upon another like bricks.
I'm old enough to have worked with SVN and young enough to have taught engineers to avoid stacking PR in Git. All wisdom has been lost and will probably be rediscovered in another time by another generation.
jollyllama 33 minutes ago [-]
Yeah, not sure what this solves that doing multiple PRs from one feature branch into another doesn't solve. But building behavior that into AI agents wouldn't be cool enough, I guess.
Rendered at 22:02:53 GMT+0000 (Coordinated Universal Time) with Vercel.
- merge some commits independently when partial work is ready.
- mark some commit as reviewed.
- UI to do interactive rebase and and squash and edit individual commits. (I can do that well from the command line, but not when using the GitHub interface, and somehow not everyone from my team is familiar with that)
- ability to attach a comment to a specific commit, or to the commit message.
- better way to visualize what change over time in each forced push/revision (diff of diff)
Git itself already has the concept of commit. Why put this "stacked PR" abstraction on top of it?
Or is there a difference I don't see?
Especially since you get all of the same advantages with plain old stream on consciousness commits and branch merges using:
git merge --no-ff
git log --first-parent
git bisect --first-parent
The idea is that it allows you to better handle working on top of stuff that's not merged yet, and makes it easier for reviewers to review pieces of a larger stack of work independently.
It's really useful in larger corporate environments.
I've used stacked PRs when doing things like upgrading react-native in a monorepo. It required a massive amount of changes, and would be really hard to review as a single pull request. It has to be landed all at once, it's all or nothing. But being able to review it as smaller independent PRs is helpful.
Stacking PRs is also useful even when you don't need to merge the entire stack at once.
Ahem, pioneered by gerrit. But actually, I'm almost certain even that wasn't original art. I think gerrit just brought it to git.
https://www.gerritcodereview.com/about.html
PR/MR is an "atomic" change (ideally the smallest change that can be landed separately - smallest makes it easier to review, bisect and revert)
Individual commits (or what "versions" are in Phabricator) are used for the evolution of the PR/MR to achieve that change.
But really I have 2 use cases for the commits:
1. the PR/MR is still too big, so I split it into individual commits (I know they will land together)
2. I keep the history of the evolution of the PR/MR in the commits ("changed foo to bar cause its a better approach")
Sure, your application has a dependency on that database, but it doesn't necessarily mean you can't deploy the application before having a database. Just make it acceptable for your application to stay in a crashloop until your database is online.
It’s not just nice for monorepos. It makes both reviewing and working on long-running feature projects so much nicer. It encourages smaller PRs or diffs so that reviews are quick and easy to do in between builds (whereas long pull requests take a big chunk of time).
I was never a fan of hg either, but now I can use jj, and get some of those benefits without actually using it directly.
Git is super mid. It’s a shame that Git and GitHub are so dominant that VCS tooling has stagnated. It could be so so so much better!
Are we back to "programming language X is slow" assertions? I thought those had died long ago.
Better algorithms win over 'better' programming languages every single time. Git is really simple and efficient. You could reimplement it in Python and I doubt it would see any significant slowness. Heck, git was originally implemented as a handful of low level binaries stitched together with shell scripts.
IOW, what do you know that nobody else does?
Phabricator and even Gerrit are significantly nicer.
Nothing since (Gerrit, Reviewboard, Github, Critique) has measured up...
I never understood the PR=branch model GitHub defaulted to. Stacked commits (ala Phabricator/Gerrit) always jived more with how my brain reasons about changes.
Glad to see this option. I guess I'll have to install their CLI thing now.
Probably relies on some internal metadata.
Right now I manually do "stacked PRs" like this:
main <- PR A <- PR B (PR B's merge target branch is PR A) <- PR C, etc.
If PR B merges first, PR A can merge to main no problems. If PR A merges to main first, fixing PR B is a nightmare. The GitHub UI automatically changes the "target" branch of the PR to main, but instantly conflicts spawn from nowhere. Try to rebase it and you're going to be manually looking at every non-conflicting change that ever happened on that branch, for no apparent reason (yes, the reason is that PR A merging to main created a new merge commit at the head of main, and git just can't handle that or whatever).
So I don't really need a new UI for this, I need the tool to Just Work in a way that makes sense to anyone who wasn't Linus in 1998 when the gospel of rebase was delivered from On High to us unwashed Gentry through his fingertips..
No idea if this feature fixes this.
Edit: Hopefully `gh stack sync` does the rebasing correctly (rebase --onto with the PR A's last commit as base)
Yeah, and I kind of see how git gets confused because the squashed commits essentially disappear. But I don't know why the rebase can't be smart when it sees that file content between the eventual destination commit (the squash) is the same as the tip of the branch (instead of rebasing one commit at a time).
I don't see how there is any other way to achieve this cleanly, it's not a git thing, it's a logic thing right?
The update branch button works normally when I don't stack the PRs, so I don't know. It just feels like a half baked feature that GitHub automatically changes the PR target branch in this scenario but doesn't automatically do whatever it takes for a 'git merge origin/main' to work.
We're in private preview and rolling out to folks on the waitlist in the coming weeks: https://gh.io/stacksbeta
Would welcome any feedback on the spec, CLI, workflows, etc.
Just using git, you'd send a set of patches, which can be reviewed, tested and applied individually.
The PR workflow makes a patch series an undivisible set of changes, which must be reviewed, tested and applied in unison.
And stacked PRs tries to work around this issue, but the issue is how PRs are implemented in the first place.
What you really want is the ability to review individual commits/patches again, rather than work on entire bundles at once. Stacked PRs seems like a second layer of abstraction to work around issues with the first layer of abstractions.
Curious whether this changes anything for the AI-assisted workflow. Right now I let Claude Code work on a feature branch and it naturally produces one big diff. Stacked PRs could be interesting if agents learned to split their own work into logical chunks.
* It amounts to doing N code reviews at once rather than a few small reviews which can be done individually
* Github doesn't have any good UI to move between commits or to look at multiple at once. I have to find them, open them in separate tabs, etc.
* Github's overall UX for reviewing changes, quickly seeing a list of all comments, etc. is just awful. Gerrit is miles ahead. Microsoft's internal tooling was better 16 years ago.
* The more commits you have to read through at once the harder it is to keep track of the state of things.
This isn't reddit people. You're not supposed to downvote just because you disagree. Downvotes are for people who are being assholes, spamming, etc...
If you disagree with a take, reply with a rebuttal. Don't just click downvote.
That said, while he hasn't posted here for a long time, this is still in the guidelines:
> Please don't post comments saying that HN is turning into Reddit. It's a semi-noob illusion, as old as the hills.
https://news.ycombinator.com/newsguidelines.html
I truly do not comprehend this view. How is reviewing N commits different from/having to do less reviews reviewing N separate pull requests? It's the same constant.
A chain of commits:
* Does not go out for review until the author has written all of them
* Cannot be submitted even in partial form until the reviewer has read all of them
Reviewing a chain of commits, as the reviewer I have to review them all. For 10 commits, this means setting aside an hour or whatever - something I will put off until there's a gap in my schedule.
For stacked commits, they can go out for review when each commit is ready. I can review a small CL very quick and will generally do so almost as soon as I get the notification. The author is immediately unblocked. Any feedback I have can be addressed immediately before the author keeps building on top of it.
Single PR with commits A, B, C: You must merge all commits or no commits. If you don't approve of all the commits, then none of the commits are approved.
3 stacked PRs: I approve PR A and B, and request changes on PR C. The developer of this stack is on vacation. We can incrementally deliver value by merging PRs A and B since those particular changes are blocking some other engineer's work, and we can wait until dev is back to fix PR C.
[1] https://andrewlock.net/working-with-stacked-branches-in-git-...
Until you can make it effortless, maintaining a substantial commit structure and constantly rebasing to add changes to the proper commit quickly turns into more effort than just waiting to the end and manually editing a monster diff into multiple sensible commits. But we take the challenge and tell ourselves we can do better if we're proactive.
I have never understood what this even means.
Either changes are orthogonal (and can be merged independently), or they’re not. If they are, they can each be their own PR. If they’re not, why do you want to review them independently?
If you reject change A and approve change B, nothing can merge, because B needs A to proceed. If you approve change A and reject change B, then the feature is only half done.
Is it just about people wanting to separate logical chunks of a change so they can avoid get distracted by other changes? Because that seems like something you can already do by just breaking a PR into commits and letting people look at one of those at a time.
I’ve tried my best to give stacked-diff proponents the benefit of the doubt but none of it actually makes sense to me.
> If they’re not, why do you want to review them independently?
For this example, you may want review from both a backend engineer and a frontend engineer. That said, see this too though:
> that seems like something you can already do by just breaking a PR into commits and letting people look at one of those at a time.
If you do this in a PR, both get assigned to review the whole thing. Each person sees the code that they don't care about, because they're grouped together. Notifications go to all parties instead of the parties who care about each section. Both reviews can proceed independently.
> If you approve change A and reject change B, then the feature is only half done.
It depends on what you mean by "the feature." Seen as one huge feature, then yes, it's true that it's not finished until both land. But seen as two separate but related features, it's fine to land the independent change before the dependent one: one feature is finished, but the other is not.
The feature is also half done in this case. The author can fix up the concerns the reviewer had in A and then both can be merged at the same time.
There is already an option to enable review comments on individual commits (see the API endpoint here: https://docs.github.com/en/rest/guides/working-with-comments...). Self-stacking PRs seem redundant.
Graphite (which they seem to be inspired by) has frozen branches exactly for that use case:
https://graphite.com/blog/introducing-frozen-branches
Here's something that would be useful: To break down an already big PR into multiples that make up a stack. So people can create a stack and add layers, but somehow re-order them (including adding something new at the first position).
I use jj to stack branches so i'll just be using the UI to do github pr stacks.
There seems to be a native stack navigation widget on the PR page, which is certainly a welcome addition.
The most important question though is whether they finally fixed or are going to fix the issues that prevent submitting stacked PRs from forks. I don't see any indication about that on the linked page.
As far as splitting work into different PRs that need coordinated merging, I've only ever encountered that when it's a long lived refactor / feature.
Every time I try to do it manually, I wind up screwing everthing up.
Very interested ot check it out.
> The gh stack CLI handles the local workflow […]
That's not "how it works", that's "how you['re supposed to] use it"… for "how it works" I would've expected something like "the git branches are named foo1 foo2 and foo3 and we recognize that lorem ipsum dolor sit amet…"
…which, if you click the overview link, it says "The CLI is not required to use Stacked PRs — the underlying git operations are standard. But it makes the workflow simpler, and you can create Stacked PRs from the CLI instead of the UI." … erm … how about actually explaining what the git ops are? A link, maybe? Is it just the PRs having common history?
…ffs…
(In case it's not obvious: I couldn't care less for using a GH specific CLI tool.)
They also allow reviewing commits individually, which is very frustrating to do without dedicated support (unless you devolve back to mailing list patch stacks).
I'm not a huge fan, since stacked PRs mean the underlying issues don't get addressed (reviews clearly taking too long, too much content in there), but it seems they want something that works for their customers, right now, as they work in real life.
It's a big improvement (assuming they've done it right).
If this works as smoothly as it sounds, that'll significantly reduce the overhead!
Has anyone already tried that was a graphite user before?
Stacked PRs are a development method, for managing changes which are separate but dependent on one another (stacked).
The two are orthogonal they can be used together or independently (or not at all).
I can't remember if Gitlab has the same limitations but I do remember trying to use Gitlab's stacked diffs and finding them to not work very well. Can't remember why tbh.
> This is a docs site that was made to share the spec and CLI for private preview customers that ended up getting picked up. This will move to GitHub docs once it’s in public preview.
(https://x.com/matthewisabel)
There’s a special case where certain official orgs can continue to use github.com instead of github.io for their Pages domain, and that’s how you end up with:
https://github.github.com/gh-stack/
from the code:
Should Pages owned by this user be regarded as “Official GitHub properties”?
def github_owned_pages? GitHub.github_owned_pages.include?(login) end
# Orgs/users that are owned by GitHub and should be allowed to use # `github.com` URLs. # # Returns an Array of String User/Organization logins. ...
I think they have a culture of circumventing 'official' channels and whoever is in charge of a thing is whoever publishes the thing.
I think it's a great way to train users to get phished by github impostors, if tomorrow we see an official download from official.github.com or even official-downloads.github.io, sure it's phishy, but it's also something that github does.
It's also 100% the kind of issues that, if it happens, the user will be blamed.
I would recommend github to stop doing this stuff and have a centralized domain to publish official communications and downloads from. Github.github.com? Come on, get serious.
TL;DR: DO NOT DOWNLOAD ANYTHING from this site, (especially not npm/npx/pnpm/bun/npjndsa) stuff. It's a Github Pages site, just on a subdomain that looks official, theoretically it might be no different from an attacker to obtain access to dksabdkshab.github.com than github.github.com. Even if it is official, would you trust the intern or whoever managed to get a subdomain to not get supply chained? github.github.com just think about it.
A stacked PR allows you to construct a sequence of PRs in a way that allows you to iterate on and merge the isolated commits, but blocks merging items higher in the stack until the foundational changes are merged.
I've done this manually by building a big feature branch and asking an LLM to extract out functionality for a portion of it.
For the former, it would seem to split based on frontend/backend, etc. rather than what semantically makes the most sense and for the latter it would include changes I don't want and forget some I do want. But I haven't tried this a lot.
I'm old enough to have worked with SVN and young enough to have taught engineers to avoid stacking PR in Git. All wisdom has been lost and will probably be rediscovered in another time by another generation.