Code reviews can be immensely helpful in identifying potential bugs and making sure that developers adhere to company coding standards. However, it's important to have clear guidelines about what is and is not up for review. A written coding standard—accessible via a web browser—is a must, in my opinion. And everyone on the team should be given a chance to provide input as to what goes in the standard. When a reviewer flags a defect, he should cite the section of the standard that the code violates, and provide a hyperlink to it.
Having a written standard and requiring that reviewers cite it for each item they mark as a defect has a couple of important effects:
- It keeps reviews from getting too personal. Reviewers are merely checking for compliance with an agreed-upon standard, not 'bashing' the developer whose code is under review.
- Developers can review code much more quickly when they have a 'checklist' of things to look out for.
I once worked for a company that decided to implement a work flow that used Gerrit for code reviews, and required a review before code could be committed to the dev
branch—a decision I was strongly in favor of at the time. And I still am. Unfortunately, we didn't have a written coding standard. A handful of senior team members thought that this would be "overkill", or "too restrictive", and felt that a de facto standard existed within the company culture that "everybody already knows". Predictably, reviews devolved into an endless debate about whitespace and curly brace placement, and heated discussions regularly occurred on topics that had nothing to do, really, with code quality or executing the company's mission.
So that's the best advice I can give: have a written, web-accessible coding standard (like this one), and require that reviewers stick to it scrupulously when flagging defects. Many software developers tend to have OCD tendencies (I suspect that's what makes us good at coding), and if you don't tamp down on this in code reviews, they can become a bully pulpit for those that can't stand this:
if (!initialized_) {
initObject(obj);
}
so they keep trying to sway people to do this instead:
if ( ! initialized_ )
{
initObject( obj );
}
Distinctions like this almost entirely devoid of meaning, and are never a determining factor in the success or failure of a project/company. So either leave brace placement explicitly unspecified in the standard, or just pick something and require everybody to live with it. Better still, use something like uncrustify in a commit hook to enforce a 'standard' syntax. A different company I worked for did that, and I thought it was weird at the time, but I totally get it now. Anything is better than having developers waste money endlessly debating trivialities. We can do that over lunch. (And we're going to, anyway. It's like a sport for us.)
If you have a published standard that 'hits the high spots', I think the dev team itself can handle code reviews. That's how we do it in my current job. (We use Crucible, FWIW, and like it pretty well.) QA isn't involved in the review process at all. A developer who wants to merge his code simply creates a review and invites other developers to join. He has a green light to merge when everyone has finished the review and all defects have been addressed. There's no strict enforcement. You 'should' create a code review before merging your topic branch—and almost everyone does—but circumstances occasionally call for a 'rogue' merge. For our team of 25+ engineers, this has worked out pretty well.