Post

Log inSign up

Post

Sameen Karim on X: "The launch of Stacked PRs is one of the biggest releases in @github history, touching almost every service we run I wanted to share some details about how we built it and everything that went into it Strap in folks, this is gonna be a long one 🧵"

  • user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    The launch of Stacked PRs is one of the biggest releases in @github history, touching almost every service we run I wanted to share some details about how we built it and everything that went into it Strap in folks, this is gonna be a long one 🧵
    5:06 PM · Jul 31, 2026390.4KViews
  • user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    At face value, stacks seems so simple. Groups some PRs, add a UI, ship it. But pull requests sit at the heart of GitHub. Nearly every service reads or writes to it. Changing what a PR is means changing all of it. In some cases, we were editing core code that hadn't been touched
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    We also didn't want this to be something that was just tacked on. It had to integrate natively and "just work" out of the box. You shouldn't have to change your rulesets or configs. Your CI workflows should run as you'd expect. Almost everything we did is downstream of that one
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    First, let's talk branch protection rules. Every PR in a stack is evaluated as if it targets the trunk, not the branch directly below it. So a rule you have for `main` governs every layer of your stack automatically. You don't touch your rulesets, and your security team can rest
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    Ok, so your rules probably require CI checks. Now we have to make sure all the Actions workflows are triggered too. A workflow scoped to PRs targeting `main` has to run on every PR in the stack, even though those PRs technically have a base of the branch below. Otherwise your
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    That meant some major changes to our internal plumbing. All the services/workflows that consume PR lifecycle events had to be updated to be "stack-aware" — and there's a lot 😅 We also of course needed to expose this externally with new webhooks and stack metadata as part of the
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    This introduced a new concept: a PR now has a base branch _and_ a merge target, and they are not always the same thing. This one could honestly be a whole article by itself, so I'll just leave it at that.
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    Code owners was a subtle one. What happens if someone edited the CODEOWNERS file mid-stack to sneakily get around review requirements for their upstack branches? So we had to freeze code owners evaluation at the stack base and effectively ignore all changes to it in the stack.
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    Then there's the merge box. Every time you load a PR, GitHub runs a simulation: generate the would-be merge commit, check for conflicts, evaluate rules and approvals against that commit. Oh and it live updates/recalculates every time there's a push or other change. It's an
    GIF
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    Stacks add specific conditions too. Every branch has to have a fully linear commit history. This may be one of the more controversial decisions we made because it requires rebasing. But we felt it was necessary because without it, we could not be confident in our security
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    The atomic multi-PR merge is one of the coolest things about stacks in GitHub. In one click, every unmerged layer below lands together, or none of them do. We generate all the commits and there's a single push to your target branch with all your changes. This is yet another one
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    After you partially merge a stack, we need to keep the remainder of the stack healthy and ready to merge too. This means retargeting the next upstack PR to point at the stack base. And running a cascading rebase across all the unmerged branches, without dropping approvals.
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    It was also important to have stacks work across all GitHub surfaces: web, mobile, Copilot, CLI, etc. It required a ton of coordination and I'm thankful to all the teams for rolling with the constant changes as we figured out how to get this right
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    But I do want to focus on the CLI for a bit, because it was a huge part of this ship. We didn't just want an API wrapper, but something that you could use for powerful local workflows. Something that's easy enough for someone who's never heard of stacking to pick up, while still
    GitHub - github/gh-stack: GitHub Stacked PRs
    From github.com
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    The `submit` and `modify` commands have a special place in my heart. Not just because I love a good TUI, but because of how much simpler it makes these difficult operations. The `modify` command supports some complex operations like reordering, folding, dropping, inserting
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    But we live in the agentic era and TUIs are not built for robots. So we had to build for both audiences: interactive inputs for humans and programmatic inputs for agents. There's a `gh stack view --json` mode that dumps the entire stack state. And the included skill file steers
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    And if you don't like our CLI, that's fine. I promise I won't cry 😭 Every stack operation is a public API, so you can build your own. There's no private endpoints or lock-in. We're already seeing open source projects and companies' internal tools updated to support the native
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    Speaking of APIs, we need to talk about merge again. We did have to make a big change: stacks can't be merged via the legacy synchronous merge APIs. Since stacks of multiple PRs can often take more than 10s (our global timeout), we had to move to async. Great news is that this
    docs.github.com
    REST API endpoints for pull requests - GitHub Docs
    Use the REST API to interact with pull requests.
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    We had to write an entirely new merge path for stacks. This was a huge undertaking, and it means there's still some work left to bring stack merges to parity with regular PR merges: - auto-merge - bypass rules - stacks across forks
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    And there's much more in store as we continue to push on both stacked PRs and improving the PR experience in general: - stack rebases can't generate signed commits (a gap more broadly with our server-side rebases) - improving the experience for rebase/force-push workflows (messy
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    That was a very long thread 😮‍💨 Thank you for making it this far if you're still reading. Behind all the sizzle, I wanted to show what goes into such a big release like this. Thank you to everyone who asked for this for years. It shipped because you kept pushing. Lots more to
    Stacked pull requests are now in public preview - GitHub Changelog
    From github.blog
    user avatar
    Sameen Karim
    GitHub
    @sameenkarim
    Jul 31
    P.S. Glad to still have a job after the 🥞 stunt in the navbar lol
    user avatar
    Anas
    @anelgarhy
    Jul 30
    thought it was called the "hamburger menu" not the pancake menu, @github explain yourself
  • user avatar
    Erk
    @eriktweets
    Jul 31
    Will it have 2(two) nines?

Log in or sign up for X

See what’s happening and join the conversation

Continue with phone
or
Log in with username or email

Relevant people

Avatar
Sameen Karim@sameenkarimFollow
Product @github leading Stacked PRs 🥞 Previously @rockerbox, @eventable Proud @UCBerkeley dropout

Trending now

Terms·Privacy·Cookies·Accessibility·Ads Info·© 2026 X Corp.