claude-code
claude-code copied to clipboard
[FEATURE REQUEST] Allow disabling Claude attribution in git commit messages
Environment
- Platform (select one):
- [X] Anthropic API
- [ ] AWS Bedrock
- [ ] Google Vertex AI
- [X] Other
- Claude CLI version: 0.2.53
- Operating System: macOS 15.3.2
- Terminal: Warp + zsh
When using the Bash tool for git commits, Claude automatically adds attribution lines: 🤖 Generated with Claude Code Co-Authored-By: Claude [email protected]
This conflicts with our organization's commit message standards, which require single-line commits with no attribution.
Feature request
Please add an option to disable Claude attribution in git commits. This could be implemented as:
- A configuration setting in Claude Code
- A parameter in the Bash tool when used for git commits
- Respecting project-level .git-commit-template files
Impact
This attribution creates extra work as we must manually remove it for every commit. It also poses risks of accidental attribution appearing in our git history, which violates our standards.
Additional context
Our CLAUDE.md (project guidelines) explicitly state: "Do not include attribution to Claude in the commit message or co-author attribution. Ever."
- issue text created by
claude-code:)
@mackermedia You mentioned adding an instruction to your CLAUDE.md. Does that fix the problem and you still want a config option, or does it not fix it?
@mackermedia You mentioned adding an instruction to your CLAUDE.md. Does that fix the problem and you still want a config option, or does it not fix it?
I've added an instruction to my projects, but it usually forgets when the context is pretty full.
@reverie - I had previously added that instruction to my CLAUDE.md, but it didn't seem to respect it. Which is why I filed this issue.
Claude code had suggested I also add:
- .git-commit-template with content:
single-line-commits-only: true
- CONTRIBUTING.md content stating:
# Contributing to REPO_NAME_HERE
## Commit Message Guidelines
We maintain strict commit message guidelines to ensure consistency in our git history:
1. **Single-line commits only** - Keep commit messages concise and to the point
2. **NO attribution to Claude or any AI tool** - Never include "Generated by Claude" or any co-author information
3. **Follow the style in CLAUDE.md** - Use the prescribed format with optional emojis for change types
Examples of good commit messages:
🐛 Fix order processing calculation for multi-origin shipments ✨ Add customer referral tracking feature 🔄 Update dealer dashboard with sales metrics
We've added a `.git-commit-template` file to help enforce these requirements.
## For AI Assistant Users (Claude, GitHub Copilot, ChatGPT, etc.)
If you're using AI tools to help with development:
1. Always review generated commit messages to remove any attribution
2. Ensure the message follows our commit style guide in CLAUDE.md
3. Remove any co-author tags automatically added by tools
Refer to [CLAUDE.md](CLAUDE.md) for complete style guidelines.
- README.md - content stating:
## IMPORTANT: Commit Message Guidelines
**CRITICAL:** Commit messages MUST be single-line only with NO attribution to Claude or any AI assistant. See [CLAUDE.md](CLAUDE.md) for complete commit style guidelines.
We've added a `.git-commit-template` file to enforce this requirement.
Please fix this. CLAUDE.md is not being respected
Very impressed with Claude Code in general.
Not very impressed that this attribution apparently has no way to be turned off, and furthermore that instructing via CLAUDE.md / other rules has no effect.
What purpose does this serve for Anthropic? Is marketing via my git commits really worth not respecting me as a dev?
Would using Github MCP to manage git workflow effectively remove the attribution, or would Claude just add the attribution there? Guess I'll try that out...
Here’s how is how I set up a global git hook to remove the attribution:
- Create a Global Hooks Directory:
First, create a dedicated directory in your home folder to store your global Git hook scripts. If you already have one, you can skip this step.
mkdir -p ~/.git-hooks
- Configure Git to Use This Directory for Global Hooks:
Tell Git to use this newly created directory as the source for global hooks for all your repositories:
git config --global core.hooksPath ~/.git-hooks
- Create the commit-msg Hook Script:
Create a new file named commit-msg (no extension) inside your ~/.git-hooks directory:
touch ~/.git-hooks/commit-msg
Open this ~/.git-hooks/commit-msg file with your preferred text editor and paste the following script into it. This script will remove the specified lines and clean up blank lines.
#!/bin/sh
COMMIT_MSG_FILE=$1
# Temporary file for processing
TMP_PROCESSED_MSG_FILE="${COMMIT_MSG_FILE}.processed.$$"
# --- Step 1: Define substrings to identify lines for removal ---
# Any line containing these strings will be removed.
# Ensure this script file is saved with UTF-8 encoding for the emoji.
SUBSTRING1="🤖 Generated with"
SUBSTRING2="Co-Authored-By"
# --- Step 2: Remove lines containing the substrings ---
# Use grep -vF to remove lines containing the fixed substrings.
# -v: Invert match (select non-matching lines).
# -F: Treat PATTERN as a fixed string, not a regular expression.
# The output of the first grep is piped to the second grep.
grep -vF "$SUBSTRING1" "$COMMIT_MSG_FILE" | grep -vF "$SUBSTRING2" > "$TMP_PROCESSED_MSG_FILE"
# --- Step 3: Clean up blank lines from the processed message ---
# This awk script will:
# - Skip all leading blank lines.
# - Print a single blank line for any sequence of one or more blank lines
# found *after* at least one non-blank line.
# - Print non-blank lines.
# - Avoid trailing blank lines (implicitly, as a pending blank line at EOF
# won't be printed).
awk '
BEGIN {
content_has_started = 0 # Flag to track if we have seen the first non-blank line
pending_blank_line = 0 # Flag to indicate a blank line separator should be printed
}
NF { # If the line has fields (it is not blank)
if (!content_has_started) {
content_has_started = 1 # Mark that content has started
} else if (pending_blank_line) {
print "" # Print the pending blank line separator before this non-blank line
}
print $0 # Print the current non-blank line
pending_blank_line = 0 # Reset pending blank line flag
next
}
!NF { # If the line is blank (NF == 0)
if (content_has_started) {
pending_blank_line = 1 # Mark that we have encountered a blank line after content has started
}
}
' "$TMP_PROCESSED_MSG_FILE" > "$COMMIT_MSG_FILE"
# Clean up the temporary file
rm -f "$TMP_PROCESSED_MSG_FILE"
# Exit with 0 to indicate success
exit 0
(Note for script users: Ensure this script file is saved with UTF-8 encoding for the 🤖 emoji to be handled correctly.)
- Make the Hook Script Executable:
Finally, make the commit-msg script (and any other scripts in that directory) executable:
chmod +x ~/.git-hooks/commit-msg
# If you have other hooks, you can use:
chmod +x ~/.git-hooks/*
How it Works:
-
The core.hooksPath configuration tells Git to look in ~/.git-hooks for hooks if a local .git/hooks directory doesn't contain a specific hook.
-
The commit-msg script will now run automatically for every commit you make in any local repository, cleaning the message before it's finalized.
-
If a repository has its own local commit-msg hook in its .git/hooks/ directory, that local hook will be used instead of this global one for that specific repository.
This hardcoded attribution raises concerns beyond just workflow preferences. Once these attributions hit git commits, especially on GitHub, they create a permanent data trail of Claude usage patterns.
I'd like transparency on:
-
Business rationale: Why is this hardcoded when users explicitly request otherwise in their project files?
-
Data collection: Are these commit attributions used to track Claude Code usage across repositories?
-
Platform partnerships: Is there any arrangement with GitHub/Microsoft regarding analysis of Claude attribution data?
-
Privacy implications: For private repositories, what assurances exist about how this attribution data is used?
The fact that this ignores explicit user instructions (CLAUDE.md, .git-commit-template, etc.) suggests this serves purposes beyond simple transparency.
Request: Please provide both a configuration option to disable attribution AND clear documentation about why this was implemented as mandatory, what data (if any) is collected via these attributions, and how user privacy is protected.
Found this in .claude/local/node_modules/@anthropic-ai/claude-code/cli.js: Modifying this should fix the issue?
# Committing changes with git
When the user asks you to create a new git commit, follow these steps carefully:
1. ${D} run the following commands in parallel:
- Run a git status command to see all untracked files.
- Run a git diff command to see both staged and unstaged changes that will be committed.
- Run a git log command to see recent commit messages, so that you can follow this repository's commit message style.
2. Analyze all staged changes (both previously staged and newly added) and draft a commit message. Wrap your analysis process in <commit_analysis> tags:
<commit_analysis>
- List the files that have been changed or added
- Summarize the nature of the changes (eg. new feature, enhancement to an existing feature, bug fix, refactoring, test, docs, etc.)
- Brainstorm the purpose or motivation behind these changes
- Assess the impact of these changes on the overall project
- Check for any sensitive information that shouldn't be committed
- Draft a concise (1-2 sentences) commit message that focuses on the "why" rather than the "what"
- Ensure your language is clear, concise, and to the point
- Ensure the message accurately reflects the changes and their purpose (i.e. "add" means a wholly new feature, "update" means an enhancement to an existing feature, "fix" means a bug fix, etc.)
- Ensure the message is not generic (avoid words like "Update" or "Fix" without context)
- Review the draft message to ensure it accurately reflects the changes and their purpose
</commit_analysis>
3. ${D} run the following commands in parallel:
- Add relevant untracked files to the staging area.
- Create the commit with a message ending with:
\uD83E\uDD16 Generated with [${T2}](${S01})
Co-Authored-By: Claude <[email protected]>
- Run git status to make sure the commit succeeded.
p.s Wouldn't it be great if all those prompts were placed inside the users .claude folder for easy modification? That way one could modify it to ones liking e.g have to follow the Conventional Commits specification for all commit messages
My experience with this is that commit instructions in CLAUDE.md will often get ignored and i often have to say something like "commit (and remember to follow instructions in your memory)" -- it would be nice if it could be told to prefer CLAUDE.md commit instructions over its default instructions...
Would be really nice to have a configuration to turn this off as mentioned. Quite annoying and always have to cancel commits and tell it to remove the co-author.
Actually it has the option in documentation, but does not work.
https://docs.anthropic.com/en/docs/claude-code/settings#available-settings
| Key | Description | Example |
|---|---|---|
| apiKeyHelper | Custom script to generate an Anthropic API key | /bin/generate_temp_api_key.sh |
| cleanupPeriodDays | How long to locally retain chat transcripts (default: 30 days) | 20 |
| env | Environment variables that will be applied to every session | {"FOO": "bar"} |
| includeCoAuthoredBy | Whether to include the co-authored-by Claude byline in git commits and pull requests (default: true) | false |
~ on 🅰 (us-east-1)
at 18:28:22 λ claude config set -g includeCoAuthoredBy false
Error: Cannot set 'includeCoAuthoredBy'. Only these keys can be modified: apiKeyHelper, autoUpdaterStatus, theme, verbose, preferredNotifChannel, shiftEnterKeyBindingInstalled, editorMode, hasUsedBackslashReturn, supervisorMode, autoCompactEnabled, diffTool, env, tipsHistory, parallelAgents, todoFeatureEnabled, messageIdleNotifThresholdMs
This is shipped! We're working on making settings configurable via config set. To unblock you for now, edit your settings.json to set includeCoAuthoredBy directly.
given that this user https://github.com/Panchajanya1999 has attributed themselves to that email, you should probably change the default (and reclaim this email address on github)
Will this setting prevent the 🤖 Generated with [Claude Code](https://claude.ai/code) message added to Pull Requests as well?
Thank you!
@bcherny claude still adds the claude attribution w/robot emoji to git commit messages, even with this added to .claude/settings.json
"includeCoAuthoredBy": false,
edit: I think the problem was because I had a comment in the .json file, and maybe claude silently skips the file in that case. I'll re-comment if that is not the case.
This is still happening by the way, despite ""includeCoAuthoredBy": false" AND explicit instructions in CLAUDE.md.
It just forgets after a while, and I sometimes don't notice, and then I have to rewrite my git history.
Very annoying issue.
@mannewalis
i found that if your .claude/settings.json is not 100% syntactically correct JSON (no extra commas, comments, etc) it will silently be ignored, and so your includeCoAuthoredBy option is not respected. with a valid settings.json i have not had this issue anymore.
JSON is valid, but I am using settings.local.json in my project dir. I will try the global one.
@mannewalis it has to be in .claude/settings.json (not .local) relative to the root folder you run claude from.
mine has contents:
{
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": []
}
]
},
"includeCoAuthoredBy": false,
"env": {
"DISABLE_TELEMETRY": "1"
}
}
ok thank you @jasonswearingen I have made the change, and will report back if it adds the attribution again.
FYI: Here's a complete summary of commands to fully clean up commits with Co-Authored-By attributions:
Complete Cleanup Commands
1. Create backup branch (safety first)
git branch backup-before-removing-attributions
2. Remove attributions from commit messages
FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch --msg-filter 'sed -e "/^Co-Authored-By:/d" -e "/🤖 Generated with \[Claude Code\]/d" | sed -e :a -e
"/^\s*$/{\$d;N;ba" -e "}"' -- --all
3. Clean up filter-branch backup refs
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
4. Delete backup branch (optional - only after verifying success)
git branch -D backup-before-removing-attributions
5. Expire reflog immediately (optional - for complete removal)
git reflog expire --expire=now --all
git reflog expire --expire-unreachable=now --all
6. Aggressive garbage collection (optional - removes old objects)
git gc --prune=now --aggressive
7. Force push to remote (updates remote history)
git push --force-with-lease origin main
Notes:
- Steps 1-3 are essential
- Steps 4-6 are optional for complete local cleanup
- Step 7 updates the remote repository
- The remote will eventually garbage collect old commits on its own
--force-with-leaseis safer than--forceas it prevents overwriting others' work
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.