ES · Leer en español Explore for free

Checklist · Intermediate · 10 min

Before merging Claude Code's code: a review checklist

Eight checks before merging code written by Claude Code: real tests, secrets, dependencies, licenses, scope, independent review and a bash script.

Cover: Before merging Claude Code's code: a review checklist

Tested with Claude Code 2.1.316 · reviewed

See the files on GitHub Free · MIT license

What it's for

Eight checks to run before merging a branch written (fully or partly) by Claude Code: that the tests really run and weren't weakened, that there are no secrets, that new dependencies exist and are justified, that licenses fit, that there are no changes outside the task's scope, whether the AI and CI configuration was touched, an independent review (/code-review, /security-review or a reviewer subagent) and, always, a person who understands the change and approves it. It includes a bash script, review-branch.sh (in the repo's en/ folder), that points out where to look.

The checklist

The script: where to look before merging

review-branch.sh (en/review-branch.sh in the repo) doesn't replace any of the above: in a few seconds it tells you where to look first (files, possible secrets, dependencies, skipped tests and AI configuration). Save it in your repo or on your PATH, make it executable with chmod +x review-branch.sh and run it from the branch you want to merge:

#!/usr/bin/env bash
# Quick review of a branch before merging: ./review-branch.sh [base-branch]
# It doesn't replace human review: it tells you where to look first.
set -euo pipefail
base="${1:-main}"
range="$base...HEAD"
git rev-parse --verify -q "$base" >/dev/null || { echo "Base branch '$base' does not exist" >&2; exit 1; }

echo "== Changed files (are they all related to the task?)"
git diff --stat "$range"

echo; echo "== Possible secrets in added lines"
git diff "$range" | grep -vE '^\+\+\+' | grep -niE '^\+.*((api|secret|private)[_-]?key|token|passw(or)?d|BEGIN [A-Z ]*PRIVATE KEY)' || echo "(nothing in sight)"

echo; echo "== Dependencies touched"
git diff --name-only "$range" | grep -E '(^|/)(package(-lock)?\.json|pnpm-lock\.yaml|yarn\.lock|requirements[^/]*\.txt|pyproject\.toml|uv\.lock|poetry\.lock|go\.(mod|sum)|Cargo\.(toml|lock)|Gemfile(\.lock)?|composer\.(json|lock))$' || echo "(none)"

echo; echo "== Tests deleted, skipped or focused"
git diff --diff-filter=D --name-only "$range" | grep -iE 'test' || true
git diff "$range" | grep -nE '^\+.*(@unittest\.skip|pytest\.mark\.(skip|xfail)|\b(it|describe|test)\.(skip|only)\(|\bx(it|describe)\()' || echo "(none added)"

echo; echo "== AI and CI configuration touched"
git diff --name-only "$range" | grep -E '^(\.claude/|\.mcp\.json|CLAUDE\.md|AGENTS\.md|\.github/)' || echo "(nothing)"

Real output on a branch with four planted problems (Nov 1, 2026). The numbers on the findings are line numbers in the git diff output, not in the file:

$ ./review-branch.sh main
== Changed files (are they all related to the task?)
 CLAUDE.md           | 1 +
 requirements.txt    | 1 +
 src/app/__init__.py | 1 +
 tests/test_app.py   | 1 +
 4 files changed, 4 insertions(+)

== Possible secrets in added lines
21:+API_KEY = "sk-fake-123"

== Dependencies touched
requirements.txt

== Tests deleted, skipped or focused
33:+    @unittest.skip("later")

== AI and CI configuration touched
CLAUDE.md

The independent review inside Claude Code:

/code-review                     # your branch + uncommitted changes, in a separate subagent
/code-review low main...my-branch  # few findings, the most certain ones
/code-review high 1234           # a pull request, more coverage
/security-review                 # diff against origin's default branch

# Against the spec, with the project template's reviewer subagent:
use the revisor subagent to review git diff main...HEAD against SPEC.md: check that every requirement
is implemented and that edge cases have tests; report only correctness failures and skip style

If you also want every PR reviewed automatically on GitHub, add the PR review with GitHub Actions recipe.

Common mistakes

What we tested and what's pending

On this PC (Linux, Claude Code 2.1.316): the script (Spanish original revisar-rama.sh, same logic as review-branch.sh) ran on a branch of a test repo with four planted problems (an API_KEY written in the code, a new requirements.txt, an @unittest.skip and a change to CLAUDE.md) and flagged all four; on a branch with no changes it flags nothing; it detects a deleted test; with a nonexistent base branch it exits with code 1; bash -n confirms the syntax. We didn't test /code-review, /security-review or the reviewer subagent, because they need a logged-in session: their behavior comes from the official docs (code-review-local, commands, best-practices). npm view, pip index versions, npm audit, pip-audit, gitleaks, license-checker and pip-licenses are cited as common tools, without testing them here.

FAQ

Does /code-review replace human review?

No. It finds correctness bugs with a subagent that didn't see the conversation, which makes it useful, but the docs leave the responsibility for reviewing with you. Use it as a first filter and leave final approval to a person, especially for authentication, money, data and deployment.

What's the difference between /code-review and PR review in GitHub Actions?

/code-review runs in your session, locally, and counts against your plan like the rest of the session. The GitHub Actions recipe (claude-code-action) reviews every PR on GitHub automatically. There's also the managed Code Review service for Team and Enterprise plans. You can combine them: locally before opening the PR, automatically on the PR.

Does /code-review read my CLAUDE.md?

Yes, it follows your CLAUDE.md, also in a run with -p. It doesn't read REVIEW.md, which only configures the managed Code Review service on GitHub.

Why didn't the script find a secret that's there?

Because it only looks for typical words in added lines: a key stored in a variable with another name or encoded slips past it. It's a quick warning, not a scanner. For that, add a secret-detection tool to CI.

How do I stop Claude from weakening tests to make them pass?

Tell it in CLAUDE.md ("don't change or skip existing tests without asking"), review the tests/ diff on every PR and ask the reviewer to flag deleted, skipped or loosened tests, as the project template's /preparar-pr skill does.

The whole library