- Published on
- 5 min read
> Claude Code Auto Commit: How to Automatically Commit Changes as You Go
- Authors

- Name
- Mick MacCallum
- @0x7fs
One of the best things about working with Claude Code is watching it churn through a multi-file refactor or feature implementation while you sip your coffee. The problem is that if something goes wrong halfway through, you might lose a chunk of good work because nothing was committed along the way.
The fix is to set up Claude Code auto commit behavior so changes get saved to git incrementally. There are a few ways to do this, ranging from simple instructions to fully automated hooks.
The CLAUDE.md Approach
The simplest way to get Claude Code to commit as it goes is to just tell it to. Add instructions to your project's CLAUDE.md file:
## When to commit
- Create commits after completing each logical unit of work.
- Do not push to the remote repository unless asked.
- Use conventional commit messages (e.g. "feat:", "fix:", "refactor:").
Claude Code reads this file at the start of every session and follows the instructions throughout. It will use git add and git commit on its own whenever it finishes a meaningful piece of work.
This approach is flexible because Claude decides when a "logical unit" is complete. It won't commit after every single line change, but it also won't wait until the very end. You can be more or less specific depending on your preference. Something like "commit after every file change" will produce more granular history, while "commit after completing each task" keeps things tidier.
The tradeoff is that this relies on Claude's judgment. It usually gets this right, but it's not guaranteed to commit at exactly the moments you'd want. For something more deterministic, hooks are the answer.
Auto-Committing with Hooks
Claude Code has a hooks system that lets you run shell commands automatically at specific points in its lifecycle. You can use this to trigger a git commit every time Claude edits a file.
Add this to your .claude/settings.json (create the file if it doesn't exist):
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "cd \"$CLAUDE_PROJECT_DIR\" && git add -A && git diff-index --quiet HEAD || git commit -m \"wip\" 2>/dev/null || true"
}
]
}
]
}
}
This fires after every Write or Edit tool call. The git diff-index --quiet HEAD check prevents empty commits when nothing actually changed, and the || true at the end ensures that a failed commit doesn't block Claude from continuing its work.
The commit messages here are just "wip" since these are incremental saves. You can always squash or rewrite them later with an interactive rebase. If you want slightly more descriptive messages, you can parse the hook input to extract the file path:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "FILE=$(echo $0 | jq -r '.tool_input.file_path // empty' 2>/dev/null | xargs basename 2>/dev/null); cd \"$CLAUDE_PROJECT_DIR\" && git add -A && git diff-index --quiet HEAD || git commit -m \"Update ${FILE:-files}\" 2>/dev/null || true"
}
]
}
]
}
}
One thing to be aware of: PostToolUse hooks run synchronously by default, meaning Claude waits for the commit to finish before moving on. For small repos this is barely noticeable, but if your git operations are slow you can add "async": true to run the commit in the background:
{
"type": "command",
"command": "cd \"$CLAUDE_PROJECT_DIR\" && git add -A && git diff-index --quiet HEAD || git commit -m \"wip\" 2>/dev/null || true",
"async": true,
"timeout": 30
}
Using a Stop Hook Instead
If committing after every file edit feels too granular, you can commit only when Claude finishes a full response. The Stop hook fires at the end of each turn:
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "cd \"$CLAUDE_PROJECT_DIR\" && git add -A && git diff-index --quiet HEAD || git commit -m \"checkpoint\" 2>/dev/null || true"
}
]
}
]
}
}
This produces fewer commits since Claude often edits multiple files in a single turn. You get a checkpoint after each back-and-forth, which is usually a natural breakpoint anyway.
Don't Forget Permissions
For any of these approaches to work without constant interruptions, you need to make sure Claude Code is allowed to run git commands. Add these to your permission allow list in ~/.claude/settings.json:
{
"permissions": {
"allow": [
"Bash(git add *)",
"Bash(git commit *)",
"Bash(git status*)",
"Bash(git diff*)",
"Bash(git log*)"
]
}
}
Notice that git push is intentionally left out. Auto-committing locally is safe since you can always amend, squash, or reset. Auto-pushing is a different story, and you probably want to keep that behind an approval prompt.
Which Approach Should You Use?
The CLAUDE.md approach is the easiest to set up and produces the cleanest commit history since Claude writes meaningful commit messages and chooses sensible breakpoints. It's what I'd recommend starting with.
If you want something more deterministic, the Stop hook is a good middle ground. You get automatic commits without the noise of one per file edit.
The PostToolUse hook is the most aggressive option. It's useful when you're doing large refactors and want the ability to roll back to any intermediate state, but you'll probably want to squash the commits afterward.
You can also combine approaches. Use CLAUDE.md instructions for meaningful commits and a Stop hook as a safety net. Claude is smart enough not to double-commit when it just committed a moment ago.
// Continue_Learning
Using Vercel's Skills Library to Supercharge AI Agents for React Native
Vercel's Skills library lets you add reusable instruction sets to AI coding agents. Here's how to use it to make agents more effective for React Native development.
Configuring Claude Code Permissions for React Native Development
React Native projects require running lots of shell commands. Here's how to configure Claude Code's permission system so you're not constantly approving the same operations.
How to Use Xcode's MCP Server to Build Xcode into Your AI Workflow
Xcode 26.3 ships with a built-in MCP server that exposes project structure, build actions, and test results to external AI tools. Here's how to set it up.
// Stay Updated
Get notified when I publish new tutorials on Swift, SwiftUI, and iOS development. No spam, unsubscribe anytime.