It’s pretty hard to review a PR with a +4k/-1k changeset that touches 72 files. PRs like that used to be rare, maybe if there was a large refactor or an upgrade that had to go in all at once. But now I run into them regularly.
Last week, when AI wrote two of those for me and I had to review them, I decided to try a new trick.
Well, the trick is actually old; I first saw it about seven years ago when I started working as a Tech Lead at Vena Solutions. Back then, our VP of Architecture really liked refactoring and cleanup, which often produced large PRs. To make those PRs palatable to us, he organized them into neat, very focused individual commits with one specific change in each commit, something like this:
f8ee9aa Rename class BadlyNamedClass to BetterNamedClass
18c240f Simplify logic in BetterNamedClass.SomeMethod()
1a4acf0 Update tests for BetterNamedClass.SomeMethod()
8b10bc0 Clean up unused imports
...(etc)...Some commits had a lot of lines changed, but it was the same change on each line (e.g. rename SomeThing to OtherThing). Other commits had a specific narrow focus, like a tweak to a complex algorithm. Each individual commit didn’t have to be compilable or pass tests by itself; it just had to tell the next chapter in the overall story of what the PR was doing.
You can get AI to reslice an existing PR
So the new trick that I tried was to get AI to reslice an existing large PR as a collection of small, focused commits. And it mostly worked! Not perfectly, but good enough that reviewing them was a lot easier.
So then I turned it into a skill (below); after using it on several more PRs, I think from now on I’ll be doing it every time just so that I can read the PRs myself.
---
name: restack-pr-commits
description: 'Reorganizes the PR as a series of easily reviewable commits.'
argument-hint: 'for pull request <PR URL>'
---
## Overview
The goal of this skill is to turn a large, hard-to-review
PR into a series of commits that are each individually easy
to review. The commits, once fully stacked, must match the
original PR character-for-character.
Each commit is "easily reviewable" if it introduces a
relatively straightforward change. It can be a commit
affecting a large number of lines that does something simple
(e.g. rename a variable or clean up unused imports),
or a commit that adds a specific tricky concept in one
file, or something in between. Generally, new tests
should be added separately from the newly added code,
but a change to functionality can have a single commit
spanning both the main code and the tests.
Each individual commit doesn't need to pass the build or
the tests; the primary criterion is reviewability.
## Steps
You should have been provided a PR to work on. If you
haven't, stop and ask for it.
Make sure that you're clear on which branch the commits
are based on. We'll call this branch the "base branch".
This would usually be the repo's main branch (called
`master`, `develop`, `dev`, or `main` - this depends on
the repo) but it may not always be the case. If it's
unclear what the base branch is, stop and ask.
1. Check out the PR's branch locally. Make sure you're
on the latest version of it. Once done, your
current branch should be the PR's branch. We'll
call it `{current-branch}` from now on. If during
this step you cannot use `git` or `gh`, stop and let
the user know, as you won't be able to proceed further.
2. Make a backup of the current branch.
- Do:
- `git checkout -b {current-branch}-backup`
- `git checkout {current-branch}`
So that you end up with the backup of the current
branch, but you'll still be working on the current
branch. DO NOT drop the backup branch; we will
leave it forever as a backup, so don't clean it up.
3. Come up with the commit breakdown.
- Review the contents of the PR, the PR description,
and any relevant documentation to fully understand
the changes.
- Come up with several distinct ideas for how to
split up the PR into easy-to-review commits.
- Come up with the criteria to figure out which of
the choices is best.
- Review each of the proposals for the split. Evaluate
them against your criteria, critique them, and rank
them against each other.
- Based on your critiques, update each of the options
for the split.
- Critique and rank these options again and come up
with the final ranking.
- Come up with the final recommendation for how to
split the PR into commits. The final recommendation
may be any combination of the proposed
recommendations based on your analysis.
4. Figure out a strategy you'll use for verifying that
the final result matches the current PR
character-for-character. Make appropriate preparations
as necessary.
5. Rebuild the PR as a series of commits on top of the
base branch as per your proposal. After each commit,
verify that the commit has added exactly what you
think it should have added and that there's nothing
missing and no copying errors. If there are any issues,
amend the commit as needed. Each individual commit
doesn't need to pass the build or the tests, so don't
rerun those between the commits.
6. Verification: when done, verify that the final
result matches the current PR
character-for-character. If not, fix any commits
as needed.
7. Rerun the build and the tests as needed.
8. Force-push the changes to the origin so that the
PR now looks like a series of new commits.
Do not clean up the backup branch; we may need it
later if there were any issues.But what about stacked PRs?
If you aren’t familiar with stacked PRs, this GitHub page gives a decent overview.
They’re certainly an option, but I find that before starting the implementation, it’s not always clear which PR should be the base PR, and sometimes after a lot of fixes and follow-up tweaks, the stack needs to get reorganized a lot, which is annoying to do when you’re dealing with PRs instead of commits.
And it’s a lot more practical to reslice a 4k LOC PR into 20 commits rather than 20 stacked PRs.

