Existe-t-il un moyen de «signer automatiquement» dans Git avec une clé GPG?

214

Existe-t-il un moyen simple de faire en sorte que Git signe toujours chaque commit ou tag créé?

Je l'ai essayé avec quelque chose comme:

alias commit = commit -S

Mais cela n'a pas fait l'affaire.

Je ne veux pas installer un programme différent pour y arriver. Est-ce faisable facilement?

Juste une question secondaire, peut-être que les commits ne devraient pas être signés, seulement les balises, que je ne crée jamais, car je soumets des commits uniques pour un projet comme Homebrew, etc.

MindTooth
la source
8
La raison pour laquelle votre alias a fonctionné est que vous ne pouvez pas créer d'alias sur une commande qui existe déjà. (connexe: stackoverflow.com/questions/5875275/git-commit-v-by-default stackoverflow.com/questions/2500586/… stackoverflow.com/questions/1278296/… )
Dan D.
2
Juste pour info: Réécrivez tous les commits pour être poussé à les signer: git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD@{u}..HEAD(je ne veux pas dire que vous devriez utiliser ceci).
Vi.

Réponses:

275

Remarque: si vous ne voulez pas ajouter -Stout le temps pour vous assurer que vos commits sont signés, il y a une proposition (branche ' pu' pour l'instant, décembre 2013, donc aucune garantie que cela se produira dans une version git) pour ajouter un config qui s'occupera de cette option pour vous.
Mise à jour de mai 2014: elle est dans Git 2.0 (après avoir été renvoyée dans cette série de patchs )

Voir commit 2af2ef3 de Nicolas Vigier (boklm) :

Ajouter l' commit.gpgsignoption de signer tous les commits

Si vous souhaitez signer GPG tous vos commits, vous devez ajouter l' -Soption en tout temps.
L' commit.gpgsignoption config permet de signer automatiquement toutes les validations.

commit.gpgsign

Un booléen pour spécifier si toutes les validations doivent être signées GPG.
L'utilisation de cette option lors de l'exécution d'opérations telles que le rebasage peut entraîner la signature d'un grand nombre de validations. Il peut être pratique d'utiliser un agent pour éviter de taper plusieurs fois votre phrase de passe GPG.


Cette configuration est généralement définie par dépôt (vous n'avez pas besoin de signer votre dépôt expérimental local privé):

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

Vous devez combiner cela avec user.signingKeyutilisé comme paramètre global (clé unique utilisée pour tous les dépôts où vous souhaitez signer la validation)

git config --global user.signingkey F2C7AB29

user.signingKeya été introduit dans git 1.5.0 (janvier 2007) avec la validation d67778e :

Il ne devrait pas être obligatoire d'utiliser la même forme que mon nom dans mon référentiel git et ma clé gpg.
De plus, je pourrais avoir plusieurs clés dans mon trousseau de clés, et je pourrais vouloir en utiliser une qui ne correspond pas à l'adresse que j'utilise dans les messages de validation.

Ce correctif ajoute une entrée de configuration " user.signingKey" qui, si elle est présente, sera transmise au commutateur "-u" pour gpg, permettant à la clé de signature de balise d'être remplacée.

Ceci est appliqué avec commit aba9119 (git 1.5.3.2) afin d'attraper le cas où Si l'utilisateur s'est mal configuré user.signingKeydans son .git/configou n'a simplement aucune clé secrète sur son trousseau de clés.

Remarques:

VonC
la source
C'est vraiment cool. Existe-t-il un moyen facile sur github de faire quelque chose comme git décrit sans avoir à télécharger le repo de trous?
13
Vous n'avez pas besoin de signer vos dépôts expérimentaux privés ... mais pourquoi pas?
Andy Hayden
168
git config --global user.signingKey 9E08524833CB3038FDE385C54C0AFCCFED5CDE14
git config --global commit.gpgSign true

Remplacez 9E08524833CB3038FDE385C54C0AFCCFED5CDE14 par votre ID de clé. N'oubliez pas: ce n'est jamais une bonne idée d'utiliser l'ID court .

MISE À JOUR: Selon un nouvel édit git , toutes les clés de configuration doivent être dans camelCase.

Felipe
la source
Vous venez de copier et coller ceci à partir de la réponse de VonC ?
Robbie Averill
19
Non. Comme vous pouvez le voir dans l'historique des éditions, quelqu'un a ajouté mon exemple dans sa réponse. ED5CDE14 est ma propre clé personnelle. Mais pas de problème.
Felipe
7
Bizarre. Je reviendrai sur le changement demain car il vous semble mauvais
Robbie Averill
Comment trouvez-vous votre identifiant de signature de clé? est-ce que le fait d'avoir seulement 1 clé GPG pour tous mes dépôts git est mauvais? parce que je préférerais de loin ne pas avoir à gérer 4 touches de diff dans des projets assez connectés.
MarcusJ
1
Cela pourrait aider les utilisateurs de Linux: Afin de le faire fonctionner dans certaines occasions (par exemple sur Vim, en utilisant une clé stockée dans une carte à puce qui nécessite la saisie d'un code PIN), j'ai dû modifier ~/.gnupg/gpg-agent.confet ajouter pinentry-program /usr/bin/pinentry-gtk-2(en suivant ce guide wiki.archlinux.org/ index.php / GnuPG # pinentry )
iakovos Gurulian
49

Edit: Depuis Git version 1.7.9, il est possible de signer Git commits ( git commit -S). Mise à jour de la réponse légèrement pour refléter cela.

Le titre de la question est:

Existe-t-il un moyen de «signer automatiquement» dans Git avec une clé GPG?

Réponse courte: oui, mais ne le faites pas.

Résolution de la faute de frappe dans la question: git commit -sne signe pas le commit. Au lieu de cela, à partir de la man git-commitpage:

-s, --signoff
Ajouter une ligne signée par le committer à la fin du message du journal de validation.

Cela donne une sortie de journal similaire à la suivante:


± $ 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 

Notez le bit "signé par: ..."; qui a été généré par le -sdrapeau sur le git-commit.

Citant l' e - mail d'annonce de sortie :

  • "git commit" a appris "-S" pour signer GPG le commit; cela peut être montré avec l'option "--show-signature" dans "git log".

Alors oui, vous pouvez signer des commits. Cependant, je recommande personnellement la prudence avec cette option; la signature automatique des validations est inutile, voir ci-dessous:

Juste une question secondaire, peut-être que les commits ne devraient pas être signés, seulement les balises, que je ne crée jamais, lorsque je soumets des commits uniques.

C'est correct. Les commits ne sont pas signés; les balises sont. La raison de cela peut être trouvée dans ce message de Linus Torvalds , dont le dernier paragraphe dit:

Signer chaque commit est totalement stupide. Cela signifie simplement que vous l'automatisez et que vous faites que la signature vaut moins. Cela n'ajoute pas non plus de valeur réelle, car la façon dont fonctionne la chaîne DAG git du SHA1, vous n'avez besoin que d' une seule signature pour que tous les commits accessibles à partir de celle-ci soient effectivement couverts par celle-ci. Donc, la signature de chaque commit manque tout simplement le point.

Je vous encourage à parcourir le message lié, ce qui explique pourquoi la signature automatique des validations n'est pas une meilleure idée que je ne pourrais le faire.

Cependant , si vous souhaitez signer automatiquement une balise , vous pourrez le faire en enveloppant le git-tag -[s|u]dans un alias; si vous voulez le faire, vous souhaiterez probablement configurer votre identifiant de clé dans ~/.gitconfigou le .git/configfichier spécifique au projet . Plus d'informations sur ce processus peuvent être consultées dans le livre de la communauté git . La signature des balises est infiniment plus utile que la signature de chaque validation que vous faites.

simont
la source
74
"Signer chaque commit est totalement stupide." -> Quelle est la meilleure façon de sécuriser les validations quand il y a un développeur "rat" qui aime pousser les validations avec un faux auteur et committer? À moins qu'il n'y ait de la magie du crochet sur le serveur, il peut diriger git blamecelui qui le veut.
Vi.
11
0. un article , 1. « est suffisante pour signer tous » -> Comment dire « Je prétends que c'est vraiment mon . Diff (mais pas sûr au sujet des précédents et d' autres commits) Je veux mettre une signature sur mon engagement sans affirmer quoi que ce soit au sujet des commits que j'ai extraits du serveur central / peu importe. 2. Dans un environnement non fiable, il devrait toujours y avoir un outil fiable pour savoir qui est coupable. Si le serveur vérifie que tous les commits sont signés avec la clé de l'email du committer, c'est difficile de simuler un commit (si vous sécurisez bien votre ordinateur)
Vi.
9
La signature d'un commit est suffisante si le code ne change jamais. Une fois que vous aurez ajouté plus de validations, vous aurez besoin de plus de signatures. Signer une balise, c'est tout marquer plus vieux que ce commit. Si vous avez besoin d'une vérification fine au fur et à mesure que les commits arrivent, il est logique de signer chaque commit. Sinon, vous devrez utiliser beaucoup de balises, ce qui ne ferait qu'encombrer le dépôt. Sur les dépôts git distants authentifiés, vous devez donner votre mot de passe ou votre clé ssh à chaque fois que vous poussez un commit, pas seulement lorsque vous poussez des balises. Il s'agit d'une situation similaire.
Hans-Christoph Steiner
22
J'ai l'impression que Linus manque un peu le sujet. Il semble avoir un cas d'utilisation entièrement différent pour les commits signés à l'esprit que l'OP dans ce thread. (Vérifier l'intégrité de l'ensemble du projet, vs vérifier la paternité d'un seul commit.)
Ajedi32
9
-1 pour "Oui, mais ne le faites pas." La réponse devrait simplement être un "OUI" catégorique. La signature des commits prouve l'auteur, ce qui autrement peut être menti dans le commit.
Urda
6

Pour que la signature automatique fonctionne avant la version 2.0 de git, vous devrez ajouter un alias git pour la validation.

# git config --global alias.commit commit -S
[alias]
    commit = commit -S
Shubham Chaudhary
la source
0

Vous devez indiquer clairement que si vous signez un commit ou un tag, cela ne signifie pas que vous approuvez tout l'historique. En cas de commit, vous ne signez que le changement à portée de main, et en cas de tag, eh bien .. vous devez définir ce que vous voulez dire avec. Vous avez peut-être tiré un changement qui prétend qu'il vient de vous mais ne l'a pas été (parce que quelqu'un d'autre l'a poussé sur votre télécommande). Ou c'est un changement auquel vous ne voulez pas participer, mais vous venez de signer la balise.

Dans les projets OSS typiques, cela peut être moins courant, mais dans un scénario d'entreprise où vous ne touchez que de temps en temps au code et que vous ne lisez pas tout l'historique, cela peut passer inaperçu.

La signature des commits est un problème s'ils sont rebasés ou sélectionnés par d'autres parents. Mais ce serait bien si un commit modifié pouvait pointer vers le commit "original" qui vérifie réellement.

eckes
la source
3
Rebaser, c'est comme mentir. Il doit être utilisé avec parcimonie. L'autre chose est que s'engager avec une signature est un code de «signature», alors assurez-vous que ce n'est pas un anti-CYA et b) un effort inutile.
11
@Barry «Rebaser, c'est comme mentir. Il doit être utilisé avec parcimonie »- ce n'est tout simplement pas vrai. Les workflows basés sur la rebase sont tout aussi valides que les workflows basés sur la fusion. Le rebasage est beaucoup trop puissant pour être utilisé avec parcimonie.
Lukas Juhrich
1
Lorsque vous utilisez cela exclusivement avec GitHub, ce n'est pas un problème, les validations de fusion ne seront pas signées par vous, car GitHub ne le prend pas en charge. L'avantage de signer chaque commit (non fusionné) dans cet environnement est qu'il est très évident lorsqu'un commit non autorisé a été ajouté via un PR car il ne sera pas signé avec votre clé GPG.
Arran Cudbard-Bell
3
"Il est dangereux si vous signez une validation ou une balise (les deux signeront tout l'historique) que vous ayez tiré une modification qui prétend que c'est de vous" Si vous ne signez une validation que si je n'interprète pas cela comme un l'approbation de chaque engagement accessible à partir du vôtre. Vous ne déclarez pas nécessairement que ces modifications passées sont valides ou approuvées par vous, mais seulement que vous avez créé une validation basée sur ces modifications. (Bien qu'avec une balise, je conviens que vous signez bien tous les commits accessibles par la balise.)
Ajedi32
1
@ ArranCudbard-Bell Tout comme une mise à jour, les validations de fusion sont signées par vous si vous définissez la valeur commit.gpgsigntrue comme suggéré par @VonC
Jay