Have you ever been assigned to review a pull request (PR) that looked like this?
If so, you probably felt overwhelmed at where to start, uncertain as to what the pull request is about, and unsure of what the author expected from you.
Pull requests are much more than a display of code changes. They’re a historical artifact for your codebase and deserve as much time and attention as the code they contain. A pull request is an opportunity to convey what, why, and how a set of changes were made.
When an engineer (or you) stumbles upon your code in months or years, they can trace back to the pull request to find more information about a given change. Additionally, a pull request acts as a guide to your code for your reviewer. It gives the author a chance to explain the context of the problem and the background of their solution to the reviewer, and allows them to call out what they’re looking for in a review.
If you aren’t sure how to create a great pull request, here are a few tips.
1. Use a template
Creating a template for your team can ensure that you’re all on the same page when it comes to what should be documented in a pull request. It promotes consistency and encourages engineers to share their current understanding with teammates and future code-owners.
GitHub makes it easy to set a pull request template for an entire repository and has a handy guide explaining how to create one.
Some things to consider when creating your team’s template are:
- How do we ensure quality?
- What questions will help us in the future when looking back on this PR?
Here’s an example template that I use, but you should work with your team and organization to come up with a template that’s right for you.
Document the purpose
This is where you should describe the what and why of your pull request.
- What user story is being implemented or what problem is being solved?
- What value is this change providing?
- Why is this change being made or feature being added?
It’s important to note that the why is significantly more important than the what here. An engineer may be able to deduce what was done by reading the code, but they may never know why a change was made if the reason isn’t documented.
For example, the following pull request description doesn’t tell a reviewer much more than the code would:
In contrast, this description explains to the reviewer and future engineers why the change was made and why it’s important to preserve the functionality.
Explain the changes
This is where you should describe the how of your pull request.
- How was the solution or feature implemented?
- What new classes, files, or modules were created or modified to implement the story?
By explaining your implementation approach and the changes you’ve made, you can save your reviewer the time they would spend reverse engineering your code.
Provide additional context
Sometimes, the changes in a pull request don’t convey the amount of investigation and effort that went into debugging an issue.
Occasionally the solution to a difficult problem is a one line change, but providing additional context and background to explain to your reviewer and to future engineers how and why the one line change fixes the problem will go a long way. Remember that anyone in your organization (or outside of it, if your repository is public) could be reading your pull request. Don't assume that the engineer reading your pull request will be as familiar with the problem as you are.
Include screen captures
Are you committing a user-facing change? If so, adding a screenshot or a GIF allows your reviewer to see the new functionality and gives them higher confidence that your change works as expected. Additionally, adding screen captures can allow product managers and designers to review and approve the changes as well.
Pro-tip: macOS Mojave supports gif capturing natively, but Gifox and GIPHY Capture are powerful tools for creating screen captures as well.
Add testing notes
At Gusto, we don't have a quality assurance team. Instead, engineers are responsible for ensuring quality in all of their features. As such, it's important that we document how to manually test user-facing features that require complex setup, or how to manually test changes that aren't user-facing at all.
Save your reviewer time by clearly documenting testing steps in the pull request description.
2. Review your work
After you've opened your pull request and filled out the PR description, it's time to review your work. Pretend you're the reviewer and walk through the changes in each file. If you're using GitHub, you can provide in-line comments to grab your reviewer's attention. You also might catch a mistake or two that should be fixed before you assign a reviewer.
You can use in-line comments to proactively address something that looks out of the ordinary. If you think your reviewer will be uncertain of why a certain change was included, point out the reason.
You can also use in-line comments to start a conversation with your reviewer, or to ask questions about your approach.
3. Keep pull requests small
Finally, keep pull requests at a manageable size by splitting out unrelated changes.
If you need to refactor a class in order to add a new feature, then you should develop, review, and land the refactor before working on the feature. First, this makes each PR smaller, decreasing the odds that something will slip through the cracks. Second, this will make it easier for your reviewer to confirm that your refactor is only changing structure and that behavior is unchanged.
It can be tempting to land an entire feature at once, but I would encourage you to challenge yourself to break down the work into several small pull requests. Can you add the backend services for a feature in one PR and build the frontend in another?
Keep in mind that larger PRs will likely need additional review time and attention due to their size. However, if the size is overwhelming to the reviewer, a large PR is likely to get less time and attention.
So, with your team, develop a process to help you improve communication and documentation in your pull requests. You might find that a descriptive pull request isn't enough to ensure quality throughout your codebase. This is both the responsibility of the author and the reviewer. And, by the way, providing a meaningful code review is hard too. Stay tuned for a post on this soon.
Thank you to my former colleagues and Quan Nguyen for several of the ideas in this post, and to Lindsey Whitley for editing.