A post making the rounds on X this week asked a question a lot of people have: how do you stop Claude Code from signing your commits? By default every commit Claude Code makes ends with a Co-Authored-By trailer naming the model, and every pull request it opens gets a “Generated with Claude Code” line. Some people like the disclosure. Others want a clean history, or work somewhere that has its own rules about it.
The fix is one setting. This guide shows which one, where to put it, what changed between versions, and how to clean up commits you already made. Everything here comes from Anthropic’s settings reference and the Claude Code changelog.
What Claude Code adds by default
There are three pieces, and each has its own key under attribution:
| Piece | Where it shows up | Default text | Key |
|---|---|---|---|
| Commit trailer | End of each commit message | Co-Authored-By: <model name> <noreply@anthropic.com> | attribution.commit |
| PR line | Pull request description | 🤖 Generated with [Claude Code](https://claude.com/claude-code) | attribution.pr |
| Session link | Commits and PRs from cloud and Remote Control sessions | A Claude-Session trailer with the claude.ai link | attribution.sessionUrl |
The name in the trailer is the model that made the commit, such as Claude Sonnet 5. If a subagent made the commit, it names the subagent’s model. When Claude Code can’t confirm the exact version it writes Claude, and when the model isn’t a Claude model at all (for example a third-party model behind a custom ANTHROPIC_BASE_URL), it writes Claude Code.
None of this touches the commit author. Your user.name and user.email from git config stay the author and committer. The trailer only matters because GitHub reads Co-authored-by lines and shows those people as co-authors of the commit.
Turn off all attribution in one line
On Claude Code v2.1.281 or later, add this to ~/.claude/settings.json:
{
"attribution": false
}
That hides the commit trailer, the PR line, and the session link everywhere you use Claude Code on this machine, including the VS Code and JetBrains extensions and the desktop app, which read the same settings files.
There’s a catch the docs call out. Versions before v2.1.281 don’t accept false here, and they skip the whole settings file that contains it, not only this key. If you share a settings file across machines or teammates on older versions, use the object form below instead. Check your version with claude --version.
The form that works on every version
Empty strings hide the text, and sessionUrl: false drops the link:
{
"attribution": {
"commit": "",
"pr": "",
"sessionUrl": false
}
}
You can also set only one of them. To keep the PR line but remove the commit trailer, set "commit": "" and leave pr out. Claude Code uses its default text for whichever key you leave unset.
Change the text instead of removing it
If your team wants disclosure in its own format, attribution.commit takes any text, including trailers. This example from the docs replaces the default with a generic line and trailer:
{
"attribution": {
"commit": "Generated with AI\n\nCo-Authored-By: AI <ai@example.com>"
}
}
The \n\n matters. Git only treats lines as trailers when they sit in the last paragraph of the message, after a blank line.
Which settings file to use
The settings files guide lists where each file applies:
~/.claude/settings.json: you, in every project on this machine. Best for a personal preference like this..claude/settings.jsonin the repo: everyone who clones the project, once you commit it. Use this when the project has a policy, for example an open source repo that asks for no AI trailers, or one that requires them..claude/settings.local.json: you, in this one project only.- Managed settings: set by your organization. If your company sets attribution lines here, your own files and CLAUDE.md rules don’t override them.
A cloud session runs on another machine and doesn’t read your ~/.claude/settings.json. To control attribution there, commit the setting in the project’s .claude/settings.json.
The old includeCoAuthoredBy setting
Older guides tell you to set this:
{
"includeCoAuthoredBy": false
}
It still works in files that predate attribution. It has been deprecated since v2.0.62, though, and Claude Code ignores it as soon as you set attribution.commit or attribution.pr. If you have both in different files and the trailer came back, that’s the likely reason. Pick attribution and delete the old key.
A CLAUDE.md rule also works
You can say it in plain words instead. A line like this in your project or user CLAUDE.md:
- Don't add Co-Authored-By trailers or "Generated with Claude Code" lines to commits or PRs.
Claude Code tells Claude that your own instructions about attribution, from CLAUDE.md or memory, take precedence over the commit and PR lines. Before v2.1.269 the built-in attribution reminder could win over a CLAUDE.md rule; the changelog lists that as fixed. The setting is still the more reliable choice, because it doesn’t depend on the model following an instruction.
Check that it worked
Make a commit with Claude Code, then print the whole message of the latest commit:
git log -1 --format=%B
To scan recent history for any leftover trailers:
git log -20 --format='%h %(trailers:key=Co-Authored-By,valueonly)'
Lines with nothing after the hash are clean. If the trailer is still there, check the JSON in the file you edited. Run /status to see which settings files Claude Code read, and claude doctor to list entries it rejected. The docs page on debugging your configuration has more.
Add a git hook as a safety net
Settings only cover commits Claude Code writes. If you want a guarantee no matter who or what writes the message, a commit-msg hook can strip the line before the commit is saved. Save this as .git/hooks/commit-msg and make it executable with chmod +x:
#!/bin/sh
# Remove Claude co-author trailers from the commit message
sed -i.bak '/^Co-Authored-By: .*<noreply@anthropic.com>$/d' "$1" && rm -f "$1.bak"
The -i.bak form works with both GNU sed and the BSD sed that ships with macOS. The pattern matches the exact Co-Authored-By casing and the noreply@anthropic.com address from the default trailer, so a human co-author line stays. If you already run Claude Code hooks, note that this is a plain git hook, so it runs for every commit in the repo, not only Claude’s.
Remove the trailer from commits you already made
For the last commit, if you haven’t pushed it:
git commit --amend
Your editor opens with the message. Delete the trailer line, save, and close.
For several older commits, start an interactive rebase from before the first one:
git rebase -i HEAD~5
Change pick to reword on each commit you want to fix, then edit each message as git opens it.
Both commands rewrite history and give the commits new hashes. If you already pushed them, the remote needs a force push. Don’t do that on main or any branch other people work from, and on a site where main deploys, rewriting it can trigger a fresh deploy. Claude Code’s auto mode blocks force pushes and amending commits Claude didn’t create in that session by default, so expect to run these yourself.
What we use
For a solo setup, like the small iPhone apps in the ZenoLab app catalog, the simplest path is "attribution": false in ~/.claude/settings.json if every machine runs v2.1.281 or later, or the object form with empty strings if not. For a repo with a stated policy, put the setting in the project’s .claude/settings.json so every clone and cloud session follows it. If you’re just getting started, our Claude Code tutorial covers settings files from the beginning.
Sources
- Git and attribution settings: code.claude.com/docs/en/settings-reference
- Settings files and precedence: code.claude.com/docs/en/settings
- Claude Code changelog (v2.0.62, v2.1.269, v2.1.281): github.com/anthropics/claude-code
- Git trailers: git-scm.com/docs/git-interpret-trailers
- GitHub co-authored commits: docs.github.com