GitCode Review Tips

Code Review Tips for Git Teams

Code review is the highest-leverage practice available to a software team. Studies consistently show that code review catches more defects per hour of effort than any form of testing. But beyond defect detection, review is where knowledge spreads across the team, where architectural decisions are validated, and where junior developers learn from seniors. Done well, code review is not a bottleneck — it is an accelerant.

Why Code Review Matters

Benefit

How it works

Defect detection

A second pair of eyes catches bugs, edge cases, and security issues the author missed

Knowledge sharing

Reviewers learn about features they did not build; authors learn best practices

Consistency

Reviews enforce style, architecture patterns, and conventions across the codebase

Onboarding

New team members learn the codebase faster through reviewing code

Accountability

Knowing your code will be read raises the standard of work

Documentation

PR descriptions and comments create a record of why decisions were made

Reviewing the Diff: Understand Context

The worst review habit is opening a PR and scrolling through the diff without understanding what the change is supposed to do. Before reading a single line of code:

  • Read the PR title and description completely.

  • Click through to the linked issue to understand the original problem.

  • Look at the files changed list — get a mental map of the scope before diving in.

  • Check the PR size: if it is >500 lines, consider asking the author to split it.

  • Understand the testing approach before reading the implementation.

When reading the code, ask: "If I did not know this PR existed, would this code be understandable?" Not just "does this change work" but "will the team be able to maintain this in six months?"

Using git diff to Understand the Full PR

See the full diff between main and a feature branch

Bash
# Three-dot diff: shows what changed on feature-branch since it diverged from main
git diff main...feature/user-search
# This is equivalent to what GitHub shows in the PR diff tab

# Diff a specific file only
git diff main...feature/user-search -- src/api/users.ts

# See which files changed and how many lines
git diff --stat main...feature/user-search
# src/api/users.ts      | 89 +++++++++++++++++++++++++
# src/api/users.test.ts | 134 +++++++++++++++++++++++++++++++++++++++
# 2 files changed, 223 insertions(+)

Compare two released versions (useful for reviewing between releases)

Bash
# All changes between v1.9.4 and v2.0.0
git diff v1.9.4..v2.0.0

# Only files that changed
git diff --name-only v1.9.4..v2.0.0

# Summary stats
git diff --stat v1.9.4..v2.0.0
Reviewing One Commit at a Time

For PRs with many commits, reviewing the full diff can be overwhelming. Instead, walk through the commits chronologically — each one should represent a logical, self-contained step.

Review commits one at a time

Bash
# List commits on the feature branch not yet in main
git log main..feature/user-search --oneline
# def5678 test(api): add tests for user search
# abc1234 feat(api): add user search endpoint

# Review the first commit (the foundation)
git show abc1234
# Shows the full diff for just that commit

# Review the second commit (tests built on the foundation)
git show def5678

# Or use git log -p to see all commits with their diffs in one scroll
git log -p main..feature/user-search
Tip
Well-structured commit history makes review much easier. If each commit tells a story ("add the database query", "add the HTTP handler", "add integration tests"), a reviewer can understand the implementation narrative. This is another reason to write small, focused commits.
GitHub Suggestions Feature

When you want to propose a specific code change, use GitHub's Suggested Changes feature instead of writing a text comment. The author sees your exact proposed code and can apply it with one click.

Writing a GitHub suggestion in a review comment

Text
In the review comment box, use the suggestion code block:

```suggestion
const label = isActive ? 'Active' : 'Inactive'
```

This replaces the highlighted lines with your suggestion.
The author can click "Commit suggestion" to apply it without
leaving GitHub. Your change appears in the commit history
with attribution.
When to Comment, Request Changes, or Approve

Action

When to use

Effect

Comment

Questions, praise, optional suggestions

No approval status change

Request Changes

Blocking issues that MUST be fixed before merge

Blocks merge until re-reviewed

Approve

All blocking concerns resolved, code is ready to merge

Satisfies the approval requirement

Reserve "Request Changes" for real blockers — security issues, correctness bugs, missing tests for critical paths, or significant design problems. Using "Request Changes" for style preferences or optional improvements is a review anti-pattern that creates unnecessary friction.

Review Checklist

Use a mental checklist when reviewing. Not every point applies to every PR, but running through this list takes only a few minutes and catches most issues:

Correctness

  • Does the code do what the PR description says it does?

  • Are edge cases handled? (empty inputs, null values, zero, very large numbers)

  • Are error cases handled? (network failure, database error, invalid input)

  • Are race conditions possible if this code runs concurrently?

  • Is the logic correct for all code paths (if/else branches, loop termination)?

Tests

  • Are new tests provided for new behaviour?

  • Do the tests actually test the right thing, or are they testing implementation details?

  • Do tests cover the error paths, not just the happy path?

  • Would a future refactor break these tests even if behaviour is correct?

Security

  • Is user input validated and sanitised before use?

  • Are SQL queries parameterised (no string interpolation into queries)?

  • Are secrets or credentials accidentally included?

  • Are authorisation checks in place (can any user call this endpoint, or only the right user)?

  • Is sensitive data logged or exposed in error messages?

Performance

  • Is there an N+1 query problem (one database query per loop iteration)?

  • Are indexes being used for the new queries?

  • Is expensive computation happening on every render/request when it could be cached?

  • Are large files or images being loaded unnecessarily?

Readability and Maintainability

  • Are variable and function names clear?

  • Is complex logic commented with the "why", not just the "what"?

  • Are functions short and single-purpose?

  • Is there code that could be reused but is duplicated instead?

  • Does the code follow the existing patterns and conventions of the codebase?

Documentation

  • Is the README updated if user-facing behaviour changed?

  • Are new API endpoints documented?

  • Are JSDoc/docstring comments added for public functions?

  • Is the CHANGELOG updated for user-visible changes?

Pair Programming as an Alternative

Asynchronous code review is not the only option. For high-stakes changes, complex algorithms, or difficult debugging sessions, pair programming can be more effective:

Approach

Best for

Drawback

Async PR review

Most changes, remote teams, parallel work

Latency, context loss

Pair programming

Complex features, onboarding, knowledge transfer

Requires scheduling, more time intensive

Pre-merge pair review

High-risk changes, final check

Can be a bottleneck

Code Review Anti-Patterns to Avoid
Warning
These patterns slow teams down and damage team culture. Recognise them in your own behaviour and gently call them out in others.

Anti-pattern

What it looks like

Better approach

Rubber stamping

LGTM with no actual review

Read the code; write at least one substantive comment

Bikeshedding

Long debate over naming or formatting

Automate formatting; accept reasonable alternatives

Review bombing

Dozens of nit comments on a good PR

Pick the top 2-3 comments; let the rest go

Holding PRs hostage

Blocking merge for weeks on non-critical changes

Time-box reviews; approve with optional follow-up

Scope creep

"While you are in here, also fix X"

Open a new issue for the additional change

Personal attacks

"This is terrible code"

Always address the code, never the person

Drive-by reviewing

Commenting on a PR without context, then disappearing

Either commit to the full review or don't start

Invisible comments

Leaving comments without requesting changes, then blocking on them

Use Request Changes when something is blocking

Note
The goal of code review is a shared understanding of the codebase and the delivery of high-quality software. Every review interaction either builds trust and knowledge, or erodes them. Choose your words accordingly.