W3docs

Подпись коммитов

Как подписывать коммиты и теги Git с помощью GPG или SSH для подтверждения авторства и получения значка Verified.

Подпись коммита прикрепляет криптографическую подпись, которая доказывает кто его создал и что содержимое не было изменено. В этой главе объясняется, почему подписи важны, как сгенерировать ключ, как подписывать коммиты и теги с помощью GPG или SSH, как проверять подписи и как исправлять ошибки, с которыми вы, скорее всего, столкнётесь в первый раз.

Что именно доказывает подпись

По умолчанию имя автора и email в коммите — это просто текст. Git никогда не проверяет их — кто угодно может задать user.name и user.email любое значение (см. git config) и создать коммит, который претендует быть от чужого имени. Подпись меняет это: она создаётся с помощью закрытого ключа, который есть только у вас, и любой, кто имеет ваш соответствующий открытый ключ, может подтвердить два факта:

  • Авторство — коммит действительно создан владельцем данного закрытого ключа.
  • Целостность — если изменится даже один байт коммита (сообщение, дерево, родитель, автор), проверка завершится неудачей.

Для проектов, где происхождение важно — чувствительный к безопасности код, релизы с открытым исходным кодом, регулируемые среды — подписанная история позволяет рецензентам доверять тому, кто что написал. На GitHub и GitLab проверенная подпись даёт зелёный значок Verified рядом с коммитом.

Примечание
Подпись не шифрует ничего. Коммит и его содержимое остаются полностью читаемыми; подпись лишь удостоверяет происхождение и целостность.

Выбор GPG или SSH

Git поддерживает два формата подписи. Выберите один:

  • GPG (OpenPGP) — традиционный вариант. Зрелый, широко поддерживаемый, но управление ключами (связки ключей, истечение срока действия, агент gpg) требует привыкания.
  • SSH — доступен начиная с Git 2.34. Если вы уже используете SSH-ключ для push, можно повторно использовать его для подписи практически без дополнительной настройки. Проще в управлении, и теперь является рекомендуемой отправной точкой для большинства людей.

Сначала проверьте вашу версию:

git --version

Подпись с помощью GPG

Создание или поиск ключа

Если у вас ещё нет GPG-ключа, создайте его (оставьте настройки по умолчанию, выбрав 4096-битный RSA или ECC-ключ):

gpg --full-generate-key

Выведите список ключей и скопируйте длинный идентификатор ключа — значение после алгоритма в строке sec:

gpg --list-secret-keys --keyid-format=long
sec   ed25519/3AA5C34371567BD2 2024-01-08 [SC]
      AB1C2D3E...
uid   Jane Dev <[email protected]>

Здесь идентификатор ключа — 3AA5C34371567BD2.

Настройка Git

git config --global user.signingkey 3AA5C34371567BD2
git config --global commit.gpgsign true

Подпись коммита или тега

При включённом commit.gpgsign каждый коммит подписывается автоматически. Чтобы явно подписать один коммит, используйте флаг -S в верхнем регистре:

git commit -S -m "Add audited payment handler"

Чтобы подписать аннотированный тег, используйте -s в нижнем регистре:

git tag -s v2.0.0 -m "Signed release 2.0.0"
Внимание
Регистр важен: -S (верхний регистр) подписывает коммит, а -s (нижний регистр) подписывает тег. В команде git commit строчный флаг -s добавляет строку Signed-off-by — это текстовый Developer Certificate of Origin, а не криптографическая подпись.

Подпись с помощью SSH

Если у вас есть ключ id_ed25519 (или любой другой SSH-ключ), укажите Git путь к открытому ключу и переключите формат подписи:

git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true

Коммиты и теги теперь подписываются теми же флагами -S / -s, что и раньше — никаких других изменений не требуется.

Включение локальной проверки для SSH

В отличие от GPG, у Git нет встроенного хранилища доверия для SSH-ключей, поэтому git log --show-signature сообщает No principal matched, пока вы не создадите файл allowed signers. Сопоставьте каждый email с его открытым ключом:

mkdir -p ~/.config/git
echo "[email protected] $(cat ~/.ssh/id_ed25519.pub)" >> ~/.config/git/allowed_signers
git config --global gpg.ssh.allowedSignersFile ~/.config/git/allowed_signers

Загрузка открытого ключа на хостинг

Значок Verified появляется только после того, как хостинг получит ваш открытый ключ.

  • GPG: скопируйте открытый ключ в формате ASCII Armor из gpg --armor --export <key-id> и вставьте его в Settings → SSH and GPG keys → New GPG key.
  • SSH: добавьте содержимое ~/.ssh/id_ed25519.pub как ключ типа Signing key (отдельно от ключа аутентификации) в той же области настроек.

Email в вашем ключе должен совпадать с email автора коммита, иначе хостинг покажет Unverified.

Проверка подписей

Проверяйте подписи локально любым из этих способов:

git log --show-signature          # show signature status in the log
git verify-commit HEAD            # verify one commit
git verify-tag v2.0.0             # verify a tag

Для компактного вывода заполнитель %G? в git log выводит один код статуса на коммит:

git log --pretty="%h %G? %s"
a1b2c3d G  Add audited payment handler
d4e5f6g N  Quick typo fix

G означает хорошую (действительную) подпись, B — плохую, U — хорошую с неизвестной действительностью, N — отсутствие подписи.

Распространённые ошибки и их устранение

  • error: gpg failed to sign the data — обычно агент GPG не может запросить вашу парольную фразу. Экспортируйте терминал, который он должен использовать: export GPG_TTY=$(tty) (добавьте в ~/.bashrc или ~/.zshrc). На macOS установите pinentry-mac, чтобы агент мог открыть диалог ввода пароля.
  • gpg: signing failed: No secret keyuser.signingkey указывает на неверный идентификатор. Проверьте повторно с помощью gpg --list-secret-keys --keyid-format=long.
  • GitHub показывает Unverified — email автора коммита не совпадает с email, привязанным к загруженному ключу, или ключ не был добавлен на хостинг.
  • No principal matched (SSH) — вы не настроили gpg.ssh.allowedSignersFile (см. выше).

Часто используемые параметры

КомандаОписание
git commit -SПодписывает один коммит.
git tag -s <name>Создаёт подписанный аннотированный тег.
git config commit.gpgsign trueПодписывает каждый коммит автоматически.
git config gpg.format sshПодписывает с помощью SSH-ключа вместо GPG.
git log --show-signatureОтображает статус подписи в логе.
git log --pretty="%G?"Выводит код статуса подписи для каждого коммита.
git verify-commit <commit>Проверяет подпись коммита.
git verify-tag <tag>Проверяет подпись тега.

Практика

Практика
Какие утверждения о подписи коммитов верны?
Какие утверждения о подписи коммитов верны?
Was this page helpful?