Nova Labs is currently on pause. New product purchases are unavailable. The blog remains live as an archive of the experiment.
Back to blog

Claude Code Git workflows: commits, PR descriptions, and code review

April 12, 2026 10 min read

Git workflows are one of those things that teams develop strong opinions about and then rarely write down in a way a new contributor (or an AI) can actually follow. The branch naming convention lives in someone's head. The commit message format is enforced by review comments, not config. The PR template exists but half the fields get deleted before submission.

Claude Code surfaces this problem quickly because it needs explicit rules to produce consistent output. The upside is that fixing it for Claude also fixes it for your team.

Commit conventions in CLAUDE.md

The most impactful section to add to your CLAUDE.md for git workflows is commit conventions. Here is a concrete example using Conventional Commits:

## Git conventions

### Commit messages
- Format: <type>(<scope>): <description>
- Types: feat, fix, docs, refactor, test, chore, perf, ci
- Scope: optional, use the affected module or area (e.g. auth, billing, api)
- Description: imperative mood, no period at end, max 72 characters
- Body: optional, wrap at 72 characters, explain WHY not WHAT
- Footer: use "BREAKING CHANGE:" prefix for breaking changes

### Examples
- feat(auth): add OAuth2 login via GitHub
- fix(billing): correct rounding for fractional line item quantities
- refactor(api): extract pagination logic into shared middleware
- docs: update CONTRIBUTING.md with new branch naming rules

### What NOT to do
- Do not write commit messages like "fix bug" or "update code"
- Do not include "I" or "we" in commit messages
- Do not summarize what files changed; git diff shows that already
- Do not combine unrelated changes in one commit; stage selectively

### Branch naming
- Features: feat/<short-description>
- Bug fixes: fix/<short-description>
- Use hyphens, not underscores
- Keep it under 40 characters

### Before committing
- Run the project's lint and test commands
- Stage only the files relevant to this change
- Review the diff before committing: git diff --staged

The "what NOT to do" section matters as much as the positive examples. Claude learns the pattern from examples but defaults to habits that are common across codebases. "Fix bug" is a common default; telling Claude explicitly that it's not acceptable prevents backsliding.

How Claude Code generates commits in practice

When you ask Claude to commit changes, it reads the staged diff and generates a message following your convention. If nothing is staged, it will typically ask what to include rather than staging everything with git add -A.

A practical workflow for end-of-task commits:

# After Claude completes a feature
You: Stage the relevant files and commit with an appropriate message.
     Review the diff first and don't include any debug code or temporary files.

Claude: [runs git diff --staged, identifies files, stages selectively, writes commit]

The instruction to review the diff first is worth making a habit. Claude will sometimes stage more than intended, especially if it created temporary files during its work. A brief check before committing catches that.

If your team uses signed commits or a specific GPG key configuration, add that to CLAUDE.md as well. Claude won't know to use git commit -S unless you tell it.

PR descriptions that reviewers actually read

Claude Code is good at summarizing what changed and why when it has access to the full branch diff and commit history. The common mistake is asking for a PR description without providing enough context:

# Weak prompt
Write a PR description for my changes.

# Better prompt
Read the diff between main and this branch (git diff main...HEAD),
the commit messages (git log main..HEAD --oneline), and
.github/PULL_REQUEST_TEMPLATE.md.
Write a PR description that fills in every section of the template.
For the test plan, describe what was tested, not what should be tested.

The distinction between "what was tested" and "what should be tested" is important. PR descriptions that say "add unit tests" in the test plan are not useful to reviewers. Claude will write that if you don't constrain it. Asking for what was actually verified produces a more honest and useful document.

You can also ask Claude to call out breaking changes explicitly:

After the description, list any breaking changes separately.
A breaking change is anything that changes a public API surface, modifies
database schema in a non-backward-compatible way, or requires env variable
changes in production.

Code review with Claude Code

Using Claude Code to review code before you submit a PR is more useful than using it after. The workflow:

Review the changes in git diff main...HEAD.
Focus on:
1. Logic errors and edge cases not covered by tests
2. Security issues: SQL injection, unvalidated input, exposed secrets
3. Performance problems: N+1 queries, unnecessary re-renders, missing indexes
4. Consistency with our existing patterns (see CLAUDE.md conventions)

Do not comment on style issues that our linter catches automatically.
For each issue found, explain why it matters and suggest the fix.

The "do not comment on style" instruction is worth including. Without it, Claude will list style issues alongside actual bugs, diluting the signal. If your linter handles it, Claude flagging it wastes review time.

Claude Code also works well for reviewing someone else's PR. Point it at the diff, ask it to evaluate against your team's CLAUDE.md conventions, and it will produce comments calibrated to your project's standards rather than generic advice.

Worktree-based feature development

Git worktrees are underused and pair well with Claude Code. The setup:

# Create a worktree for a feature branch
git worktree add ../myproject-feature-auth feat/oauth-github

# Now you have two working directories:
# ~/myproject (main branch, your interactive work)
# ~/myproject-feature-auth (feat/oauth-github, Claude's work)

Point Claude Code at the worktree directory. It can build the feature there, run tests, and commit progress while your main directory stays on the current branch. You can review the work at any point without interrupting either side.

This pattern is especially useful for long-running tasks. If you're asking Claude to implement a feature that will take twenty minutes, you don't want to sit on a detached HEAD or a half-committed branch in your main directory. The worktree keeps the states cleanly separated.

Cleaning up when done:

# After merging
git worktree remove ../myproject-feature-auth
git branch -d feat/oauth-github

Branch protection and safety rules

Add git safety rules to your CLAUDE.md to prevent the commands that are difficult to recover from:

## Git safety rules
- Never run git push --force or git push --force-with-lease without explicit confirmation
- Never run git reset --hard without explicit confirmation
- Never run git clean -fd without explicit confirmation
- Never commit directly to main or master; always use a feature branch
- Before any destructive operation, explain what it will do and ask to confirm

## Protected branches
- main: no direct commits, requires PR
- release/*: no direct commits, requires PR from main

## Recovery
- If something goes wrong, use git reflog to find the previous HEAD
- Never delete .git directory

The reflog note is practical. Claude Code will sometimes suggest a reflog recovery when you've lost work, but knowing it's there is only useful if you know to look. Putting it in the safety rules section makes it findable.

Generate your git config with ContextKit

If you want to generate a complete git conventions section for your CLAUDE.md, the ContextKit Generator includes git workflow configuration as part of the full config output. If you already have a CLAUDE.md and want to know whether the git section is complete, the Analyzer scores it and identifies missing pieces.

Rebasing and history cleanup

Interactive rebase is one git workflow where Claude Code is less useful for the interactive parts (it can't operate git rebase -i interactively) but more useful for the planning:

# Ask Claude to plan the rebase, then execute manually
You: I have 8 commits on this branch. Run git log --oneline to see them.
     Tell me which ones should be squashed, which should be reworded,
     and whether any are out of logical order. I'll run the rebase myself.

Claude: [reads log, recommends squash plan, explains rationale]

You: [runs git rebase -i and follows the plan]

Claude is good at identifying commits that belong together (multiple "fix typo" commits that should be squashed into their parent) and commits whose messages don't meet your convention. Having it produce the plan and executing it yourself is a clean split of responsibilities.

Automating the pre-commit check

A practical addition to your CLAUDE.md: define what Claude should do before every commit. This functions like a lightweight pre-commit hook but operates at the AI level:

## Pre-commit checklist
Before committing, always:
1. Run the project lint command and fix any errors
2. Run the project type check if applicable
3. Run the fast test suite (unit tests, not integration)
4. Review git diff --staged and remove any debug logs, console.logs, or TODO placeholders
5. Verify the commit message matches the convention

This doesn't replace a real pre-commit hook (which runs regardless of who or what is committing), but it improves the quality of Claude's commits in sessions where the hook isn't configured.

Combined with a solid commit convention and branch safety rules, this section of CLAUDE.md makes Claude Code a disciplined contributor rather than a fast one that leaves cleanup for you.

Want to build your own AI OS?

The AI OS Blueprint gives you the complete system: 53-page playbook, working skills, and a clonable repo. Starting at $47.

30-day money-back guarantee. No subscription.