Sometimes, a PR grows too large, making it difficult to review. Splitting a PR into smaller, manageable pieces can improve clarity, facilitate more thorough reviews, and speed up the integration process.
Why split a pull request?
Ease of review: Smaller PRs are easier to understand and review, leading to more effective code inspections and fewer oversights.
Focused changes: Each PR can focus on a single aspect of the change, reducing the cognitive load on reviewers.
Faster integration: Smaller PRs can be integrated faster, reducing the time changes sit in review queues, which in turn minimizes merge conflicts.
Better discussion: Discussions can be more focused and actionable when they revolve around specific, isolated changes.
The case for short pull requests
According to a Graphite.dev blog post, the optimal PR size is approximately 50 lines. The data suggests that PRs of this size are reviewed and merged about 40% faster than those with 250 lines. Moreover, they are less likely to be reverted and typically garner more thorough reviews with 40% more comments per line of code. These bite-sized PRs not only expedite the review process but also enhance the overall quality and understanding of the code changes.
How to split an existing PR on GitHub
Identifying the split points
Before splitting a PR, identify logical breakpoints within your changes where the code can be divided into self-contained updates.
Steps for splitting a PR:
Create new branches for each segment:
Based on the identified split points, create new branches from the current branch's latest commit.git checkout -b new-branch-for-segment
Cherry-pick commits:
Usegit cherry-pick
to move commits related to each segment onto the corresponding new branches.git cherry-pick <commit-hash>
Push the new branches:
Push each new branch to the repository.git push origin new-branch-for-segment
Open new PRs:
In GitHub, navigate to each new branch and open a new PR for each segment.Close the original PR:
Once the new PRs are created, close the original PR with a comment linking to the new PRs for context.
Using Graphite CLI to split PRs
The Graphite CLI can simplify the process of splitting GitHub PRs by automatically splitting up an existing branch into multiple PRs by commit
or hunk
, using the gt branch split
command.
Steps with the Graphite CLI using gt branch split
:
Select the desired split strategy:
Determine whether you want to split the existing branch bycommit
or byhunk
. If the selected branch only has one commit you will enterhunk
mode automatically. If instead you wish to split your branch along already-defined commits you can use thecommit
mode.Run
gt branch split
:
Usegt branch split
with either the--by-commit
flag or the--by-hunk
flag.By commit using the
--by-commit
flag In this mode, you split your branch along already-defined commit boundaries. For example, if you have a branch with five commits on it, you could put the first three into one branch and the others into another. This preserves commit history of the original branch and its descendants.By hunk using the
--by-hunk
flag This mode allows you to split your branch by selecting hunks that you'd like to apply to each new branch. The interface is made up of iterative calls to git add --patch, which prompts you to stage your changes. You can split your branch by first staging only those you'd like to include in the first branch, then giving it a name, then moving on to the second, giving that one a name, and so on.Push the stacks and open PRs:
Push the new stacks to GitHub usinggt submit --stack
. This will prompt you to provide metadata for each newly created PR per branch.
Conclusion
Splitting a large PR into smaller, more digestible chunks can greatly improve the review process. Both Git and the Graphite CLI offer tools to facilitate this, whether through manual branch and commit management or through automated stack manipulation.
For more detailed command usage and to understand advanced features, refer to the official Graphite documentation.