Hacker News new | ask | show | jobs
by sameenkarim 2 days ago
Hey from the GitHub Stacked PRs team!

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.

11 comments

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.

Github salaries can't afford devs from Google and Meta who have seen the bliss of a well oiled massive monorepo change management system and forge.
Having also worked with the tools you mentioned, is using commits in-place of "versions" + squash merging all that different?

  1. Adding commits means reviewers can easily diff changes to the PR
  2. Squash merging preserves only 1 commit per PR ends up on trunk
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.

Doesn't GitHub do this already? If I force push the PR branch, the PR shows a message about this with a link to diff it against the previous version.
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.

The seeming lack of engagement with prior art is so frustrating.
I think it's a very Microsoft thing. It's a parallel evolution of software branching from the microcomputer era.
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.

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.
This emphasizes the problem even more. Only one out of ten people use the force push approach, most others add commits to the PR.

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.

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.
Personally I find this feature works 50% of the time, and I don’t understand why.
IMO not using horrible opaque change IDs is one of the best parts of this. If I wanted it to work like Gerrit, I would just be using Gerrit.
You don't have to expose change IDs in the UI other than as a secondary thing! The current integer index would work just fine.
And enough of the time you can just match based on subject line, similar to how fixup/squash commits work with autosquash.

There’s enough ways you can match up commits, with plenty of prior art in this space.

Congrats Sameen and the rest of the team! Excited to see stacks make it into GitHub.

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-...

I tried to look through this earlier.

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).
Oh good! I have had a chance to try it.
What do you gain by having multiple repos?
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:

``` 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) ```

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

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.
This is the feature I’ve missed most from Gerrit. Thank you
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.
Your team did an awesome job - I’ve been wanting this feature for years and what you guys delivered is exactly what I had in mind.
> 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 needed this feature! Thank you
Why not to make it part of Git project? Such fragmentation adds complexity and vendor locking.
Presumably because "vendor locking" is pretty much their entire business model
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.