Pull/Merge Request Peer Review: Good Practices
I wrote this when I was at muster.chat. It is lengthy, and it is draft.
The polished version is much nicer
The merge review process is a common part of the software development lifecycle now, and this document covers practices that can help improve the process and make it smoother and maybe even more enjoyable for your team.
Good Practices
This document started its life as a “Best Practices” document, but “Best Practice” only applies within a specific idealised scenario. In reality, few, if any teams are within this context.
Accepting the reality of life, the document is about good practices. All of the practices here will bring benefits. Some of them will bring more benefit than others, but by the same token, some of them are more work to implement.
You will have to decide how you want to take this journey of improvement of the review process. It is far better to implement one change that is sustainable than try to implement 5 changes that fall by the wayside in a month or two.
Slow and steady (and deliberate) wins the race
- Aesop
Pull/Merge Request
These days, code reviews are usually done through Pull Requests (by GitHub,
Bitbucket, Gitea, etc.) or Merge Requests (by GitLab).
Pull request, as a concept makes more sense in open source software where someone forks a repo and requests their changes to be “pulled” into the original repository.
Within the context of a team where the requests are internal, the term merge request is easier to understand.
Both the terms are generally used interchangeably.
Target Audience
A lot of the items in this document can be valuable for review processes in all kinds of software development teams. However, this document is primarily aimed at teams who collaborate internally with trusted members, i.e. within an organisation as opposed to open collaboration with strangers.
A little history
Old School Code Reviews
Code reviews can add a lot of value to a software engineering team. Before git, and pull requests (or merge requests), code reviews happened differently.
There would be physical gatherings, and everyone gathered around a single computer, or the code was printed out (leading to the 80 char line length limit that we see even now).
There were also email based reviews, attaching the patches to emails, which the reviewers replied to with comments or suggested changes. In some cases source control systems were set up to automatically email people on each commit.
These reviews were after the fact. The code was already merged in and the outcomes of the review were added afterwards.
The revolution that git brought
Git brought with it lightweight branches, and along with a more ubiquitous internet, the path was paved for pull/merge requests.
Gerrit, by Google provided an early implementation of a workflow where changes could be proposed, discussed and reviewed before merging. This process was refined and followed up by the git platforms like GitHub and GitLab soon after.
Reviewing code before merging it in is such a common pattern now largely due to the great deal of value it brings. These processes have been a game changer for open source software which gets contributions from external, often untrusted parties.
Teams that only have contributions from trusted sources also implement processes to review code before merge. These processes, however, can be tuned for much higher velocities and is our main focus.
The Pull Request
The concept of the Pull Request was invented by Linux Torvalds with the
introduction of git-request-pull into git.
The idea of it was to support pulling in changes from a forked repository. GitHub subsequently popularised the concept.
Benefits
With a good peer review process in place, every team should be able to improve their effectiveness, and improve the quality of their code base. These benefits usually result in the team being able deliver better software and in a more timely fashion, which also improves the team’s credibility.
Improved Code Quality
Alexander Pope pointed out that “To err is human,” and you probably know the proverb that “two heads are better than one.” Peer reviews bring the benefits of expertise from multiple people to improve the quality of code.
This brings in benefits in the form of:
- Decreased defect rate
- Improved Security
- Improved maintainability
Arguably, if your entire team review a bit of code, it should have all the good qualities of code from your entire team. While impractical and with diminishing returns, the key is however to get the right people to review code for maximum benefit.
Improved Team Effectiveness
This is by far the biggest benefit of code reviews. Each review improves the knowledge and the capability of the team. Reviews also help to reduce the risk of knowledge silos by encouraging knowledge sharing.
Working together as a team also has other benefits including improving morale, the work culture and engendering a sense of purpose, all of which leads to longer term employment.
Improve Team Communication & Collaboration
Good code reviews encourage team members to interact and work out how to express their thoughts and feeling about lines of code. Apart from helping to strengthen the relationship between the members of the team, it’ll also improve the teams ability to communicate with each other, making the team more effective overall in achieving its goals.
Knowledge Sharing
There are multiple knowledge sharing benefits. The biggest one is an improved level of general product and code base knowledge within the team. In other words, it helps to mitigate knowledge silos.
It’s a good idea to get team members who are unfamiliar with the code in the PR to review them. An outside perspective can often help to raise potential issues or opportunities that were not previously considered. It would also help with cross pollination in terms of knowledge sharing.
Another valuable aspect of code reviews is in the onboarding process. By reviewing other requests, new starts get a safe space to dive into the code and get a better understanding of how things work. A fresh perspective can also help identify potential blind-spots and areas for improvement. On the other side, when they ask for a review of their code, they also get early feedback, which can help them re-align their ways of working and understanding as required.
Code reviews are a good way to maintain high visibility of the code base and changes to it. This awareness and knowledge of the code base helps to reduce or eliminate knowledge silos and improve the all around quality of the code.
Team Cohesion & Resilience
With both of the above, the team has better cohesion. By eliminating knowledge silos and improving the level of knowledge of the team, the team is able communicate better within itself, and externally. Every team member is more likely to give the same answer to a question, and reliance on any individual to be able to answer a specific question diminishes over time. Furthermore, a new team member will find it easier to onboard to the team and when a member is on vacation or leaves the team, there is less of a knowledge gap.
There is one other valuable aspect, and that is of alignment. The peer reviews become a near constant form of checking in on direction. With these check-ins the team as a whole is going to be moving together in the same direction.
Improved Team Credibility
Improving the code quality and the team effectiveness are powerful tools to be able to understand what the team is capable of delivering and in delivering it effectively. This capability will inevitably improve the credibility of the team and its ability deliver.
Challenges
Doing peer reviews of merges can also have some challenges, though they are usually easily overcome. A team that refuses to do code reviews may have more fundamental challenges to overcome first.
Collaboration Requirement
Doing regular peer reviews requires a high level of team collaboration, starting with the logistics of when and how the reviews happen. However, practicing peer reviews usually improves team collaboration.
If the collaboration requirements are too high for a team, the team likely has far larger challenges to tackle first.
Infrastructure
Being able to do peer reviews requires tools that support in it. Fortunately, there are plenty of platform that support this (e.g. GitHub, GitLab, Bitbucket) and you can even deploy your own ones (e.g. Gerrit, GitLab).
Getting a working setup for managing peer reviews for merges should be negligible effort and cost as it has become a part of most development processes today.
Misconceptions
There are plenty of misconceptions about the merge peer review process. Let’s cover some of them here. If you know of others, please let us know, and we’ll update it.
It slows things down
It is easy to understand why it might seem like peer reviews can slow down development. In a way it does: a software product that does not have peer review might get delivered sooner under some rare circumstances. However, once the most critical preventable bugs are addressed, it will likely have taken longer, and have cost goodwill and morale.
Code reviews in fact speeds up development because the sooner you can find potential problems, the easier and quicker it is to resolve.
This is probably the perfect time for a reminder that:
The only way to go fast is to go well
– Robert C. Martin (Uncle Bob)
The improved alignment of the team also means that even if everyone is moving a little slower, everyone is moving in the same direction. Contrast this with a team where everyone is moving quicker but in (slightly) different directions.
Only Senior Developers Review
One reason for a peer review is to improve the quality of the code. An engineer with a lot of experience will bring value to the review. There will be issues that they are better at identifying and helping to resolve. However, having someone with little or no experience review code will also contribute to improving the quality of code. Part of this is simply from having another point of view. The more diverse the input you can get, the more valuable the review. Each of us know different things, and have different strengths. The more people who collaborate, the higher the quality is likely to be.
There are other reasons for code review including visibility and building familiarity. There might be parts of the code that impacts others work either now or in the future, and it’ll make it easier for others to do their work later. There are also opportunities to learn from code reviews, including from junior developers who may be looking at the problem through a different lens.
Only for big Projects
It might be true that the larger the project, the more value peer reviews can bring. A lot of this value comes from the diversity of feedback that can be collected. However, a small two person project also benefits from peer review. While the diversity in perspective might be lower, having more than one perspective is still hugely valuable.
Peer reviews are a great way to catch potential issues early, even in small projects and this can have a positive effect on morale and the external perception of the teams ability.
Pursuing Perfection
Reviews are not about someone with more knowledge or experience imparting their wisdom to others. It is also not an effort to get the code base perfect! There is of course no such thing.
Peer reviews are about collaborating together to build something, within the constraints of the circumstances, that is a well thought out way to solve the given problem.
Alternatives to Peer Review
Pair Programming
Pair programming can function a little like a code review session. Due to its nature, it can reduce the requirement for code reviews, particularly in a tiny team. However, it is still a good idea to get code that was done in a pairing session to go through a code review. The more diverse the perspectives you can get, the better.
Mob Programming
Mob programming would effectively eliminate any requirement for code reviews since the code is build collaboratively, with the review happening live.
The Basics
The more frequently we integrate, the less places we have to look for conflict errors, and the more rapidly we fix conflicts.
– Martin Fowler
Before git, everybody committed directly to the main branch, which was called trunk. It was a good idea to commit (or integrate) early and often. Otherwise, you’d find yourself with merge conflicts.
The PR/MR flow is essentially the same, except that the old school commit has become the request to merge.
When to review
While there is good reason to gate the review on merge, this is not always the best method. There is no reason for it to be the only method either.
The review that happens at each stage has different priorities as well.
Before writing code
It’s a good idea to come up with a plan of action for how you are going to solve the problem. You can come up with the initial solution collaboratively. Alternatively, once you have a viable solution, run your team through it to get additional opinions and perspectives. Course correction here is the easiest and the lowest cost.
The main purpose of the review here is to ensure that the approach is sound, no critical options or possibilities are missed, and more importantly that the correct problem is being solved.
Draft Reviews
If there is some complexity it may be worth getting some additional perspectives once you have some tests and rough code. The draft review may also be valuable if you are new to the team or to software engineering.
The review at this stage again focuses on the overall approach and ensuring that there are no gaps in communication or understanding.
Ready to merge
Most reviews happen when a small enough bit of work is complete. This stage is also where most reviews tend to happen.
The main outcome here should be to ensure that the change does not negatively impact the code base and that it adds value.
The main question to be asked is:
Is it good enough to merge
There could be changes and fixes that are improvements that could be completed in subsequent merges and that is to be expected.
After the merge
There is no reason to ignore a review because it has been merged. The best time to find an issue is when the code is being written. The second best time is before it impacts the customer.
Once the code has been merged, there is less time pressure and the review can happen with more rigor. Any improvements that come out of the review can be completed in subsequent merges.
Your Motivation
While there are lot of benefits to the team from doing reviews, what are the benefits to you?
As a requester
Getting your code reviewed isn’t about getting it “checked” or “graded.” It is about a collaborative effort to try to ensure that the quality of the code is in general as high as reasonably possible.
Part of the benefit to you is that there are likely to be fewer defects in the code you write. Nobody wants the customer to be impacted by a bug (particularly a critical one at the weekend), and this is one way to try and mitigate that risk.
You could learn something new. No matter how long you have been writing software, there is a good chance that you can learn something from someone else reviewing your code. Continuous improvement applies not just to the code, but also to our abilities.
It is also an opportunity to mentor the more junior members of your team. Learning to mentor others is an important skill in becoming a better engineer.
Asking for someone to review your code is a privilege. There is no need to be entirely responsible for the code you write, and to try and think about all the ways in which it could do wrong. Lean on your team.
Encourage your team to ask questions. Perhaps you were too close to the code and didn’t realise that some of it isn’t as easy to understand. You’ll appreciate making it easier to understand when you come back to it in six months or a year.
As a reviewer
Depending on your level of experience and your role, there are many benefits from reviewing code.
Reviewing code is undoubtedly a privilege and a valuable activity for the reviewer. When defects are found, it impacts the whole team and usually also impacts the customer. In a lot of cases, a code review could have picked it up and prevented it altogether. The time spent in code reviews is paid back many times over in the time saved hunting bugs and in the related restorative work. It will reduce stress and effort for the future you.
Having a better understanding of the code base as a whole has its own benefits. It is also an opportunity to align on tools and libraries in use.
There are further benefits based on your experience and role.
Junior
Of all the roles, the junior developer perhaps stands to gain the most from code reviews. It is worth taking every opportunity to do reviews. These are excellent opportunities to see how others solve problems and to ask questions.
Reviews aren’t just about making software better. It is also about making sure that the code is easy to understand and to follow - for everyone. If you are unsure about something, ask the question. Maybe the code needs to be simplified.
Senior/Lead Developers
The biggest advantage for senior/lead developers is the opportunity to check that the code being written is in line with your expectations and direction. Reviews are the most valuable opportunities to ensure this.
Unless you are in a small team, it would make sense to focus on the big picture and on mentoring the more junior members of the team to pick up the smaller details in the review.
Your experience will help you pick up potential issues that others may miss, and it is critical to flag these. In identifying these at this stage instead of in production, you are saving yourself a great deal of pain in the future.
Quality Assurance/Product Owner/Scrum Master
If you use Behaviour Driven Development (BDD)—and you probably should—it would make sense for the whole team to do some code reviews including the Product Owner. This opportunity is really valuable for the PO and anyone in Quality Assurance to close any gaps in understanding of what the code should be doing.
If you are not using BDD, it is still a good idea to try and make the tests, particularly the functional ones as easy to understand as possible. Peer review is an opportunity for the whole team to check their alignment. The better you are able to make use of it, the more value it will bring.
Empathy & Compassion
Peer reviews are a social and collaborative activity. It is important that you bear this in mind when doing reviews. No matter what the issue or disagreement, put the people first. It is more important that you collaborate to a reasonable solution than getting the code into some “perfect state.”
Remember, that one of the purposes of code reviews is for the whole team to pull in the same direction. Explain, clarify and discuss solutions and alternative ways of doing something. Ultimately, any action should be agreed together as a team as much as possible.
The priorities in communication should be:
- Kindness & Compassion: It is difficult to know what others are thinking, or what they are going through. No matter how you feel about someones work, express it with kindness and compassion.
- Polite: No matter who you are or who the other team member is, it is important to be polite. Being rude damages credibility and team cohesion.
- Respect: Another valuable trait in any team member, the absence of which results in losing credibility, team cohesion and morale.
- Direct Communication: Talk about the code, not the person, and about how it could be improved. Avoid value judgments and make your statements as objective as possible.
- Humility: The aim is to improve the quality of the code. No matter who found an issue or how embarrassing it might seem, it is more important to improve the code. Appreciate the input so that they are motivated to find issues for you next time. Remember that it’s better to find the issue now than in production.
In other words, consider the team and its members to be the most valuable, and through a better understanding of each other and collaboration, aim to achieve the outcome of improved code.
The Review
The review is a whole team process and starts long before the request comes in.
As the team
Be holistic
As humans, we are prone to bias, errors, and unverified claims. Peer reviews can provide differing views which serve to question and dispel at least some of these and helps to improve rigor, credibility, and diverse perspectives. These benefits can go beyond code.
The more holistically you can consider your reviews, the more value you can get out of it. Consider the impact of code everywhere, not just in that context that it was built. How does it impact:
- Infrastructure
- Costs
- Customer / User
- Support & Maintenance
- Marketing
- Other areas of the business
How can you ensure that code review takes all the relevant areas into consideration? What else could benefit from review?
Defining and continually improving processes that support this is important.
Processes
If you don’t already have an agreed set of guidelines and expectations, you should work towards getting that in place. These guidelines should include:
- Coding standards (use pre-existing ones if at all possible)
- Branch naming (and validation)
- Rules for TODO’s and other tags (and checking)
- PR naming strategy
- It is a good idea to treat the PR title as the merge commit title
- Git guidelines
- Conventional commits?
- How much to curate and fixup commits (or whether to squash)
- Architectural Safeguards
- Modular Components to minimise merge conflicts
- Knowledge Sharing
- How will you avoid single person dependencies for code reviews?
- How will you mitigate knowledge silos?
- Review Process
- When is a PR in draft state, and when is it ready?
- How should branch protection work?
- Target time until first review?
- Target time to merge per PR?
- What’s the maximum size of a PR? (recommendations later)
- What constitutes a request for change instead of approval? i.e. what blocks a merge?
- When do you request a re-review?
- What kind of changes can happen in a subsequent PR? (How) do you track those requests?
- Who commits? Merge, Squash or Rebase
- It usually makes sense for the requester to do the merge, at the very least as a way for them to close off the work they have completed.
- Review templates
- Who does reviews? How many reviews are required?
- Communication
- Who needs to be included
- What areas of impact needs to be considered?
- Ownership
- Which team is responsible for which parts of the code (set up CODEOWNERS)
Automation
Once you have agreed as much of the processes as possible, the next step is to automate as much of those as possible. For instance:
- Validate:
- Branch names
- Commit messages
- Size of PR
- Configure review rules:
- Branch protection rules
- Minimum Reviewers
- Run linters (configured with your coding style)
- Configure auto-detection of common errors:
- Stray print statements
- Newline at end of file
- Spaces at end of line
- If possible/relevant, assign reviewers
- Build & Run all tests
- Deploy a test instance
- Static Code analysis
- Scan for dependency updates
- Scan for security vulnerabilities
Automating these will make it pull requests quicker and allow their reviewers to focus on the more important issues. It also means that the requester can “self-serve” to improve quality themselves.
Collect Metrics
The next part, which is also important is often ignored in development teams. Collecting the metrics of your development process is at least as important as all the metrics you collect from running systems.
The metrics you collect can help you identify process issues, improve, and to measure progress.
Some of the valuable metrics you can collect are:
- Size of PR (lines of code)
- Time to first review
- Reviews per PR
- Cycle time (time from PR creation to merge)
- Defects (and seriousness)
Continuous Improvement
Another key part that should be done as a team is continuous improvement. Having an intention to monitor and continuously improve the process is a key part of agile, and is no different when it comes to peer review.
The metrics you collect (from the above section) should help with this.
Metrics aren’t everything though - you could bring cycle time down to zero by not doing a review but that will almost certainly increase defects.
As the Requester
As the one requesting a review, the largest burden of the process falls on you. The goal is to get high quality reviews from a reasonable number of relevant people.
To achieve this, you want to make the review as easy as possible for the reviewers. One important aspect of the process is making sure the feature you are building is the feature that was asked for. The second part of this is validating that you are building it the way it is expected.
Only once alignment has been confirmed can we move on to general code quality, bug finding, maintainability, and the other benefits that the review brings.
Break it down
Before you start on your feature, it’s worth thinking about how you are going to split it into PR’s. Unless it’s a tiny feature, you will likely want to do multiple self contained small PR’s to complete the feature.
If the implementation of the feature is nontrivial, another thing you might want to do before you start is to work out a rough plan of how you are going to implement it, ideally collaboratively with the team.
This can help validate alignment, both on what your going to implement and how.
Each subsequent PR is an opportunity for further validation. If you need course correction, the earlier it is flagged, the easier it is.
Prep while you work
While you are building the feature, it’s worth thinking about what will go in the PR description:
- What specific part of the feature is getting implemented?
- What screenshots would represent the functionality?
- Are there screen recordings that could help the reviewer understand the functionality?
- What’s the impact of this specific change?
- Are there any risks?
- What should the reviewer test? How?
It may help to start collecting some of this into a draft request while you are working through the implementation.
Keep it small
With small code reviews, the reviewers will find it easier to hold the whole change in their mind, which makes it easier to reason about what the change does, and its impact. This results in:
- Faster reviews
- Better reviews
- Improved quality
- Better velocity, i.e. quicker merges and development of features
- Easier collaboration
How small you ask? There is evidence that the ideal PR is 50 lines (or fewer) , which might be too small. It is a good idea (1) , (2) , however, to aim for PR’s to be no more than 200 - 400 lines. The limit will depend on factors like how verbose your language is (e.g. Java).
Split the PR if it:
- Is too large
- Does more than “one thing” (e.g. two features, or a feature, and a bug fix)
- Has high complexity, risk, or impact
Creating the PR
Ensure the PR has more context than might be necessary, particularly if there could be reviews from people who may not be fully aware of the motivations behind the change. Ideally the reviewers are already aware of the feature, the motivations, and the approach for solving the problem before they ever get the request.
If the reviewers know to expect a PR and have a rough idea of what to expect from it, it will be easier for them to plan for it, and to do the review.
Good idea of things to include in the PR description:
- Link to the issue/feature/story that is tackled, including details of:
- Why is this being done?
- What is the expected end result?
- Details of exactly what part of the above is being tackled, including details of what has already been completed and what’s next, if relevant.
- Screenshots of the change
- Video if relevant of how it works.
- What questions should the reviewer answer for you?
- Detailed instructions on how to test it. Another place where a video might be helpful.
- The impact of the change, including to:
- Infrastructure
- Costs
- Maintenance
- Support
- Customers
- Data
- Regulations (e.g. GDPR)
- Identified risks, if any
The smaller the change the easier it will be to be thorough about all the above.
Before assigning any reviewers, the final step is to do a Self Review. Put yourself in the shoes of a reviewer and do a review of the whole PR, starting with the above. It is better if a reviewer finds an issue instead of your customer. Similarly, it is better if you find an issue instead of a reviewer.
Waiting
While waiting for the review, it is a good idea to do any pending reviews so that you can help unblock others work. If there are none that you can contribute to, you could use stacked PRs (aviator.co can help with this) to carry on with your work. Avoid building up multiple stacks though as each stack will require additional effort to keep in line with “upstream” changes.
Making Changes
A good review is one which catches issues that you hadn’t thought about. Better to find them now than in production. Appreciate the time and effort that the reviewers have put in to help you out.
Prioritise, discuss and implement the changes. Focus on the changes that are
easy to implement, then the ones that are crucial to be able to merge the PR.
Take a note of the remaining changes for subsequent PRs. It is a good idea to
fixup with git to curate your commits rather than having commits that
fix stuff from review.
Depending on your team guidelines, request re-reviews as required, but ensure
that you are not using your reviewers as someone who checks your work. It is
after all, a Peer review.
Merging the request
Before you merge, ensure that nobody is currently in the process of reviewing your code. Reviewing code can take time and it can be frustrating if a PR is closed while in the middle of a review. It is important to communicate with your team to avoid gaps in communication. The PR process does not remove the requirements for communication.
Once you have a request ready to merge, go ahead and follow the team guidelines on merging. Well done!
It is a good idea to appreciate the reviewers for their input and feedback. Software development is easier when done collaboratively. When your reviewers feel like their contributions valued, they are more likely to enjoy doing reviews for you.
As the Reviewer
Reviewing code is hard, but is worth the effort. Here are some strategies to make reviews easier as well as more effective.
The quicker you can do the review, the better. The person who has requested the review could be (partially) blocked until the review is complete. Furthermore, lean methodology would consider it as waste the longer the code is not merged in. This requirement, of course, has to be balanced with maintaining focus for yourself and minimising interruptions.
Reviews are not about checking someone elses work or about grading it. It is about learning (for both of you), collaborating and improvement (code and your abilities). Bearing this in mind, LGTM (Looks Good To Me) reviews likely add the least value.
If you do not spot any areas for improvement, consider pointing out areas that stood out for you, or that you learned from. Review is collaborative and appreciating someones work is an important part of collaboration and team building.
Time Limit
It is a good idea to limit a review session to no more than an hour. “Vigilance decrement ” is the decline characterised by reduced accuracy and slower response times when performing tasks that require sustained attention. In fact, the clock test, a 1948 study showed a decline in ability by 10 - 15% after 30 minutes.
If a PR looks like it’ll take longer than an hour to review, it may be better to ask them to break it up.
Another option might be to split the review into multiple sessions.
Goals
Why are you doing the code review?
If you are a more junior developer, or new to the team, you may be looking to learn about the code base or engineering in general. When you learn something, consider adding a comment. These comments can help to reinforce your learning, validate your understanding and appreciate the requester. Code reviews aren’t only about improvement.
More senior developers may be more interested in preventing defects and maintaining or improving the quality of the code base. Mentoring and coaching could also be a part of that. Try to bear in mind that mentoring and coaching can also apply to other reviewers.
Having an idea of what you are looking to get out of the review is important. Remember that while doing a code review is hard, it is also a valuable opportunity: to learn, to contribute, and to collaborate on curating the source code which is an important asset owned by your team.
Communication
Being constructive in your communication goes without saying and helps to build a collaborative process focused on improvement.
Avoid “You”
To make reviews easier, it is a good idea to talk about the work and not the person. One straightforward strategy you can use is to avoid the word “You.”
Let’s try an example:
You misspelled ‘successfully’
How did that feel, compared to:
sucessfully -> successfully
How about another one?
Can you rename the variable to be more descriptive?
compared to:
Can we rename this variable to be more descriptive?
Using ‘we’ above also helps to reinforce the collaborative team nature of a review.
There are of course exceptions, particularly when you want their opinion, but be conscious that it does not come across as passive aggressive.
What do you think about X?
It might take a little while to break this habit, but it is worthwhile. If you would like know more about this, you should look up Transactional Analysis (TA), a psychoanalytic theory and therapy that can help with communication.
Avoid Value Judgments
Whether something is good, bad, right, or wrong is usually too subjective to be constructive or valuable. Focusing on the why can be more helpful. Another option is to make it clear that it is an opinion.
This library is a bad choice
can be improved:
This library looks like it’s not maintained, and could cause us issues. We should use X instead.
or even:
I think this library is a bad choice because I did not enjoy working with it before.
By making it clear that it is an opinion, it makes it easier to talk about.
Ask Questions
Regardless of seniority or experience, if you do not understand how or why something is the way it is, ask the question.
Code should be readable and easy to understand for everyone. The fact that you had to ask might be indication that the code needs to change to be easier to understand.
It is usually better to make the code easier to understand than to add a comment with explanations.
Be Specific and Offer Alternatives
When talking about improvements, strive to be specific, and to offer alternatives.
This function takes too many parameters
Does not help the requester.
Having so many parameters hurts readability and suggests that the function may be doing too much. Can we refactor this method to simplify it?
If you do not have a solution, it would be better to open a dialogue.
I am worried that the number of parameters here hurts readability. Can we talk about how we can address this?
Collaboration is a powerful tool when it comes to improving quality of code and working out effective solutions.
Communicate
If you are not going to be able to do a review or a re-review, let the requester know so that they can carry on.
If there is something which is better reviewed synchronously, request a call/meeting as relevant. Sometimes a quick 5min call can save a 20min commenting conversation, not to mention potential misunderstandings.
Affirm & Appreciate
When you see something valuable or if someone has gone an extra mile, or maybe only half a mile - call it out and appreciate them. Code reviews aren’t only about opportunities for improving the code. It’s also opportunities to improve the team cohesion, wellbeing and morale. By calling out good work, you will also be encouraging it.
Invite Discussion
Consider phrasing nontrivial comments as invitations to discussion rather than being prescriptive. Collaborating to a mutually agreed outcome can not only provide an improved solution, but can also lead to better ways of working.
Prioritise Feedback
If you can prioritise your feedback, it can help the requester focus on the most relevant items first. You could consider the following priorities:
- Blocker: Needs to be addressed before merge
- Follow Up: Can be addressed in a subsequent PR, but should be addressed
- Minor: Could be resolved in a subsequent PR if time allows.
Big Items first
While your focus ability is still high, start with the big picture items. Are there any blockers? Is there any reason this bit of code cannot or should not be merged?
Are there any missing items?
- Documentation?
- Tests?
- Artifacts?
After that, focus on the smaller items. As you get more senior, you may want to consider focusing less on small or trivial issue. Your time may be better spent encouraging and helping the more junior developers on the team to do reviews and find and report those. If you find most or all of issues, you team may be inclined to leave the reviews to you.
Test the change
It is a good idea to pull the changes yourself and test it. It can help identify any assumptions about dev environments, locally installed packages and bugs that the requester was perhaps too close to see.
Loop in others
If you come across code or changes that could benefit from review by people not currently on the list, it is a good idea to let the requester know and to bring them in. The requester may have a reason for not including them, so it may be worth checking with them first.
Things to Consider
Try to consider all the impact this change could have, including:
- Maintenance
- Support
- Infrastructure
- Security
- Costs
- Customer/User
- Compliance
- Scalability
Other things to consider:
- Biases & Assumptions: Is there anything the requester is too close to see?
- Complexity: Could anything be simplified, or even better designed away?
- Alternative solutions: Assume the author has considered them too, but might be worth a discussion
- Dependencies: The fewer the dependencies, the better. Can some of them be removed?
It may be impossible to consider everything, but it is good to be mindful of the impact the change could have. It is also a good idea to document any potential risks, and possible mitigation.
Post Merge
Just because a PR has been merged does not mean that it no longer benefits from review. Reviewing PRs after they have been merged provides the same benefits. It is a good idea to work out how that process would work since platforms like GitHub are not built to support this workflow as well as the gated merge.
From a lean methodology perspective, it would make sense to automate as many of the checks as possible and automatically merge on pass. All reviews would then be completed post-merge. This process would have the benefit that all features are providing value at the earliest possible point.
For Everyone
It is important to integrate your code continuously. This process reduces waste by:
- Making merges easier (fewer conflicts)
- Potential defects are found sooner, and are easier to resolve
- Validating the direction of the feature as well as the method (i.e. where are we going and how)
- Allow reuse of code earlier
It may help to think of development more like crafting or curating software, collaboratively, together.
Be Gracious
No matter your role in the team or how long you have been a part of it, the cohesion of the team and the wellbeing of its members is crucial to its effectiveness. The quality of what you build is also important, but by and large, it is easier to fix software than it is to fix issues within a team.
Be mindful of actions that may negatively impact your or your teams wellbeing and cohesion. Be aware of your ego and if it is getting in the way of collaboration.
Be kind, courteous and considerate: Be gracious!
