¿Hay alguna forma de "autofirmar" confirmaciones en Git con una clave GPG?

213

¿Hay una manera fácil de hacer que Git siempre firme cada confirmación o etiqueta que se crea?

Lo probé con algo como:

alias commit = commit -S

Pero eso no funcionó.

No quiero instalar un programa diferente para que esto suceda. ¿Es factible con facilidad?

Solo una pregunta secundaria, tal vez las confirmaciones no deberían firmarse, solo etiquetas, que nunca creo, ya que envío confirmaciones individuales para un proyecto como Homebrew, etc.

MindTooth
fuente
8
La razón por la que su alias funcionó es porque no puede alias sobre un comando que ya existe. (relacionado: stackoverflow.com/questions/5875275/git-commit-v-by-default stackoverflow.com/questions/2500586/… stackoverflow.com/questions/1278296/… )
Dan D.
2
Solo para información: reescriba todos los commits que se enviarán para firmarlos: git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD@{u}..HEAD(No quiero decir que deba usar esto).
Vi.

Respuestas:

275

Nota: si no desea agregar -Stodo el tiempo para asegurarse de que sus confirmaciones estén firmadas, hay una propuesta (rama ' pu' por ahora, diciembre de 2013, por lo que no hay garantía de que llegue a un lanzamiento de git) para agregar un config que se encargará de esa opción por usted.
Actualización de mayo de 2014: está en Git 2.0 (después de reenviarse en esta serie de parches )

Ver commit 2af2ef3 por Nicolas Vigier (boklm) :

Agregue la commit.gpgsignopción para firmar todas las confirmaciones

Si desea que GPG firme todas sus confirmaciones, debe agregar la -Sopción todo el tiempo.
La commit.gpgsignopción de configuración permite firmar todas las confirmaciones automáticamente.

commit.gpgsign

Un booleano para especificar si todas las confirmaciones deben estar firmadas por GPG.
El uso de esta opción cuando se realizan operaciones como rebase puede resultar en la firma de un gran número de confirmaciones. Puede ser conveniente utilizar un agente para evitar escribir su frase de contraseña GPG varias veces.


Esa configuración generalmente se establece por repositorio (no necesita firmar sus repositorios locales experimentales privados):

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

Combinaría eso con user.signingKeyutilizado como una configuración global (clave única utilizada para todos los repositorios donde desea firmar confirmación)

git config --global user.signingkey F2C7AB29

user.signingKeyse introdujo en git 1.5.0 (enero de 2007) con commit d67778e :

No debería haber un requisito de que use la misma forma de mi nombre en mi repositorio git y mi clave gpg.
Además, podría tener varias claves en mi llavero, y podría querer usar una que no coincida con la dirección que uso en los mensajes de confirmación.

Este parche agrega una entrada de configuración "user.signingKey " que, si está presente, se pasará al modificador "-u" para gpg, permitiendo que se anule la clave de firma de etiqueta.

Esto se aplica con commit aba9119 (git 1.5.3.2) para detectar el caso en el que si el usuario ha configurado maluser.signingKey en su .git/configcuenta o no tiene ningún claves secretas en su llavero.

Notas:

VonC
fuente
Eso es realmente genial. ¿Hay alguna manera fácil en github de hacer algo como git describe sin tener que descargar el repositorio de agujeros?
13
No necesita firmar sus repositorios experimentales privados ... pero ¿por qué no lo haría?
Andy Hayden
168
git config --global user.signingKey 9E08524833CB3038FDE385C54C0AFCCFED5CDE14
git config --global commit.gpgSign true

Reemplace 9E08524833CB3038FDE385C54C0AFCCFED5CDE14 por su ID de clave. Recuerde: nunca es una buena idea usar la ID corta .

ACTUALIZACIÓN: Por un nuevo decreto git , todas las claves de configuración deben estar en camelCase.

Felipe
fuente
¿Acabas de copiar y pegar esto de la respuesta de VonC ?
Robbie Averill
19
No. Como puede ver en el historial de la edición, alguien ha agregado mi ejemplo en su respuesta. ED5CDE14 es mi propia clave personal. Pero no hay problema.
Felipe
77
Extraño. Revertiré el cambio mañana, ya que se ve mal para ti
Robbie Averill
¿Cómo encuentra su identificación de firma clave? Además, ¿es malo tener solo 1 clave GPG para todos mis repositorios git? porque preferiría no tener que lidiar con 4 teclas diff en proyectos bastante conectados.
MarcusJ
1
Esto podría ayudar a los usuarios de Linux: para que funcione en algunas ocasiones (por ejemplo, en Vim, usando una clave almacenada en una tarjeta inteligente que requiere la entrada del PIN) tuve que editar ~/.gnupg/gpg-agent.confy agregar pinentry-program /usr/bin/pinentry-gtk-2(siguiendo esta guía wiki.archlinux.org/ index.php / GnuPG # pinentry )
iakovos Gurulian
49

Editar: A partir de la versión 1.7.9 de Git, que es posible firmar confirmaciones Git (git commit -S ). Actualizando ligeramente la respuesta para reflejar esto.

El título de la pregunta es:

¿Hay alguna forma de "autofirmar" confirmaciones en Git con una clave GPG?

Respuesta corta: sí, pero no lo hagas.

Abordar el error tipográfico en la pregunta: git commit -sno firma el compromiso. Más bien, de la man git-commitpágina:

-s, --signoff
Agrega una línea firmada por el confirmador al final del mensaje de registro de confirmación.

Esto proporciona una salida de registro similar a la siguiente:


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

Tenga en cuenta el bit "Firmado por: ..."; que fue generado por la -sbandera en elgit-commit .

Citando el correo electrónico de anuncio de lanzamiento :

  • "git commit" aprendido "-S" a GPG-firma el commit; Esto se puede mostrar con la opción "--show-signature" para "git log".

Entonces sí, puedes firmar confirmaciones. Sin embargo, personalmente insto a la precaución con esta opción; la firma automática de confirmaciones no tiene sentido, vea a continuación:

Solo una pregunta secundaria, tal vez las confirmaciones no deberían firmarse, solo etiquetas, que nunca creo, ya que envío confirmaciones individuales.

Eso es correcto. Los compromisos no están firmados; las etiquetas son La razón de esto se puede encontrar en este mensaje de Linus Torvalds , cuyo último párrafo dice:

Firmar cada confirmación es totalmente estúpido. Simplemente significa que lo automatizas y haces que la firma valga menos. Tampoco agrega ningún valor real, ya que la forma en que funciona la cadena git DAG de SHA1, solo necesita una firma para que todas las confirmaciones accesibles desde esa estén efectivamente cubiertas por esa. Por lo tanto, firmar cada confirmación simplemente pierde el punto.

Animaría a examinar el mensaje vinculado, lo que aclara por qué firmar confirmaciones automáticamente no es una buena idea de una manera mucho mejor de lo que podría.

Sin embargo , si desea firmar automáticamente una etiqueta , podrá hacerlo envolviéndola git-tag -[s|u]en un alias; si va a hacer eso, probablemente desee configurar su identificación de clave ~/.gitconfigo el .git/configarchivo específico del proyecto . Se puede ver más información sobre ese proceso en el libro de la comunidad de git . Firmar etiquetas es infinitamente más útil que firmar cada confirmación que realice.

simont
fuente
74
"Firmar cada confirmación es totalmente estúpido". -> ¿Cuál es la mejor manera de asegurar los commits cuando hay un desarrollador "rata" al que le gusta empujar commits con el autor y el committer falsificados? A menos que haya algo de magia de gancho en el servidor, puede dirigirlo git blamea quien quiera.
Vi.
11
0. un artículo , 1. "es suficiente para firmarlos todos" -> Cómo decir "Afirmo que este es realmente mi diferencia (pero no estoy seguro acerca de los compromisos anteriores y posteriores). Quiero poner una firma en mi compromiso sin afirmar nada sobre los commits que saqué del servidor central / lo que sea 2. En un entorno no confiable todavía debe haber una herramienta confiable para averiguar quién es el culpable. Si el servidor verifica que todos los commits estén firmados con la clave del correo electrónico del committer, es difícil de falsificar una confirmación (si asegura bien su computadora).
Vi.
99
Firmar una confirmación es suficiente si el código nunca cambia. Una vez que agregue más confirmaciones, necesitará más firmas. Firmar una etiqueta es marcar todo ANTIGUO que esa confirmación. Si necesita una verificación detallada a medida que se acercan las confirmaciones, tiene sentido firmar cada confirmación. De lo contrario, tendrías que usar muchas etiquetas, lo que desordenaría el repositorio. En repositorios de git remotos autenticados, debe proporcionar su contraseña o clave ssh cada vez que empuja un commit, no solo cuando empuja etiquetas. Esta es una situación similar.
Hans-Christoph Steiner
22
Siento que Linus está perdiendo el punto. Parece tener en mente un caso de uso completamente diferente para las confirmaciones firmadas que el OP en ese hilo. (Verificación de la integridad de todo el proyecto, frente a la verificación de la autoría de un solo compromiso.)
Ajedi32
99
-1 para "Sí, pero no lo hagas". La respuesta debería ser simplemente un "SÍ". Firmar confirmaciones prueba al autor, algo que de otra manera se puede mentir en la confirmación.
Urda
6

Para que la firma automática funcione antes de la versión 2.0 de git, deberá agregar el alias de git para commit.

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

Debe dejar en claro que si firma una confirmación o etiqueta, no quiere decir que aprueba todo el historial. En caso de confirmaciones, solo firma el cambio en cuestión y, en caso de etiqueta, bueno ... debe definir qué quiere decir con él. Es posible que haya realizado un cambio que dice que es suyo pero que no lo fue (porque alguien más lo empujó a su control remoto). O es un cambio en el que no desea participar, pero acaba de firmar la etiqueta.

En los proyectos típicos de OSS, esto podría ser menos común, pero en un escenario empresarial donde solo toca el código de vez en cuando y no lee todo el historial, puede pasar desapercibido.

Firmar confirmaciones es un problema si se rebajan o se eligen a otros padres. Pero sería bueno si una confirmación modificada pudiera apuntar a la confirmación "original" que realmente verifica.

Eckes
fuente
3
Rebasar es como mentir. Se debe usar con mucha moderación. La otra cosa es que comprometerse con una firma es el código de "cierre de sesión", así que asegúrese de que sea a) no anti-CYA yb) no se desperdicie el esfuerzo.
11
@Barry “Rebasar es como mentir. Debe ser usado con moderación ”, esto simplemente no es cierto. Los flujos de trabajo basados ​​en Rebase son tan válidos como los flujos de trabajo basados ​​en fusión. Rebasar es demasiado poderoso para ser usado con moderación.
Lukas Juhrich
1
Cuando use esto exclusivamente con GitHub, eso no es un problema, las confirmaciones de fusión no serán firmadas por usted, ya que GitHub no lo admite. La ventaja de firmar cada confirmación (no fusión) en este entorno es que es muy obvio cuando se agrega una confirmación no autorizada a través de un RP, ya que no se firmará con su clave GPG.
Arran Cudbard-Bell
3
"Es peligroso si firmas un commit o una etiqueta (ambos firmarán todo el historial) que podrías haber sacado un cambio que dice que es tuyo" Si solo firmas un commit, no lo interpretaría como un endoso de cada compromiso accesible desde el suyo. No está declarando necesariamente que esos cambios pasados ​​son válidos o respaldados por usted, solo que creó una confirmación basada en esos cambios. (Aunque con una etiqueta, estoy de acuerdo en que está firmando todas las confirmaciones accesibles por la etiqueta.)
Ajedi32
1
@ ArranCudbard-Bell Como una actualización, las confirmaciones de fusión están firmadas por usted si se configura commit.gpgsigncomo verdadero según lo sugerido por @VonC
Jay