Есть ли способ «автоматической подписи» коммитов в Git с помощью ключа GPG?

214

Есть ли простой способ сделать так, чтобы Git всегда подписывал каждый созданный коммит или тэг?

Я попробовал это с чем-то вроде:

псевдоним commit = commit -S

Но это не помогло.

Я не хочу устанавливать другую программу, чтобы это произошло. Это выполнимо с легкостью?

Просто дополнительный вопрос, может быть, коммиты не должны подписываться, только теги, которые я никогда не создаю, так как я отправляю отдельные коммиты для проекта, такого как Homebrew и т. Д.

MindTooth
источник
8
Причина, по которой ваш псевдоним сработал, заключается в том, что вы не можете использовать псевдоним для уже существующей команды. (связано: stackoverflow.com/questions/5875275/git-commit-v-by-default stackoverflow.com/questions/2500586/… stackoverflow.com/questions/1278296/… )
Дэн Д.
2
Только для информации: переписать все коммиты, которые нужно нажать, чтобы подписать их: git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD@{u}..HEAD(я не имею в виду, что вы должны использовать это).
Ви.

Ответы:

275

Примечание: если вы не хотите добавлять -Sвсе время, чтобы убедиться, что ваши коммиты подписаны, есть предложение (ветвь ' pu' на данный момент, декабрь 2013 года, поэтому нет гарантии, что он попадет в релиз git), чтобы добавить Конфиг, который позаботится об этой опции для вас.
Обновление май 2014: выпущено в Git 2.0 (после повторной отправки в этой серии патчей )

См совершать 2af2ef3 на Николя Vigier (boklm) :

Добавьте commit.gpgsignопцию, чтобы подписать все коммиты

Если вы хотите, чтобы GPG подписывал все ваши коммиты, вы должны -Sвсе время добавлять опцию.
Опция commit.gpgsignconfig позволяет автоматически подписывать все коммиты.

commit.gpgsign

Логическое значение, указывающее, должны ли подписываться все коммиты.
Использование этой опции при выполнении таких операций, как rebase, может привести к подписанию большого количества коммитов. Может быть удобно использовать агент, чтобы не вводить вашу парольную фразу GPG несколько раз.


Эта конфигурация обычно устанавливается для репо (вам не нужно подписывать свои частные экспериментальные локальные репо):

cd /path/to/repo/needing/gpg/signature
git config commit.gpgsign true

Вы бы объединили это с user.signingKeyиспользованием в качестве глобального параметра (уникальный ключ, используемый для всех репо, где вы хотите подписать коммит)

git config --global user.signingkey F2C7AB29

user.signingKeyбыл представлен в git 1.5.0 (январь 2007 г.) с коммитом d67778e :

Не должно быть требования, чтобы я использовал одинаковую форму моего имени в моем git-репозитории и ключе gpg.
Кроме того, у меня может быть несколько ключей в моей связке ключей, и я могу захотеть использовать тот, который не совпадает с адресом, который я использую в сообщениях фиксации.

Этот патч добавляет запись конфигурации " user.signingKey", которая, если присутствует, будет передана переключателю "-u" для gpg, позволяя переопределить ключ подписи тега.

Это обеспечивается коммитом aba9119 (git 1.5.3.2), чтобы отследить случай, когда пользователь неверно настроил user.signingKeyсвои данные .git/configили просто не имеет никаких секретных ключей в своей связке ключей.

Ноты:

VonC
источник
Это действительно круто. Есть ли на github простой способ сделать что-то вроде git description без необходимости загружать репо?
13
Вам не нужно подписывать свои частные экспериментальные репозитории ... но почему бы и нет?
Энди Хейден,
168
git config --global user.signingKey 9E08524833CB3038FDE385C54C0AFCCFED5CDE14
git config --global commit.gpgSign true

Замените 9E08524833CB3038FDE385C54C0AFCCFED5CDE14 на свой идентификатор ключа. Помните: никогда не стоит использовать короткий идентификатор .

UPDATE: Пер новый мерзавец эдикта , все ключи конфигурации должны быть в верблюжьем.

Фелипе
источник
Вы только что скопировали и вставили это из ответа VonC ?
Робби Аверилл
19
Нет. Как вы можете видеть в истории издания, кто-то добавил мой пример в свой ответ. ED5CDE14 - мой личный ключ. Без проблем.
Фелипе
7
Bizarre. Я верну изменения завтра, так как это выглядит плохо для вас
Робби Аверилл
Как вы находите свой идентификатор подписи ключа? также, плохо ли иметь только 1 GPG-ключ для всех моих репозиториев git? потому что я бы предпочел не иметь дело с 4-мя дифференциальными клавишами в довольно связанных проектах.
MarcusJ
1
Это может помочь пользователям Linux: чтобы заставить его работать в некоторых случаях (например, в Vim, используя ключ, хранящийся на смарт-карте, для которой требуется ввод PIN-кода), мне пришлось отредактировать ~/.gnupg/gpg-agent.confи добавить pinentry-program /usr/bin/pinentry-gtk-2(следуя этому руководству wiki.archlinux.org/ index.php / GnuPG # pinentry )
iakovos Gurulian
49

Edit: На Git версии 1.7.9, то это можно подписать Git совершающее ( git commit -S). Обновление ответа немного, чтобы отразить это.

Название вопроса:

Есть ли способ «автоматической подписи» коммитов в Git с помощью ключа GPG?

Краткий ответ: да, но не делай этого.

Обращаясь к опечатке в вопросе: git commit -sне подписывает коммит. Скорее со man git-commitстраницы:

-s, --signoff
Добавить подпись от коммиттера в конце сообщения журнала фиксации.

Это дает вывод журнала, подобный следующему:


± $ git log                                                                                 [0:43:31]
commit 155deeaef1896c63519320c7cbaf4691355143f5
Author: User Name 
Date:   Mon Apr 16 00:43:27 2012 +0200

    Added .gitignore

    Signed-off-by: User Name 

Обратите внимание на бит «Подписано: ...»; это было сгенерировано -sфлагом на git-commit.

Цитируя электронное сообщение о релизе :

  • "git commit" научился "-S" для GPG-подписать коммит; это можно показать с помощью опции --show-signature для git log.

Так что да, вы можете подписывать коммиты. Тем не менее, я лично призываю к осторожности с этой опцией; автоматическое подписание коммитов практически бессмысленно, см. ниже:

Просто дополнительный вопрос, возможно, коммиты не должны подписываться, только теги, которые я никогда не создаю, так как я отправляю отдельные коммиты.

Это правильно. Комитеты не подписаны; теги есть. Причину этого можно найти в этом сообщении Линуса Торвальдса , последний абзац которого гласит:

Подписывать каждый коммит совершенно глупо. Это просто означает, что вы автоматизируете это, и вы делаете подпись на сумму меньше. Это также не добавляет никакой реальной ценности, поскольку, как работает цепочка мерзких DAG в SHA1, вам когда-либо понадобится только одна подпись, чтобы все коммиты, достижимые из этого, были эффективно охвачены этим. Так что подписание каждого коммита просто упускает смысл.

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

Однако , если вы хотите автоматически подписать тег , вы сможете сделать это, git-tag -[s|u]заключив его в псевдоним; если вы собираетесь это сделать, вы, вероятно, захотите установить свой идентификатор ключа ~/.gitconfigили .git/configфайл проекта . Больше информации об этом процессе можно увидеть в книге сообщества git . Подписание тегов бесконечно более полезно, чем подписание каждого коммита, который вы делаете.

simont
источник
74
«Подписывать каждый коммит совершенно глупо». -> Какой лучший способ обезопасить коммиты, когда есть «крысиный» разработчик, которому нравится выдвигать коммиты с фальшивым автором и коммиттером? Если на сервере нет какой-то магии крючков, он может направить git blameкому угодно.
Ви.
11
0. статья , 1. «достаточно подписать их все» -> Как сказать «Я утверждаю, что это действительно моя разница (но я не уверен насчет предыдущих и последующих коммитов). Я хочу поставить подпись на своем коммите не утверждая ничего о коммитах, которые я извлек с центрального сервера / что угодно. 2. В ненадежной среде все еще должен быть надежный инструмент, чтобы выяснить, кто виноват. Если сервер проверяет, что все коммиты подписаны ключом электронной почты коммиттера, это трудно подделать коммит (если вы хорошо защитите свой компьютер)
Vi.
9
Подписание одного коммита достаточно, если код никогда не меняется. Как только вы добавите больше коммитов, вам понадобится больше подписей. Подпись тега означает все, что старше, чем этот коммит. Если вам нужна детальная проверка по мере поступления коммитов, имеет смысл подписать каждый коммит. В противном случае вам придется использовать много тегов, которые просто загромождают репо. На аутентифицированных удаленных репозиториях git вы должны давать свой пароль или ключ ssh каждый раз, когда вы нажимаете коммит, а не только когда вы нажимаете теги. Это похожая ситуация.
Ганс-Кристоф Штайнер,
22
Я чувствую, что Линус упускает суть. Похоже, он имеет в виду совершенно иной вариант использования подписанных коммитов, чем OP в этом потоке. (Проверка целостности всего проекта, против проверки авторства одного коммита.)
Ajedi32
9
-1 для «Да, но не делай этого». Ответ должен быть просто "ДА". Подписание коммитов доказывает автору, что в противном случае может быть использовано в коммите.
Урда
6

Чтобы автоматическая подпись работала до версии git 2.0, вам нужно добавить псевдоним git для commit.

# git config --global alias.commit commit -S
[alias]
    commit = commit -S
Шубхам Чаудхари
источник
0

Вы должны четко указать, что если вы подписываете коммит или тег, это не означает, что вы одобряете всю историю. В случае коммитов вы только подписываете изменения под рукой, а в случае тега, ну ... вам нужно определить, что вы имеете в виду. Возможно, вы извлекли изменение, которое утверждает, что оно от вас, но не было (потому что кто-то другой выдвинул его на ваш пульт). Или это изменение, в котором вы не хотите участвовать, но вы только что подписали тег.

В типичных проектах OSS это может быть не так часто, но в корпоративном сценарии, когда вы только касаетесь кода время от времени и не читаете всю историю, он может остаться незамеченным.

Подписание коммитов является проблемой, если они будут перебазированы или подобраны другим родителям. Но было бы хорошо, если бы измененный коммит мог указывать на «оригинальный» коммит, который фактически проверяет.

Экес
источник
3
Перебазирование - это как ложь. Это должно использоваться чрезвычайно экономно. Другое дело, что фиксация с помощью подписи - это «отписывание» кода, поэтому будьте уверены, что это а) не анти-CYA и б) не напрасные усилия.
11
@ Барри «Перебазирование - это как ложь. Его следует использовать крайне экономно »- это просто неправда. Рабочие процессы, основанные на ребазе, так же действительны, как и рабочие процессы, основанные на слиянии. Перебазировка слишком мощная, чтобы использовать ее экономно.
Лукас Юрич
1
При использовании этого исключительно с GitHub, это не проблема, коммиты слияния не будут подписаны вами, так как GitHub не поддерживает это. Преимущество подписания каждого (не объединяющего) коммита в этой среде состоит в том, что становится очень очевидным, когда мошеннический коммит был добавлен через PR, поскольку он не будет подписан вашим ключом GPG.
Арран Кудбард-Белл
3
«Опасно, если вы подпишете коммит или тэг (оба подпишут всю историю), что вы могли получить изменение, которое утверждает, что оно от вас» Если вы только подписываете коммит, хотя я бы не интерпретировал это как одобрение каждого коммита, достижимого от вас. Вы не обязательно заявляете, что эти прошлые изменения действительны или одобрены вами, только что вы создали коммит на основе этих изменений. (Хотя с тегом я согласен, что вы действительно подписываете все коммиты, доступные по тегу.)
Ajedi32
1
@ ArranCudbard-Bell Точно так же, как обновление, коммиты слияния подписываются вами, если вы установили commit.gpgsignзначение true, как предложено @VonC
Jay