SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor · Обновлено 2026-09-06

Что Claude Code добавляет в сообщения коммитов

Claude Code автоматически вставляет Co-authored-by и ссылки на сессии в git-коммиты. Узнайте, как проверить эти данные до отправки в репозиторий и избежать утечки ссылок.

Что Claude Code добавляет в коммит

Claude Code добавляет трейлер Co-authored-by: в конец создаваемых им сообщений коммитов, а также строку атрибуции в описания открываемых им pull request. Сессии, запущенные в облаке или через Remote Control, также содержат ссылку на сессию на сайте claude.ai. Все эти данные представляют собой обычный текст, который сохраняется в истории git. После отправки (push) в публичный репозиторий эти данные становятся общедоступными и остаются там до тех пор, пока кто-либо не перепишет историю.

Точная формулировка меняется от релиза к релизу, поэтому не стоит полагаться на текст трейлера, приведенный в каком-либо руководстве, включая это. Вместо этого проверяйте свои собственные коммиты. Приведенные ниже команды git являются надежной частью этой темы: механизм обработки трейлеров в git работает одинаково на протяжении многих лет и продолжит работать так же после того, как в следующем релизе изменится текст.

Что такое git trailer на самом деле

Trailer — это строка формата Token: value в последнем блоке сообщения коммита. В Git нет фиксированного списка токенов. Signed-off-by:, Reviewed-by:, Fixes: и Co-authored-by: — это соглашения, построенные на одном механизме. Платформы для хостинга репозиториев, такие как GitHub или GitLab, считывают их, чтобы определить, какую информацию отображать на странице коммита.

Git строго регламентирует расположение этого блока. В документации к git interpret-trailers указано, что перед группой должна быть одна или несколько пустых строк. Блок должен находиться в конце сообщения или непосредственно перед строкой, начинающейся с ---. Кроме того, он должен либо состоять только из trailer-строк, либо «содержать как минимум один trailer, созданный Git или настроенный пользователем, и состоять из таких строк не менее чем на 25%».

Это последнее правило имеет решающее значение. Обычный URL или произвольный текст в последнем блоке не является trailer-строкой, и наличие достаточного количества таких строк препятствует распознаванию всего блока как набора trailer-записей. Именно поэтому коммит может визуально содержать строку Co-authored-by:, но все инструменты, корректно работающие с trailer-записями, не увидят её.

Как прочитать трейлеры, которые уже есть в истории?

Начните с исходного сообщения последнего коммита.

git log -1 --format=%B

%B выводит тему и тело сообщения в исходном виде, без переносов строк и переформатирования. Этот вывод является эталонным. Всё, что вы видите в веб-интерфейсе репозитория — это лишь его визуализация.

Теперь узнайте, какие из этих строк git распознает как трейлеры.

git log -1 --format=%B | git interpret-trailers --parse

--parse — это сокращение для --only-trailers --only-input --unfold, поэтому на выходе будет только блок трейлеров. Корректный результат — по одной строке на каждый трейлер. Если вывод пуст, хотя вы видите строку Co-authored-by:, значит, блок не соответствует правилам размещения, описанным выше.

Чтобы просканировать всю историю, запросите трейлер по ключу.

git log --format='%h %(trailers:key=Co-authored-by,valueonly)'

Старые версии git не поддерживают опцию key= в команде %(trailers). Поиск по тексту сообщения работает везде.

git log -i --grep='^Co-authored-by:' --format='%h %an %s'

--grep выполняет поиск по сообщению коммита, а -i делает поиск регистронезависимым. Это важно, так как написание этого трейлера с заглавной буквы различается в разных инструментах. Перед отправкой (push) сузьте область поиска до тех коммитов, которые вы еще не отправили.

git log origin/main..HEAD --format=%B

Эти коммиты всё еще находятся локально, а значит, их можно легко изменить.

Что делает Co-authored-by: с атрибуцией на GitHub?

GitHub считывает этот заголовок и отображает второго автора на странице коммита. Он связывает этого автора с профилем только в том случае, если адрес электронной почты принадлежит какой-либо учетной записи. Согласно документации GitHub, коммиты отображаются на графике вклада, если они «сделаны с использованием адреса электронной почты, привязанного к вашей учетной записи на GitHub», поэтому адрес, который никому не принадлежит, не может быть привязан к профилю. Для работы в паре это и является основной целью: адрес вашего коллеги привязан к его учетной записи, и коммит засчитывается обоим. Если адрес не принадлежит ни одной учетной записи, заголовок меняет только отображение на странице коммита, не затрагивая список контрибьюторов репозитория.

Сам Git полностью игнорирует этот заголовок. git shortlog -sn и git log --author считывают заголовок автора, который содержит ваше имя и адрес электронной почты, поэтому локальная статистика никогда не покажет соавтора. Атрибуция здесь — это функция платформы, надстроенная над соглашением о простом тексте, что и составляет различие между самим git и платформой, на которой вы размещаете репозиторий.

Ссылка на сессию — это другая проблема

Трейлер указывает соавтора. URL сессии — это указатель на транскрипт. В настройках Claude Code упоминается документ attribution.sessionUrl как ключ, который исключает «ссылку на сессию claude.ai из коммитов в облаке и Remote Control». Это также объясняет происхождение ссылки: сессии в веб-интерфейсе и сессии, управляемые через Remote Control.

Ссылка не является учетными данными. Доступ к сессии определяется правами учетной записи, а не секретностью URL. Причина, по которой её стоит исключать из публичного репозитория, проще. Это постоянный публичный текст, содержащий внутренний идентификатор сессии, который ведет на рабочий транскрипт, изначально не предназначенный для сторонних читателей. В приватном репозитории ситуация обратная: рецензент может перейти по ссылке и изучить процесс внесения изменений. Информация о том, где хранятся эти транскрипты и как долго они существуют, приведена в как Claude Code хранит сессии и возобновляет их.

Настройки, управляющие атрибуцией коммитов в Claude Code

Эти ключи, проверенные по справочнику настроек Claude Code на 1 сентября 2026 года, описаны в разделе "Git and attribution":

  • attribution: "Настройка атрибуции, которую Claude Code добавляет к коммитам и pull request"
  • attribution.commit: "Изменение или скрытие трейлера, который Claude Code добавляет к коммитам"
  • attribution.pr: "Изменение или скрытие строки атрибуции в описаниях pull request"
  • attribution.sessionUrl: "Исключение ссылки на сессию claude.ai из коммитов в облаке и при использовании Remote Control"
  • includeGitInstructions: "Удаление встроенных инструкций для коммитов и PR из системного промпта"
  • includeCoAuthoredBy: помечен как устаревший, с примечанием "используйте attribution для скрытия или изменения атрибуции коммитов и PR"

Берите значение, которое принимает каждый ключ, из соответствующей записи в справочнике настроек, а не из руководства. Имена ключей стабильны. Допустимые значения и значения по умолчанию могут меняться, и файл настроек с правильно написанным ключом, но неверным значением, будет молча игнорироваться.

Место, где вы записываете настройку, определяет, на кого она распространяется. ~/.claude/settings.json применяется к каждому проекту, который вы открываете. Файл .claude/settings.json, закоммиченный в корне репозитория, будет действовать для всех, кто его клонирует. Файл .claude/settings.local.json принадлежит только вам в рамках одного проекта, и Claude Code добавляет его в ваш глобальный git exclude при первом создании файла, поэтому он не попадает в ваши коммиты. Приоритет настроек следующий: управляемые настройки, затем командная строка, затем локальные настройки проекта, затем общие настройки проекта и, наконец, пользовательские. Таким образом, локальный файл вашего коллеги имеет приоритет над файлом, который закоммитили вы, поэтому рассматривайте закоммиченную настройку как значение по умолчанию, а не как гарантию.

Затем выполните проверку, так как ваша уверенность в настройке не является доказательством. Позвольте Claude Code сделать следующий коммит обычным способом, а затем проверьте результат.

git log -1 --format=%B
git log -1 --format=%B | git interpret-trailers --parse

Если трейлер всё ещё выводится, значит, изменение не было применено к сессии. Проверьте, какой именно файл вы редактировали, и сверьтесь с порядком приоритетов выше, прежде чем делать вывод о неисправности ключа.

Элементы управления, не зависящие от настроек

Настройка конфигурирует один конкретный инструмент. Правило репозитория должно работать даже в том случае, если участник использует другой инструмент или вообще не использует агентов. Git предоставляет место для размещения такого правила: хук commit-msg запускается с путем к файлу сообщения в качестве первого аргумента; он может изменить этот файл или полностью отклонить коммит.

#!/bin/sh
# .githooks/commit-msg
grep -qi '^co-authored-by: claude' "$1" || exit 0
grep -vi '^co-authored-by: claude' "$1" > "$1.new" && mv "$1.new" "$1"
chmod +x .githooks/commit-msg
git config core.hooksPath .githooks

Первый grep завершается досрочно, если нет работы, поэтому обычный коммит практически не требует затрат ресурсов. Второй записывает сообщение обратно без соответствующей строки. Сопоставляйте один точный токен, а не все трейлеры, так как фильтр, написанный как «удалить последний блок», также удалит строку Signed-off-by:, которая требуется проекту.

.git/hooks не является частью репозитория, поэтому хук, помещенный туда, никогда не попадет к другим участникам. core.hooksPath указывает Git на директорию, которую можно закоммитить, и каждый человек все равно должен самостоятельно выполнить эту одну строку git config. Git не установит ее автоматически, и это сделано намеренно: репозиторий, который мог бы устанавливать собственные исполняемые файлы при клонировании, стал бы способом запуска кода на вашей машине.

Чтобы отклонить коммит вместо его перезаписи, выведите сообщение в стандартный поток ошибок и выполните exit 1 из хука. Отказ — это честный выбор для общего репозитория, так как скрытое редактирование сообщения коммита другого человека маскирует правило, вместо того чтобы обучать пользователя. Это другой уровень по сравнению с собственными хуками агента, которые срабатывают при вызове инструмента еще до того, как в процесс вовлекается Git, и в том, как хук Claude Code сопоставляет инструмент и блокирует его рассматривается именно эта сторона.

Ни один из этих методов не помогает при получении pull request из форка, так как хук находится на машине, которую вы не контролируете. Проверка в CI (непрерывной интеграции) — это единственный уровень, который видит каждый коммит перед его слиянием.

if git log --format=%B "origin/${BASE_BRANCH:-main}..HEAD" | grep -qi '^co-authored-by: claude'; then
  echo "Attribution trailer found. Rewrite the branch before merging." >&2
  exit 1
fi

Запишите правило, а также обеспечьте его соблюдение. Файл AGENTS.md, расположенный рядом с понятным человеку CONTRIBUTING.md, сообщает агенту и человеку одно и то же, а проверка в CI делает это правило обязательным.

Удаление трейлера перед отправкой (push)

Для только что созданного коммита:

git log -1 --format=%B | grep -vi '^co-authored-by: claude' | git commit --amend -F -

-F - считывает новое сообщение из стандартного потока ввода. Git автоматически удаляет пустые строки в начале и конце сообщения, переданного таким образом, поэтому пустая строка, оставшаяся после удаления трейлера, исчезнет сама. Проверьте результат с помощью git log -1 --format=%B, прежде чем продолжить работу.

Для нескольких коммитов в ветке выполните интерактивный rebase относительно ветки, в которую планируется слияние, и отметьте каждое сообщение, которое требуется изменить, как reword.

git rebase -i origin/main

Каждый коммит, начиная с самого раннего из отредактированных, получает новый хеш, так как хеш коммита включает в себя его сообщение и родительский коммит. Это безопасно, пока коммиты находятся только в локальном репозитории, и требует дополнительных действий, если они уже были отправлены на удаленный сервер.

Удаление трейлера после отправки (push)

В ветке, которую используете только вы, перепишите историю, как описано выше, а затем принудительно отправьте изменения.

git push --force-with-lease

--force-with-lease отклоняет отправку, если удаленный репозиторий обновился с момента вашего последнего --force, поэтому он не может незаметно отбросить коммит, добавленный кем-то другим. Обычный --force такой проверки не выполняет.

Для трейлера, распределенного по длинной истории, git filter-repo переписывает каждое сообщение за один проход. Запустите клонирование изнутри вашей текущей рабочей копии, чтобы URL был взят из уже существующего удаленного репозитория.

pip install git-filter-repo
git clone "$(git remote get-url origin)" ../project-rewrite
cd ../project-rewrite
git filter-repo --message-callback '
return b"\n".join(l for l in message.split(b"\n") if not l.lower().startswith(b"co-authored-by: claude"))
'

Callback-функция получает каждое сообщение в виде байтов и возвращает сообщение для сохранения, поэтому каждая строка в нем имеет префикс b. filter-repo отказывается работать с репозиторием, который не является свежим клоном, если вы не передадите флаг --force. После завершения работы он удаляет удаленный репозиторий origin, чтобы вы случайно не отправили переписанную историю обратно. Добавьте удаленный репозиторий снова осознанно, выполните принудительную отправку (force-push) и попросите всех сделать повторный клон, так как все хеши, которые у них есть, теперь неверны.

Четко осознавайте, чего переписывание сделать не может. Оно меняет только вашу копию репозитория. Оно не затрагивает форки, существующие клоны, зеркала, страницы pull request, где сообщение уже было процитировано, или индекс поиска по коду, который проиндексировал вас на прошлой неделе. В случае утечки секрета исправление заключается в его ротации, а переписывание истории — это лишь очистка. Трейлер с раскрытием информации не является секретом, поэтому сопоставьте необходимость переписывания всей истории с затратами: каждый открытый pull request придется создавать заново.

Чего ожидает рецензент на другой стороне

Мейнтейнеры не имеют единого мнения по этому вопросу, и именно эти разногласия — реальная причина проверить правила перед тем, как что-либо удалять. Некоторые проекты требуют раскрытия информации и попросят вас вернуть её обратно, так как рецензент иначе воспринимает патч, написанный машиной. Другие запрещают это, часто из-за вопросов о том, кто юридически является автором изменений. Проекты, использующие DCO (developer certificate of origin), требуют наличия строки Signed-off-by: — это ваше заявление о праве на отправку кода, и неосторожный фильтр сообщений удаляет её вместе с атрибуцией.

Сначала прочитайте CONTRIBUTING.md. Если в проекте ничего не сказано, выберите одно правило для репозитория и зафиксируйте его. Трейлер, который присутствует только в половине коммитов, хуже любого из вариантов: он делает историю одного проекта похожей на два разных.

Если вы запускаете агент на сервере, а не на своем ноутбуке, тот же вопрос возникает на уровень ниже. Запуск Claude Code на VPS под собственной учетной записью определяет, к каким репозиториям агент вообще имеет доступ, а что кодинг-агент отправляет за пределы машины описывает трафик, который никогда не отображается в сообщении коммита.

FAQ

Учитывается ли Co-authored-by-трейлер для Claude в статистике участников моего репозитория?

Нет. GitHub привязывает коммит к профилю через адрес электронной почты, связанный с учетной записью GitHub, и на этом основании ведет учет вкладов. Адрес, не принадлежащий ни одной учетной записи, не может быть привязан, поэтому трейлер меняет страницу коммита, но оставляет список участников без изменений. Сам Git никогда не считывает трейлеры для этой цели. git shortlog -sn учитывает только заголовок автора, поэтому соавтор там никогда не отображается.

Как найти все коммиты, которые уже содержат этот трейлер?

git log -i --grep='^Co-authored-by:' --format='%h %an %s' выводит их список по всей истории без учета регистра. В актуальных версиях git git log --format='%h %(trailers:key=Co-authored-by,valueonly)' считывает значение через собственный парсер трейлеров git, вместо поиска по «сырому» тексту. Чтобы увидеть только те коммиты, которые вы еще не отправили в удаленный репозиторий, добавьте диапазон: git log origin/main..HEAD --format=%B.

Можно ли удалить трейлер из уже отправленных коммитов?

Да, путем перезаписи истории, но это сопряжено с реальными издержками. В ветке, которую используете только вы, выполните amend или rebase, а затем git push --force-with-lease. В общей ветке каждый коммит, начиная с самого первого измененного, получит новый хеш, поэтому каждый клон и каждый открытый pull request придется пересоздавать. Кроме того, перезапись никогда не затронет форки, зеркала или клоны, сделанные кем-либо ранее.

Является ли ссылка на сессию claude.ai в сообщении коммита угрозой безопасности?

Это не учетные данные, и доступ к сессии определяется учетной записью, а не тем, насколько сложно угадать URL. Проблема в том, что это постоянный публичный текст, указывающий на транскрипт, который создавался как рабочие заметки. В документации к настройкам Claude Code указан attribution.sessionUrl как ключ, который исключает эту ссылку из коммитов в облаке и Remote Control, а хук commit-msg удаляет ее из всего, что не охвачено этой настройкой.

Стоит ли вообще отключать атрибуцию?

Это зависит от репозитория, а не от личных предпочтений. В публичном проекте следуйте файлу CONTRIBUTING.md, так как сопровождающий, которому нужно раскрытие информации, попросит вернуть его обратно. В корпоративном репозитории сохранение трейлера часто полезно, так как это позволяет проверяющему спустя год понять, почему изменение выглядит именно так. Примите решение один раз для всего репозитория и обеспечьте его соблюдение через CI, чтобы история оставалась согласованной.

#claude-code#git#commit-messages#attribution#privacy