VS Code 为每个提交静默添加"Co-Authored-by Copilot"标记
VS Code 的 Copilot 扩展会悄悄地向你的每次提交注入 Co-Authored-by 标记——即使每一行代码都是你自己写的。以下是彻底阻止它的精确方法。
Co-authored-by: GitHub Copilot 标记追加至提交消息末尾——有时即便它根本没有参与也会如此。这影响到署名记录、开源贡献历史,以及雇主的知识产权政策。你可以通过 git 钩子、VS Code 设置变更或全局 gitconfig 规则来消除这一行为,各方案各有取舍。如果你最近瞥了一眼 git 日志,发现完全由自己编写的提交消息底部出现了一行陌生的文字,你没有看错。GitHub Copilot——更准确地说,是 VS Code 的 Copilot 扩展——一直在悄悄地将自己的名字戳入提交的共同作者栏,无论它是否碰过那次推送中的任何一行代码。这并非阴谋;这是一套默认加入的署名系统,大多数开发者从未真正知情同意过。以下将精确拆解注入机制的工作原理、GitHub 如此设计的缘由,以及——最实用的部分——究竟哪些设置、钩子和配置能让它彻底停止。
标记实际长什么样
在修复任何问题之前,先了解你面对的是什么。被注入的文本是一个标准的 git 提交标记(trailer)——在提交消息正文末尾空行之后追加的键值对。它遵循 git interpret-trailers 以及 Gerrit、GitHub 自身合并基础设施所使用的格式:
feat: add user authentication flow
Implement JWT-based login with refresh token rotation.
Co-authored-by: GitHub Copilot <github-copilot[bot]@users.noreply.github.com>
最后那一行就是 Copilot 注入的内容。邮件地址 github-copilot[bot]@users.noreply.github.com 是一个真实的 GitHub 机器人账号,这意味着 GitHub 的贡献图谱和提交署名引擎会将其视为真正的共同作者——不是注释,不是可以忽略的元数据,而是一旦推送便永久嵌入提交历史的一等 git 对象。
它会出现在哪里
- GitHub 的提交视图:该提交会在你的头像旁边显示"Co-authored by GitHub Copilot"徽章。
git log --format=full:标记出现在完整提交正文中。git shortlog:根据解析方式,Copilot 可能作为贡献者出现在项目统计中。- GitHub 的贡献者图谱:该机器人账号可能在你的仓库中被注册为贡献者。
git rebase -i 或 git filter-branch 重写历史来移除它是一种破坏性操作,会导致强制推送并破坏队友的本地历史。预防比事后补救要容易得多。最容易出现的场景
当你使用 VS Code 的生成提交消息功能——源代码管理侧边栏中的星光图标(✨)——时,注入最为激进。点击它,Copilot 起草一条消息,共同作者标记便在你确认之前就已捆绑其中。但开发者的反馈证实,即便消息是手动编写的,尤其是当 Copilot Chat 在该会话中处于活跃状态且曾为已暂存文件生成过任何代码时,该标记同样会出现。
注入背后的机制
GitHub Copilot 的 VS Code 扩展在底层与 VS Code 的源代码管理器(SCM)API 深度集成。当你暂存文件并打开提交消息输入框时,Copilot 将自己注册为 SCM 输入框提供者,可以在你输入任何字符之前,以编程方式预填或修改该文本框——包括追加标记。
这不是一个流氓功能。这是与 GitHub AI 署名理念挂钩的已记录行为:若 AI 模型对某项工作有实质性贡献,GitHub 认为该贡献应被记录在案。问题在于执行层面:"实质性贡献"被解读得相当宽泛,而退出选项的 UI 深埋在多层菜单之中,而非一个醒目的首次运行提示。
VS Code 的 SCM API 如何使此成为可能
VS Code 暴露了 vscode.scm.inputBox 及相关 API 供扩展接入。Copilot 扩展利用这些 API:
- 观察哪些文件已暂存及其差异内容。
- 判断 Copilot 在编辑这些文件期间是否被调用(或仅处于活跃状态)。
- 通过 Copilot API 生成提交消息。
- 在提交前将消息——包括标记——注入提交输入框。
注入发生在 VS Code 客户端,而非 GitHub 服务器,这意味着服务端规则或分支保护无法在其进入历史记录之前拦截它。
不使用生成功能也会发生吗?
会——而且这正是最让开发者抓狂的地方。用户报告即便在以下情况下也会出现标记:
- 提交消息是手动编写的(未使用星光按钮)。
- 暂存的修改 100% 为手动输入。
- Copilot Chat 处于打开状态但未被用于当前任务。
扩展对"Copilot 参与了"的启发式判断相当宽松。如果 Copilot 在差异中任意文件的编辑会话期间处于活跃状态——即便你拒绝了每一条建议——它仍可能追加标记。这正是投诉的核心:这不是对实际 AI 贡献的署名,而是基于空间接近度的署名。
为何这不只是外观问题
git 日志中多出一个幽灵共同作者,看似只是个无关紧要的烦恼,但在你决定是否紧急处理之前,有些真实的下游后果值得了解。
知识产权与雇主政策
许多雇主——尤其是金融、医疗和国防承包等受监管行业——对 AI 生成代码有明确的知识产权政策。专有代码库的提交中出现 Co-authored-by: GitHub Copilot 一行,就是 AI 工具参与了该代码创建过程的书面记录。即便 Copilot 只是自动补全了一个右括号,该标记也会留下法律团队可能需要处理的审计追踪。
如果你的公司尚未明确批准在生产代码中使用 Copilot,这个标记就是你未曾同意承担的法律风险。
开源许可合规影响
AI 生成代码的法律地位及其与版权左转(copyleft)许可证(GPL、AGPL)的兼容性仍悬而未决。对贡献来源有严格要求的项目可能会拒绝或要求重写包含 Copilot 署名的提交历史——自由软件基金会及其他组织已就此发表立场。如果你在维护一个贡献者期望代码来源清晰的开源项目,Copilot 标记将使情况复杂化。
贡献统计与求职作品集
GitHub 个人主页和贡献图谱越来越多地被作为非正式作品集使用——被招聘人员、潜在合作者和会议程序委员会参考。在你公开仓库的提交中将机器人列为共同作者,会模糊这些图谱本应传达的署名信号。这是小事,但那是你的历史记录。
四种阻止方式
没有单一的万能修复方案适用于所有工作流。正确的选择取决于你是需要全局方案、单仓库覆盖,还是保留 Copilot 提交消息生成功能但只剥离标记。
方案一 — VS Code 扩展设置
最直接的途径是在 VS Code 设置中禁用该行为。打开设置(Ctrl+, 或 Cmd+,),搜索 "copilot commit"。寻找 GitHub Copilot 扩展下与提交消息生成和共同作者署名相关的选项。
在 settings.json 中,相关配置路径如下:
{
"github.copilot.chat.generateCommitMessage.enabled": false
}
完全禁用提交消息生成可从源头阻断注入——Copilot 不再填充提交输入框,也就没有机会追加标记。如果你仍希望使用 AI 辅助的提交消息但不需要署名行,某些版本的扩展会单独提供共同作者标记的开关。在 VS Code 侧边栏的 扩展 > GitHub Copilot > 设置 中检查已安装版本的可用选项,因为确切的设置名称在不同 Copilot 扩展版本间有所变化。
方案二 — Git 钩子(最可靠)
prepare-commit-msg 钩子在提交消息编辑器打开之前自动运行,可以精准移除 Copilot 标记,无论它是如何进入的。此方案独立于 VS Code 运行,在扩展更新后仍然有效,并适用于仓库中你所使用的任何 git 客户端。
在 .git/hooks/prepare-commit-msg 处创建钩子文件:
#!/bin/sh
# Strip GitHub Copilot co-author trailer from commit messages
sed -i '/^Co-authored-by: GitHub Copilot/Id' "$1"
然后赋予其可执行权限:
chmod +x .git/hooks/prepare-commit-msg
如需团队级方案,使用提交至仓库的共享钩子目录并配置 git 使用它:
# In .gitconfig or the repo's local config
git config core.hooksPath .githooks
然后将同样内容的钩子提交至 .githooks/prepare-commit-msg。每位克隆仓库并运行 git config core.hooksPath .githooks(或将其自动化至安装脚本)的开发者都将获得剥离行为。
sed 的 -i 参数会就地编辑文件。在 macOS 上,BSD sed 需要显式指定备份扩展名:sed -i '' '/^Co-authored-by: GitHub Copilot/Id' "$1"。如果你的团队同时使用 Linux 和 macOS,请添加 shell 条件判断。方案三 — 按工作区禁用 Copilot
如果你的顾虑是仓库特定的(例如客户项目或有严格来源要求的开源仓库),你可以仅针对该工作区完全禁用 Copilot,而不影响全局设置。在仓库根目录下,创建或编辑 .vscode/settings.json:
{
"github.copilot.enable": {
"*": false
}
}
这将在该工作区禁用所有 Copilot 功能——补全、对话和提交消息生成。切换至个人项目时,Copilot 正常运行。缺点是你将失去该仓库中的所有 Copilot 辅助,而不仅仅是共同作者注入。
方案四 — 全局 gitconfig 清理规则
如果标记从多种工具和环境(不仅仅是 VS Code)泄漏到提交中,在家目录的 git 模板中设置全局 prepare-commit-msg 钩子可覆盖所有情况:
# Set a global hooks template directory
git config --global init.templateDir ~/.git-templates
# Create the directory and hook
mkdir -p ~/.git-templates/hooks
cat > ~/.git-templates/hooks/prepare-commit-msg << 'EOF'
#!/bin/sh
sed -i '/^Co-authored-by: GitHub Copilot/Id' "$1"
EOF
chmod +x ~/.git-templates/hooks/prepare-commit-msg
此后你初始化或克隆的任何新仓库都将自动继承此钩子。对于现有仓库,在仓库根目录运行 git init 即可——这对现有仓库是安全的,会复制模板钩子而不影响你的历史记录。
方案对比
| 方法 | 范围 | 移除标记 | 保留补全功能 | 可团队共享 | 扩展更新后仍有效 |
|---|---|---|---|---|---|
| VS Code 设置(禁用生成) | 全局或工作区 | 是 | 否 | 通过提交 settings.json | 是 |
prepare-commit-msg 钩子(本地) |
单个仓库 | 是 | 是 | 通过 .githooks/ 模式 |
是 |
工作区禁用(copilot.enable) |
单个仓库 | 是 | 否 | 通过 .vscode/settings.json |
是 |
| 全局 git 模板钩子 | 所有仓库(新建及未来) | 是 | 是 | 否(用户级别) | 是 |
| 完全禁用 Copilot 扩展 | 全局 | 是 | 否 | 不适用 | 不适用 |
希望保留 Copilot 补全功能的个人用户最佳选择:prepare-commit-msg 钩子 + 全局模板。
有统一策略的团队最佳选择:提交 .githooks/ 目录并附带设置文档。
敏感客户仓库最佳选择:在 .vscode/settings.json 中配置工作区级别的 copilot.enable: false 并提交,使队友自动继承该设置。
清理已有标记的提交
如果你已经将包含 Copilot 标记的提交推送到私有仓库并希望清理历史,该操作需要强制重写。仅在你是唯一贡献者且完全了解更改提交 SHA 后果的分支上执行此操作。
# Interactive rebase to edit recent commits
git rebase -i HEAD~10
# For each offending commit, mark it 'reword' then remove the trailer line
# Or use filter-branch for bulk cleaning:
git filter-branch --msg-filter \
'sed "/^Co-authored-by: GitHub Copilot/Id"' \
HEAD~20..HEAD
重写后,你需要强制推送:
git push --force-with-lease origin your-branch
--force-with-lease 比 --force 更安全,因为如果自你上次拉取后有其他人向该分支推送了内容,它会拒绝推送。但它无法保护公开共享分支——在对非个人功能分支执行此操作之前,请与团队协调。对于已推送至公开 GitHub 且不希望重写历史的仓库,务实的做法是:在项目的 CONTRIBUTING 文件中记录该情况,今后添加钩子,并接受旧提交已是既成事实。对活跃公开仓库进行历史重写带来的问题往往多于它解决的问题。
快速检查清单
根据你的实际情况,按顺序执行以下步骤:
- 确认你看到了标记:运行
git log --format=full -5,检查任何提交正文底部是否有Co-authored-by: GitHub Copilot。 - 在受影响的仓库中安装
prepare-commit-msg钩子——这是摩擦最小、可靠性最高的修复方案。 - 检查 VS Code Copilot 设置:打开设置,搜索"copilot commit",如果你不使用星光按钮,请禁用提交消息生成。
- 对于敏感仓库:添加禁用该工作区 Copilot 的
.vscode/settings.json并提交,让队友继承该设置。 - 对于团队环境:创建
.githooks/目录,添加prepare-commit-msg脚本并提交,然后在项目的设置说明或 Makefile 中加入git config core.hooksPath .githooks。 - 设置全局 git 模板,如果你在多个个人仓库中工作并希望一劳永逸地覆盖所有情况。
- 审查共享分支上的近期提交:使用
git log --grep="Co-authored-by: GitHub Copilot" --oneline找出受影响的提交,再决定是否有必要进行历史清理。 - 验证修复有效:暂存一个文件,让 VS Code 打开提交对话框,在确认提交前检查标记是否已消失。
参考资料与延伸阅读
-
GitHub 文档 — 提交标记署名 — GitHub 关于共同作者标记如何在 GitHub 贡献图谱中运作的官方文档,以及
Co-authored-by格式对仓库统计和拉取请求署名的意义。 -
VS Code GitHub Copilot 扩展更新日志(marketplace.visualstudio.com)— Copilot 扩展的发布说明记录了提交消息生成功能的引入时间及后续署名行为的变更;搜索 2023 年底以后的版本。
-
git-scm.com — githooks 文档 —
prepare-commit-msg钩子的权威参考,涵盖其调用上下文、参数,以及它与不同 git 客户端提交流程的交互方式。 -
软件自由保护协会 — Copyleft 与 AI 生成代码 — SFC 发布的关于 AI 模型输出如何与 GPL 和 AGPL 许可义务交互的分析,适合正在决定如何处理项目中 Copilot 署名的开源维护者参考。
-
GitHub 社区论坛 — "Copilot 在未经我许可的情况下添加 Co-authored-by" — 持续更新的开发者讨论帖,记录了注入行为的真实案例、用户验证的解决方案,以及 GitHub 员工关于预期设计与已报告边缘情况的回应。