Is This Really Required? Meet gh stack GitHub's new gh stack extension simplifies stacked pull requests by managing branch dependencies and propagation, allowing developers to keep diffs small and reviewable. The tool, still in public preview, automates rebasing and syncing across layers, with commands to view, navigate, and submit stacks. 🦄 I'm writing this post much earlier than I usually would for all of my work friends. I've been using gh stack since the preview was made available in the GitHub UI a few weeks ago. It's a game changer when it comes to working across multiple branches — or it will be just as soon as they get the rest of the kinks worked out.Hopefully this helps explain exactly what the extension does and when you should definitely be using it. Don't miss the agent setup near the end 🥞🦾 My boss told me to make my diffs smaller — consistently, and for long enough that I could recite the follow-up before it showed up in the comments: is this really required? My answer was nearly always yes, and it got overridden often enough that substantial changes stopped making it out the door at all. The obvious problem, the one we all already know, is that large diffs are difficult to read. GitHub agrees in their docs: Large pull requests are difficult to review and create bottlenecks, especially when AI helps you generate a high volume of code in a short time. gh stack https://docs.github.com/en/pull-requests/get-started/stacked-prs-quickstart fixes the thing I'd abandoned trying forever ago: stacking branches so the diffs stay contained and still get released in a single merge. The concept isn't new, and I've tried to maintain these by hand several times, which is not at all recommended. What's changed is that it's easy to work with — which matters as much on a repo my lead reads as it does on one nobody but an AI ever opens. Think of each PR as a pancake, with the plate being main or whatever trunk branch you started from. Every pancake in the stack targets the layer below it, and GitHub is in charge of the syrup between every layer from the top one down to the plate. Change a layer at the bottom and those changes have to propagate up through the syrupy goodness into the next one, which used to mean a rebase and a force-push, one at a time, in order, and made the whole thing useless for heavy dev work. Now gh stack manages all the syrup for you. You need gh installed and authenticated, push access to origin , and a clean tree on your trunk branch. Stacked PRs are still in public preview, so expect the edges to move accordingly. gh extension install github/gh-stack gh stack init auth-middleware creates a branch and checks it out git add . && git commit -m "Add auth middleware" gh stack add api-routes next layer, branched off the current one git add . && git commit -m "Add API routes" gh stack submit pushes everything, opens the linked PRs Branch names pass through exactly as given, slashes and all, so gh stack add refactor/foo gets you refactor/foo . Leave the name off and it stops to ask. submit is the half that opens pull requests. sync pushes branches and refreshes PRs that already exist, but it has no create path, so a stack you've synced ten times still has nothing on GitHub until you submit . Past two layers I stop remembering which branch I'm standing on, so this is most of what I actually type: gh stack view Arrows move through the layers, ↵ checks out whichever one you're sitting on, o opens its PR in the browser, and c and f expand that layer's commits and files without moving you anywhere — so I look at the whole stack, stop on the right pancake, and hit enter. When I already know where I'm going, the jumps are shorter: gh stack bottom the layer sitting on main gh stack top the newest layer gh stack down one toward the plate gh stack up 2 two toward the top gh stack trunk back to main itself Editing something at the bottom after the stack exists is the thing gh stack actually buys you. Go to the pancake that owns the change, edit it, commit, and run one command: gh stack bottom git add . && git commit -m "Fix the config default" gh stack sync If two layers touch the same lines, sync stops on the conflict and restores every branch to where it was, so nothing is left half-rebased. Dropping a layer takes the stack apart and rebuilds it from the branches you're keeping, in order: gh stack unstack drops local tracking and the stack on GitHub gh stack init auth-middleware api-routes rebuild without the layer you're dropping gh stack submit re-points the bases and relinks the stack Those branches already exist, so init adopts them rather than creating anything — the commits, the branches, and their open PRs all survive it. The only thing thrown away is the chain between them. One rule covers all of merging: whatever layer you're on merges everything from that layer down to the trunk, using whichever merge option you picked. Say you've got five layers sitting on main . If you only want the first one, merge layer 1 — layers 2 through 5 stay open and re-target onto the new trunk behind it. If you start from layer 5, you get all five, because everything between layer 5 and the plate goes with it. That one's open on layer 5, which is why it's offering all five. Everything above this line is optional if you integrate with AI, because of one command sitting in a tip box on GitHub's quickstart page and never mentioned again: gh skill install github/gh-stack That's an agent skill, and installing it hands the whole workflow over. The agent creates the stack, puts each concern in its own layer, commits into the layer that owns the change instead of whatever branch happens to be checked out, rebases everything above it, and submits the chain. I stopped running stack commands almost entirely — I describe the layers and read what comes back. One thing it can't do is decide the layers. Buried in the Copilot tutorial https://docs.github.com/en/copilot/tutorials/stack-ai-generated-code-in-pull-requests : you own the shape of the stack. The agent proposes them, and I decide whether the boundary between the data model and the endpoints is a real dependency or just where the model ran out of steam. I've used the skill since I found it and it makes my life a whole lot easier. I also have to keep reminding Claude to use it. Work started grading us on file diffs per PR, which finally put a price on a habit I'd had for years — sneaking small workflow changes and lint fixes into whatever branch I already had open, because they needed doing and I knew I wouldn't get another chance any time soon. Stacking gave me both halves: the cleanup gets its own layer, the diffs per PR stay small enough not to hurt my score, and the whole chain still goes out in one release. Nobody's grading my portfolio site, and every layer there gets reviewed by an AI instead of my lead. I redid the whole thing out of a series of prompts and came out with five PRs that were all still too big, because at work I ask for a small chunk and on my own stuff I ask for "rewrite this." Splitting them still earned its keep, and for exactly the reason GitHub gives: a smaller diff gets reviewed better. The diff doesn't care who's reading it, and handing an agent one layer instead of a whole feature leaves it less to review. I built a stack of reviewable layers to make AI more accurate, not me. gh stack does one thing, which is keep each diff small enough to get read properly. At work the reader is my lead and on my own projects it's an AI, and the tool doesn't care which — which is why it's worth running on a repo no other person will ever open. So before the next agent session, write the layer list yourself and paste it in with the ask using the /gh-stack skill: 1. data model and migration 2. CRUD endpoints that use the model 3. auth middleware and guards 4. integration tests Claude read GitHub's entire stacked-PR documentation set so I wouldn't have to, then a second pass caught that the draft had accused those docs of hiding four things they say plainly. It wrote this footer immediately after, which I'm choosing to read as contrition.