engineering · ai · workflow
SICKO MODE: Splitting Branches
The Big Branch Problem™
Shipping a big branch of code is risky. The bigger it is, the easier it is for subtle but insidious issues to hide within. Big branches generate merge conflicts when working as a team. Also, big branches are soul-crushing to review.
LLMs take the Big Branch Problem™ to the next level, because they are the "go infinite" of the code generation strategy. They transmute a few sentences into a lever that slings 10K line code changes like it's Tuesday. And in the haystack of those changes, there's at least one needle of hallucination.
One. Dangerous. Fucking. Needle.
Luckily, you can also use LLMs to mitigate this problem. By adding a few prompting steps into your workflow before prepping a branch for review, you can carve things up, and de-risk the Big Branch Problem™.
Pre-Release...
- Simplify the code related to my current branch
- Code review the diff of my current branch, address comments
- Split the branch / PR into smaller incremental units, which can be reviewed and merged in series, with the latter parts being what actually releases my changes
1/2 are important, but topics for other articles. This article focused on the 3rd step - splitting up work into bite sized changes to release incrementally.
Use Case 1: Split a Branch in Half
Take this branch and split it into two new branches that can be released incrementally. Base the second branch off the first.
Why? A large code change (400+ lines) will take longer to review. You will put it off. You will skim it. If it touches critical areas alongside unimportant areas, it will introduce unnecessary risk.
My initial approach here was "split this branch into a series of branches to release incrementally." It works better to specify where to cut. Slicing the branch in half delivers more consistent results than slicing into many pieces. I've found it's more intuitive to measure/define where to "cut" the changes, rather than leave that segmentation process to the agent.
[prompt above]. In the first branch, include changes in
some_file.js, log statements, small refactors, and any changes which can be released without user-facing impact. In the second branch, include everything else which would impact production. (or however else you need it cut)
Use Case 2: Create Draft PRs with Conventional Commits
Create draft pull requests from those two branches, using conventional commit naming (eg "fix:", "feat:", "chore:"). In the pull request description, link to both pull requests in a numbered list.
Why? By splitting out the code changes from a large branch, it separates dependencies from their callers. This means some parts are missing from the second branch in review. In this case, the pull request description + sequence number acts as a manifest linking all the changes together, even after they're merged.
Use Case 3: Link Branches to a Task ID
Provide a task ID ("TASK-XYZ") and sequence number in the branch names (eg: "fix/xyz-1-branch-name", "fix/xyz-2-branch-name") and titles of the pull requests (eg: "fix: [TASK-XYZ - Part 1] Pull request 1", "fix: [TASK-XYZ - Part 2] Pull request 2")
Why? This is what allows us to link the branches together with a task ID or tag as we split them up.
NOTE: You can copy the prompt and just override the value with: Instead of task ID "TASK-XYZ", use "MY-NEW-ID".
Use Case 4: Move Changes Between Branches
Move all changes from
some_file.jsin branchfix/xyz-1-branch-nameto branchfix/xyz-2-branch-name.
Why? Splitting up the branches sometimes includes things that should be in one or the other. This lets us cherry-pick changes without having to manually jump between them. This one seems simple, but is very powerful — this kind of surgical branch-splitting gets messy.
Pulling It All Together
Take this branch and split it into two new branches that can be released incrementally. Base the second branch off the first. Create draft pull requests from those two branches, using conventional commit naming (eg "fix:", "feat:", "chore:"). In the pull request description, link to both pull requests in a numbered list. Provide a task ID ("UNI-XYZ") and sequence number in the branch names (eg: "fix/uni-xyz-1-branch-name", "fix/uni-xyz-2-branch-name") and titles of the pull requests (eg: "fix: [UNI-XYZ - Part 1] Pull request 1", "fix: [UNI-XYZ - Part 2] Pull request 2"). Instead of task ID "UNI-XYZ", use "MY-COOL-ID".
Then, review what it produces and use "Move [specific changes] in branch [first-branch] to branch [second-branch]" to fine-tune.