← Claude Code Hub
✦ Tip #135 Jul 15, 2026

Attribution in Claude Code: strip the 'Co-Authored-By: Claude' line from your commits

Claude Code signs every commit it touches, unless you tell it no twice: once for the model, once for the CLI itself.

Comparison: a default commit with the Co-Authored-By: Claude line versus a clean commit with attribution set in settings.json, and the two layers (CLAUDE.md as guidance, settings.json enforced by the CLI)

TL;DR The setting that actually removes it is attribution in your settings.json ({"commit": "", "pr": ""}): it works at the CLI level, so it doesn't matter what the model decides to write. I also keep a rule in my global CLAUDE.md that forbids it explicitly. That's not redundant paranoia: Claude Code's own default commit template includes that line as an example, and without an instruction overriding it, the model can end up writing it itself, bypassing the setting entirely. Two layers, not one.

Every commit Claude Code makes for you ships with an extra line by default: Co-Authored-By: Claude <noreply@anthropic.com>, sometimes with a 🤖 Generated with Claude Code line above it. It's not a bug, it's the built-in attribution convention. And plenty of people are annoyed by it: there's an open feature request in the Claude Code repo asking for exactly this, a full Hacker News thread, and several developer TILs walking through how to remove it. I've had this banned in my global CLAUDE.md since day one: never, under any circumstance, add "By Claude Code" or similar when touching Git or GitHub. For a while I thought that was enough.

Why CLAUDE.md alone isn't enough

A CLAUDE.md tells the model what to do, it doesn't enforce it. Claude Code ships with a default example template for creating commits that includes that attribution line as part of the message. If your CLAUDE.md doesn't explicitly override it, the model reaches for that template and writes the line as plain text inside the message, not as something the CLI appends separately. The result in your history looks the same, but the mechanism is different, and that matters: rely on the instruction alone, and it only takes a long session where context gets diluted, a poorly worded CLAUDE.md, or a commit made outside the normal flow, for the line to sneak back in.

The setting that actually enforces it: attribution

// ~/.claude/settings.json (every project) or .claude/settings.json (just this one)
{
  "attribution": {
    "commit": "",
    "pr": ""
  }
}

commit controls the line added to commit messages. pr controls the note added to pull request descriptions created by gh pr create. Setting both to empty removes them entirely: not just Co-Authored-By, but the Generated with Claude Code line that usually rides along with it.

Unlike CLAUDE.md, this doesn't depend on the model remembering anything: the CLI itself decides what gets appended to the final message, so it doesn't matter if the model "forgets" the rule halfway through a session.

Coming from an older version? You might have includeCoAuthoredBy: false in your settings.json. It still works, but it's deprecated in favor of attribution, which splits commit and PR instead of one all-or-nothing switch.

// before
{ "includeCoAuthoredBy": false }

// now
{ "attribution": { "commit": "", "pr": "" } }

Before and after

$ git log -1
commit a1b2c3d
Author: Juan <juan@example.com>

    Fix retry logic in payment handler

    🤖 Generated with Claude Code

    Co-Authored-By: Claude <noreply@anthropic.com>

With attribution set to empty:

$ git log -1
commit a1b2c3d
Author: Juan <juan@example.com>

    Fix retry logic in payment handler

The two layers I run

  1. attribution in my global settings.json (~/.claude/settings.json), so no project inherits it by default unless I say so.
  2. A line in my global CLAUDE.md: "never, under any circumstance, add 'By Claude Code' or similar when interacting with Git or GitHub." It's not decoration: it covers the places attribution doesn't reach, like a message Claude hand-writes inside a script, or a note that slips out outside the normal commit flow.

Neither the setting nor the instruction alone is perfect. Together, they are. And while you're deciding what goes where, here's the full map: CLAUDE.md is read as guidance, settings.json is enforced whether Claude follows it or not. This is exactly that principle, applied to a real case.

Reference

Setting Where it lives What it covers Level
attribution.commit settings.json (user, project, or local) Line added to commit messages CLI, deterministic
attribution.pr settings.json (user, project, or local) Note added to PR descriptions via gh pr create CLI, deterministic
includeCoAuthoredBy settings.json (deprecated) All-or-nothing switch, attribution's predecessor CLI, deterministic
A rule in CLAUDE.md CLAUDE.md (any level) Any message the model writes outside the normal flow Instruction, not enforced

Official docs: Claude Code settings

Free guide

51 tips to master Claude Code.

One page per tip. Five chapters. What I actually use daily in production — no theory, no fluff.

  • I. Getting started 10 tips
  • II. Awareness 3 tips
  • III. Mastery 22 tips
  • IV. Autonomy 10 tips
  • V. Comparison 6 tips
Are you a professional Web developer?

You'll receive the guide by email · You join the Gravitas newsletter · Unsubscribe anytime

of 51
#

Wmedia · 51 Tips
Free guide · 51 tips · 5 chapters

51 tips to master Claude Code.

Are you a professional Web developer? · Unsubscribe anytime