Your first PR should be small enough to read in one sitting.
Audit the diff before you push it, not after review starts.
Three commands tell you if the change is reviewable.
That matters more now than it did two years ago.
Many first PRs today contain lines you did not type yourself.
A reviewer still pays the full cost of reading them.
Below is the pre-push audit I would run on any first PR.
It is a checklist, not a gate — you still decide.
Treat the numbers in the decision table as heuristics, not evidence.
Step 1 — Anchor the diff to the merge base
git diff main shows you changes you did not make.
Your branch point is older than main, so you see other people's work.
Anchor to the merge base instead.
git fetch origin git merge-base HEAD origin/main git diff --stat $(git merge-base HEAD origin/main)..HEAD The --stat output is your first honest look at the PR.
If it lists files you never opened, stop and find out why.
Step 2 — Count lines per file, not in total
A 300-line PR in one new test file is easy to review.
The same 300 lines across nine files is not.
Sort by file and read the top of the list.
git diff --numstat $(git merge-base HEAD origin/main)..HEAD | sort -k1,1nr Columns are added, deleted, path.
Binary files show - instead of a count, so read those separately.
Step 3 — Separate whitespace churn from real edits
Editors and formatters rewrite whitespace without asking.
Whitespace-only hunks hide your real change from the reviewer.
Compare the diff with and without -w.
git diff --shortstat $(git merge-base HEAD origin/main)..HEAD git diff -w --shortstat $(git merge-base HEAD origin/main)..HEAD A large gap between those two lines means reformatting happened.
Either revert it, or land it as a separate commit.
Step 4 — List the paths that should not move
Lockfiles, build output, snapshots, and vendored code are the usual suspects.
One install command can rewrite a lockfile you never meant to touch.
Grep the changed file list before you push.
git diff --name-only $(git merge-base HEAD origin/main)..HEAD \ | grep -E '(lock|\.min\.|dist/|vendor/|\.snap$)' || echo 'none' none is the answer you want.
Anything else needs a one-line justification in the PR description.
Step 5 — Test the tree you are about to commit
Your working tree is not your commit.
Unstaged leftovers can make a broken commit look green.
Stash everything except the index, then run the tests.
git add -p # stage hunks, not whole files git stash push --keep-index --include-untracked your-test-command # whatever CI runs, same args git stash pop # restore the rest Failures here are real failures for that commit.
Watch two edge cases: tests that need your unstaged edits, and fixtures that only exist untracked.
The audit script
The script below combines steps 1–4 into one run.
It is illustrative and was not executed for this article.
Check each command against your own Git version before trusting it.
#!/usr/bin/env bash # diff-audit.sh — illustrative, unverified here. set -euo pipefail BASE="${1:-origin/main}" git fetch --quiet origin MB=$(git merge-base HEAD "$BASE") echo "merge-base: $MB" echo "== per-file line counts ==" git diff --numstat "$MB"..HEAD | sort -k1,1nr echo "== totals ==" git diff --shortstat "$MB"..HEAD git diff -w --shortstat "$MB"..HEAD echo "== suspicious paths ==" git diff --name-only "$MB"..HEAD \ | grep -E '(lock|\.min\.|dist/|vendor/|\.snap$)' || echo "none" echo "== commits ==" git log --oneline "$MB"..HEAD Read the commit list last.
Three commits with one idea each beat one commit with three ideas.
Where a free model fits in the loop
Scope triage is repetitive and low-risk.
That is a reasonable place to spend a free model call.
MonkeyCode is presented as an open-source project with free model access and a free server option.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
The announcement I was given cites a large free token allowance on the order of ten million tokens.
That number is operator-supplied, so verify the current terms on the project's official page before you rely on it.
Here is the prompt shape I would use on a diff.
Illustrative only — I have not run it, and its output is not verified.
You are checking scope, not style. For each changed file, output one line: path | one-sentence intent | in-scope? (yes / no / unclear) Ticket text: <paste ticket> Diff: <paste git diff --numstat and the first 50 lines of git diff> Use the result to ask better questions, not to skip reading.
A model that says in-scope: yes is not a reviewer.
Also check your repository's policy before sending code to any external service.
Where a free server option helps
Sometimes the blocker is not the diff, it is the toolchain.
A cold local setup can eat your whole first hour.
If the project offers a free server option, run the audit and the test command there instead.
Keep the split honest: audit locally, execute remotely, read output locally.
Confirm the remote environment matches the CI image before trusting a green run.
If you cannot confirm that, treat the result as a hint and say so in the PR.
Decision table
| Signal | Action |
|---|---|
| Lockfile changed, ticket is unrelated | Revert that file; do not reinstall |
| One commit touches many unrelated files | Split by hunks with git add -p |
-w diff is much smaller than raw diff | Land formatting separately or revert |
| Generated or vendored files moved | Confirm the build step, or drop them |
| Tests pass only with unstaged edits | Fix the commit, not the stash |
These thresholds are judgment calls, not measurements.
Your repo's size and review culture should override them.
How to verify your own audit
You need a way to know the audit worked.
Pick checks you can actually run.
- Re-run the script after splitting. The per-file counts should drop.
- Run
git show --stat HEADand read the file list out loud. - Ask the reviewer one question: "is any file here unexpected?"
- If CI fails, compare its command with the one you ran in step 5.
A diff audit that never changes your PR is not doing anything.
Expect it to remove at least one file the first few times.
Who should skip this
- Single-line documentation fixes. The audit costs more than the change.
- Repos where the lockfile change is the point, such as dependency bumps.
- Repos that commit generated artifacts on purpose; there,
dist/belongs in the diff. - Teams whose pre-commit hooks already run these checks.
Close
Your first PR is a reading request, not a code delivery.
Make the reading short and the request explicit.
Everything else — trust, review speed, follow-up work — follows from that.
If you run the audit script, tell me which check caught something your eyes missed.
That is the part worth writing down for the next newcomer.

