All articles

A Git Workflow That Makes Code Review Worth Doing

Code review only works if the commits are readable and the branch is scoped. Here is the workflow I follow on every project.

Code review gets a bad reputation for being slow. Usually the slowness is not a review problem — it is a commit problem. When a pull request is 47 files changed with a message of "misc fixes", the reviewer has no frame of reference.

One logical change per commit

A commit is a unit of thought, not a unit of time. I do not commit "everything I did today". I commit "added input validation to the registration form" and then separately commit "fixed the flaky timeout in the auth test".

git add -p (patch mode) lets you stage specific hunks instead of all modified files. After a long session, I use it to reconstruct the logical sequence of changes before pushing.

Commit messages that answer "why"

The diff answers what changed. The commit message answers why. A message that repeats the diff is noise.

  • Bad: "update user query"
  • Good: "scope user query to active accounts — inactive users were appearing in search results"

Branch scope

A branch should map to a ticket or a clearly bounded task. The moment a branch grows a second purpose, I create a second branch and cherry-pick.

A PR that does one thing can be approved in 20 minutes. A PR that does four things requires 90 minutes and produces vague review comments.

Before opening a pull request

  1. Rebase on main to resolve conflicts while the context is fresh.
  2. Read through your own diff as if you are the reviewer. Remove debug output, fix obvious style issues.
  3. Write a PR description that states the problem, the approach, and any decisions you want explicit sign-off on.
  4. Mark known compromises with a comment so the reviewer knows you saw it.

Reviewing someone else's code

Distinguish between blocking feedback and suggestions. "This will cause a null dereference in production" is a blocker. "I would have named this variable differently" is a suggestion.

Ask questions rather than issuing directives for anything ambiguous. "Why did you choose this over X?" opens a conversation. "You should use X instead" closes it.