Pattern
quality
review

Diff Hygiene

Keep AI-generated changes reviewable with small, focused diffs.

Why Diff Hygiene Matters

Large, messy diffs are:

  • Hard to review
  • Risky to merge
  • Difficult to revert
  • Impossible to bisect

AI can generate huge changes quickly. Your job is keeping them manageable.

The Rules

Rule 1: One Concern Per Commit

Each commit should do ONE thing:

  • Add a feature
  • Fix a bug
  • Refactor code
  • Update dependencies

Never mix concerns in a single commit.

Rule 2: Size Limits

Diff SizeAction
< 100 linesEasy to review
100-300 linesAcceptable for features
300-500 linesSplit if possible
> 500 linesMust split

Rule 3: No Drive-By Fixes

If AI suggests fixing "other issues" while working on your task:

  1. Note them separately
  2. Complete original task first
  3. Fix them in separate commits

Structuring AI Work

Prompt for Small Changes

Constrained Change Request

engineer

Limit scope of AI changes

Make ONLY the following change:
[specific change]

DO NOT:
- Refactor surrounding code
- Fix unrelated issues
- Add extra features
- Change formatting of unchanged lines

Multi-Step Process

For larger features:

Step 1: Types and interfaces

First, let's add the type definitions only.
Don't implement anything yet.

Step 2: Core logic

Now implement the core function.
Use the types we just created.

Step 3: Integration

Now connect this to the existing code.
Minimal changes to existing files.

Step 4: Tests

Now add tests for what we built.
Separate commit for tests.

Reviewing AI Diffs

Before Committing

Run through this checklist:

  • Does the diff match what I asked for?
  • Are there unexpected file changes?
  • Any formatting-only changes?
  • Any unrelated "improvements"?

Cleaning Up Diffs

If AI added unwanted changes:

bash
# Interactively stage only what you want
git add -p

# Or reset and start fresh
git checkout -- path/to/file

Commit Message Discipline

Format

<type>(<scope>): <short description>

<longer description if needed>

AI-assisted: yes

Types

  • feat: New feature
  • fix: Bug fix
  • refactor: Code restructuring
  • test: Test changes
  • docs: Documentation
  • chore: Maintenance

Examples

feat(auth): add password reset flow

- Add reset email endpoint
- Add token validation
- Add password update endpoint

AI-assisted: yes

Pull Request Patterns

Structure

markdown
## Summary
[One paragraph explaining the change]

## Changes
- [Bullet list of what changed]

## Testing
- [How to verify]

## Screenshots
[If UI changes]

Breaking Up Large PRs

If the PR is too big:

  1. Create a feature branch
  2. Break into smaller PRs against feature branch
  3. Merge feature branch when complete

Anti-Patterns

The Kitchen Sink

diff
+ // Added authentication
+ function authenticate() { ... }
+
+ // Fixed typo while I was here
- const mesage = "hello"
+ const message = "hello"
+
+ // Improved this function
- function old() { return 1 }
+ function improved() { return calculate() }

Problem: Three unrelated changes in one commit.

The Reformat

diff
- function foo(){return bar}
+ function foo() {
+   return bar
+ }

Problem: Formatting changes obscure real changes.

The Dependency Drift

diff
+ // Added new feature
+ import { newThing } from 'new-package'

Problem: New dependency snuck in with feature.

Tools

Git Hooks

Pre-commit hook to warn about large diffs:

bash
#!/bin/bash
LINES=$(git diff --cached --stat | tail -1 | grep -o '[0-9]* insertion' | grep -o '[0-9]*')
if [ "$LINES" -gt 300 ]; then
  echo "Warning: Large diff ($LINES lines). Consider splitting."
fi

Diff Review

Always review before committing:

bash
# Review what's staged
git diff --cached

# Review with context
git diff --cached -U10

Verification

Your diff hygiene is good if:

  • Commits have single purposes
  • PR diffs are under 400 lines
  • No drive-by fixes included
  • Formatting and logic changes are separate