VS Code добавляет «Co-Authored-by Copilot» к каждому коммиту
Расширение Copilot для VS Code незаметно добавляет трейлер Co-Authored-by в ваши коммиты — даже если вы написали каждую строку самостоятельно. Вот как именно это остановить.
Co-authored-by: GitHub Copilot к сообщениям коммитов, когда оно участвует в их генерации — а иногда и в тех случаях, когда не участвует. Это затрагивает записи об авторстве, историю вкладов в open-source проекты и потенциально политику работодателей в отношении интеллектуальной собственности. Нейтрализовать это можно с помощью git-хука, изменения настроек VS Code или глобального правила gitconfig — у каждого подхода есть свои компромиссы.Если вы недавно заглядывали в свой git log и заметили незнакомую строку в конце сообщений коммитов, которые написали полностью самостоятельно, — вам не кажется. GitHub Copilot — точнее, расширение Copilot для VS Code — тихо проставляет своё имя в коммиты как соавтор, независимо от того, изменил ли он хоть одну строку в этом пуше. Это не заговор, а система атрибуции по принципу «отказ по умолчанию», на которую большинство разработчиков никогда осознанно не соглашались. Далее — точное описание того, как работает это внедрение, почему GitHub так сделал, и — что наиболее полезно — какие именно настройки, хуки и конфиги заставят это прекратиться.
Как выглядит трейлер
Прежде чем что-то исправлять, полезно точно понять, с чем вы имеете дело. Внедряемый текст — стандартный трейлер git-коммита: пара «ключ — значение», добавляемая после пустой строки в конце тела сообщения коммита. Он следует тому же формату, что используется git interpret-trailers и такими инструментами, как Gerrit и собственная инфраструктура слияния GitHub:
feat: добавить поток аутентификации пользователей
Реализовать JWT-вход с ротацией refresh-токенов.
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) для его удаления является деструктивной операцией, которая потребует принудительного пуша и нарушит локальную историю коллег. Профилактика значительно проще, чем устранение последствий.В каких коммитах это встречается чаще всего
Внедрение наиболее агрессивно при использовании функции Создать сообщение коммита — значка с блёстками (✨) на боковой панели Source Control. Нажмите его — Copilot составит сообщение, и трейлер соавтора будет добавлен ещё до того, как вы подтвердите. Но разработчики сообщают, что трейлер появляется и в коммитах с сообщением, написанным вручную, — особенно если Copilot Chat был активен в этом сеансе и использовался для генерации кода в проиндексированных файлах.
Механизм внедрения
Расширение GitHub Copilot для VS Code глубоко интегрируется с API Source Control Manager (SCM) VS Code. Когда вы индексируете файлы и открываете поле ввода сообщения коммита, Copilot регистрируется как провайдер поля ввода SCM и может программно заполнять или изменять это текстовое поле — в том числе добавлять трейлеры прежде, чем вы наберёте хоть один символ.
Это не самовольная функция. Это задокументированное поведение, связанное с философией атрибуции AI у GitHub: если модель AI существенно внесла вклад в работу, GitHub считает, что этот вклад должен быть зафиксирован. Проблема в реализации: «существенно внесла вклад» трактуется расширением очень широко, а UX для отказа скрыт на несколько уровней вглубь меню, а не предлагается в виде заметного запроса при первом запуске.
Как SCM API VS Code это делает возможным
VS Code предоставляет vscode.scm.inputBox и связанные API, которые расширения могут использовать. Расширение Copilot применяет их для:
- Наблюдения за тем, какие файлы проиндексированы, и их диффами.
- Определения того, был ли Copilot вызван (или просто активен) во время редактирования этих файлов.
- Генерации сообщения коммита через Copilot API.
- Внедрения сообщения — включая трейлер — в поле ввода коммита перед отправкой.
Внедрение происходит на стороне клиента в VS Code, а не на серверах GitHub, а значит, серверные правила или защиты веток не могут перехватить его до того, как оно попадёт в историю.
Происходит ли это без использования функции генерации?
Да — и именно это больше всего раздражает разработчиков. Пользователи сообщают о появлении трейлера даже когда:
- Они написали сообщение коммита вручную (не через кнопку с блёстками).
- Проиндексированные изменения были написаны вручную на 100%.
- Copilot Chat был открыт, но не использовался для текущей задачи.
Эвристика расширения для определения «Copilot был задействован» размытая. Если Copilot был активен во время сеанса редактирования любого файла в диффе — даже если вы отклоняли каждое предложение — он всё равно может добавить трейлер. В этом и суть претензий: это не атрибуция за реальный вклад AI, это атрибуция по факту близости.
Почему это важно не только с эстетической точки зрения
Посторонний соавтор в git log может показаться косметическим неудобством, но есть реальные последствия, которые стоит понять, прежде чем решать, насколько срочно действовать.
Интеллектуальная собственность и политика работодателей
Многие работодатели — особенно в регулируемых отраслях, таких как финансы, здравоохранение и оборонные контракты — имеют чёткую политику интеллектуальной собственности в отношении кода, созданного AI. Строка Co-authored-by: GitHub Copilot в коммите к проприетарной кодовой базе — это задокументированная запись о том, что инструменты AI участвовали в создании этого кода. Даже если Copilot автодополнил только закрывающую скобку, этот трейлер создаёт след аудита, которым юридическим отделам, возможно, придётся заниматься.
Если ваша компания явно не разрешила использование Copilot для продакшн-кода, этот трейлер создаёт риск, на который вы не подписывались.
Последствия для лицензирования open-source
Правовой статус кода, созданного AI, и его совместимость с копилефт-лицензиями (GPL, AGPL) ещё не урегулированы. Проекты со строгой политикой принятия вкладов могут отклонить или потребовать переписать историю для коммитов, содержащих атрибуцию Copilot, — FSF и другие организации опубликовали свои позиции по этому вопросу. Если вы поддерживаете open-source проект с контрибьюторами, которые ожидают чистой провенанс, трейлеры Copilot в вашей истории усложняют ситуацию.
Статистика контрибьюторов и портфолио для найма
Профили GitHub и графы контрибуций всё чаще используются как неформальные портфолио — рекрутерами, потенциальными коллаборантами, программными комитетами конференций. Наличие бота в качестве соавтора коммитов в ваших публичных репозиториях искажает сигнал атрибуции, который эти графы призваны предоставлять. Мелочь, но это ваша история.
Четыре способа остановить это
Не существует единственного канонического решения, подходящего для каждого рабочего процесса. Правильный подход зависит от того, нужно ли вам глобальное решение, переопределение для конкретного репозитория или что-то, что сохраняет генерацию сообщений коммитов Copilot, но убирает только трейлер.
Вариант 1 — Настройки расширения VS Code
Наиболее прямой путь — отключить это поведение в настройках VS Code. Откройте настройки (Ctrl+, или Cmd+,), затем найдите «copilot commit». Вы ищете параметры расширения GitHub Copilot, связанные с генерацией сообщений коммитов и атрибуцией соавтора.
В settings.json соответствующий путь конфигурации выглядит так:
{
"github.copilot.chat.generateCommitMessage.enabled": false
}
Полное отключение генерации сообщений коммитов останавливает внедрение у источника — Copilot вообще не будет заполнять поле ввода коммита, и возможности добавить трейлер не будет. Если вы всё же хотите использовать AI-генерацию сообщений коммитов, но без строки атрибуции, некоторые версии расширения предоставляют отдельный переключатель именно для трейлера соавтора. Перейдите в Extensions > GitHub Copilot > Settings на боковой панели VS Code, чтобы проверить, что доступно в вашей установленной версии, — точные названия настроек менялись в разных выпусках расширения Copilot.
Вариант 2 — 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 на её использование:
# В .gitconfig или локальном конфиге репозитория
git config core.hooksPath .githooks
Затем зафиксируйте ваш хук в .githooks/prepare-commit-msg с тем же содержимым выше. Каждый разработчик, клонировавший репозиторий и выполнивший git config core.hooksPath .githooks (или при автоматизации в скрипте настройки), получит поведение по удалению трейлера.
-i в sed редактирует файл на месте. На macOS BSD sed требует явного расширения резервной копии: sed -i '' '/^Co-authored-by: GitHub Copilot/Id' "$1". Добавьте условную конструкцию shell, если ваша команда использует и Linux, и macOS.Вариант 3 — Отключить Copilot для рабочего пространства
Если ваша озабоченность связана с конкретным репозиторием (например, клиентским проектом или open-source репозиторием со строгими правилами провенанса), можно полностью отключить Copilot для этого рабочего пространства, не трогая глобальные настройки. В корне репозитория создайте или отредактируйте .vscode/settings.json:
{
"github.copilot.enable": {
"*": false
}
}
Это отключит все функции Copilot — автодополнение, чат и генерацию сообщений коммитов — только в этом рабочем пространстве. При переключении на личный проект Copilot работает как обычно. Недостаток — вы теряете всю помощь Copilot в этом репозитории, а не только внедрение соавтора.
Вариант 4 — Глобальное правило очистки gitconfig
Если трейлер проникает в коммиты из нескольких инструментов и сред (не только VS Code), глобальный хук prepare-commit-msg в шаблоне git домашней директории охватывает всё:
# Установить глобальную директорию шаблонов хуков
git config --global init.templateDir ~/.git-templates
# Создать директорию и хук
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/ с документацией по настройке.
Лучший вариант для чувствительных клиентских репозиториев: copilot.enable: false на уровне рабочего пространства, зафиксированный в .vscode/settings.json.
Очистка коммитов, в которых это уже есть
Если вы уже запушили коммиты с трейлером Copilot в частный репозиторий и хотите очистить историю, операция требует принудительной перезаписи. Делайте это только на ветках, где вы единственный контрибьютор и понимаете последствия изменения SHA коммитов.
# Интерактивный rebase для редактирования последних коммитов
git rebase -i HEAD~10
# Для каждого затронутого коммита отметьте его как 'reword' и удалите строку трейлера
# Или используйте filter-branch для массовой очистки:
git filter-branch --msg-filter \
'sed "/^Co-authored-by: GitHub Copilot/Id"' \
HEAD~20..HEAD
После перезаписи потребуется принудительный пуш:
git push --force-with-lease origin ваша-ветка
--force-with-lease безопаснее --force, потому что откажет в пуше, если кто-то другой запушил в ветку после вашего последнего fetch. Это не защищает публичные общие ветки — координируйтесь с командой перед выполнением этого на чём-либо, кроме личной фиче-ветки.Для репозиториев, уже запущенных в публичный GitHub, где вы не хотите переписывать историю, прагматичный ответ таков: задокументируйте ситуацию в файле CONTRIBUTING вашего проекта, добавьте хук на будущее и смиритесь с тем, что старые коммиты останутся такими, какие они есть. Перезапись истории в активных публичных репозиториях создаёт больше проблем, чем решает.
Краткий чеклист
Пройдите по этому списку в порядке, соответствующем вашей ситуации:
- Убедитесь, что видите трейлер: выполните
git log --format=full -5и проверьте наличиеCo-authored-by: GitHub Copilotв конце тела любого коммита. - Установите хук
prepare-commit-msgв затронутом репозитории — это наименее трудоёмкое и наиболее надёжное исправление. - Проверьте настройки Copilot в VS Code: откройте настройки, найдите «copilot commit» и отключите генерацию сообщений коммитов, если не пользуетесь кнопкой с блёстками.
- Для чувствительных репозиториев: добавьте
.vscode/settings.json, отключающий Copilot для этого рабочего пространства, и зафиксируйте его, чтобы коллеги унаследовали настройку. - Для командных сред: создайте директорию
.githooks/, добавьте скриптprepare-commit-msg, зафиксируйте его и добавьтеgit config core.hooksPath .githooksв инструкции по настройке проекта или Makefile. - Установите глобальный шаблон git, если работаете со многими личными репозиториями и хотите решение «настрой и забудь».
- Проверьте последние коммиты в общих ветках: используйте
git log --grep="Co-authored-by: GitHub Copilot" --onelineдля поиска затронутых коммитов, прежде чем решить, нужна ли очистка истории. - Убедитесь, что исправление работает: проиндексируйте файл, дайте VS Code открыть диалог коммита, проверьте отсутствие трейлера перед подтверждением коммита.
Источники и дополнительное чтение
-
GitHub Docs — Commit Trailer Attribution — Официальная документация GitHub о том, как работают трейлеры соавторов в графе контрибуций GitHub и что означает формат
Co-authored-byдля статистики репозитория и атрибуции в pull request. -
Список изменений расширения GitHub Copilot для VS Code (marketplace.visualstudio.com) — Примечания к выпускам расширения Copilot документируют введение генерации сообщений коммитов и последующие изменения в поведении атрибуции; ищите версии с конца 2023 года.
-
git-scm.com — Документация по githooks — Авторитетный справочник по хуку
prepare-commit-msg, его контексту вызова, аргументам и взаимодействию с процессом коммита в различных git-клиентах. -
Software Freedom Conservancy — Копилефт и код, созданный AI — Опубликованный анализ SFC о том, как результаты работы моделей AI взаимодействуют с лицензионными обязательствами GPL и AGPL, актуально для мейнтейнеров open-source проектов, принимающих решение об обработке атрибуции Copilot в своих проектах.
-
GitHub Community Forum — «Copilot добавляет Co-authored-by без моего ведома» — Продолжающиеся дискуссионные ветки с реальными случаями поведения внедрения, подтверждёнными пользователями обходными решениями и ответами сотрудников GitHub о задуманном дизайне в сравнении с описанными пограничными случаями.