Existe uma maneira de "autoassinar" confirmações no Git com uma chave GPG?

213

Existe uma maneira fácil de fazer o Git sempre assinar cada commit ou tag que é criado?

Eu tentei com algo como:

alias commit = commit -S

Mas isso não deu certo.

Não quero instalar um programa diferente para que isso aconteça. É factível com facilidade?

Apenas uma pergunta secundária: talvez os commits não devam ser assinados, apenas tags, que eu nunca crio, pois envio commits únicos para um projeto como o Homebrew, etc.

MindTooth
fonte
8
O motivo pelo qual seu alias funcionou é porque você não pode alias sobre um comando que já existe. (related: stackoverflow.com/questions/5875275/git-commit-v-by-default stackoverflow.com/questions/2500586/… stackoverflow.com/questions/1278296/… )
Dan D.
2
Apenas para obter informações: reescreva todos os commits a serem enviados para assiná-los: git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD@{u}..HEAD(não quero dizer que você deva usar isso).
Vi.

Respostas:

275

Nota: se você não deseja adicionar -So tempo todo para garantir que seus commits sejam assinados, existe uma proposta (filial ' pu', por enquanto, dezembro de 2013, portanto, não há garantia de que seja uma versão git) para adicionar um config que cuidará dessa opção para você.
Atualização de maio de 2014: está no Git 2.0 (depois de reenviar nesta série de patches )

Veja commit 2af2ef3 de Nicolas Vigier (boklm) :

Adicione a commit.gpgsignopção para assinar todas as confirmações

Se você deseja assinar o GPG com todos os seus commits, é necessário adicionar a -Sopção o tempo todo.
A commit.gpgsignopção de configuração permite assinar todas as confirmações automaticamente.

commit.gpgsign

Um booleano para especificar se todas as confirmações devem ser assinadas por GPG.
O uso dessa opção ao executar operações como rebase pode resultar em um grande número de confirmações sendo assinadas. Pode ser conveniente usar um agente para evitar digitar sua senha do GPG várias vezes.


Essa configuração geralmente é definida por repo (você não precisa assinar seus repositórios locais experimentais particulares):

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

Você combinaria isso com user.signingKeyusado como uma configuração global (chave exclusiva usada para todos os repositórios em que você deseja assinar o commit)

git config --global user.signingkey F2C7AB29

user.signingKeyfoi introduzido no git 1.5.0 (janeiro de 2007) com o commit d67778e :

Não deve haver um requisito de que eu use a mesma forma do meu nome no meu repositório git e na minha chave gpg.
Além disso, posso ter várias chaves no meu chaveiro e querer usar uma que não corresponda ao endereço usado nas mensagens de confirmação.

Este patch adiciona uma entrada de configuração " user.signingKey" que, se presente, será passada para a opção "-u" do gpg, permitindo que a chave de assinatura da etiqueta seja substituída.

Isso é reforçado com comprometer aba9119 (git 1.5.3.2), a fim de pegar o caso Se o usuário tiver configurado incorretamente user.signingKeyem sua .git/configou simplesmente não tem nenhum chaves secretas em seu chaveiro.

Notas:

VonC
fonte
Isso é muito legal. Existe uma maneira fácil no github de fazer algo como o git descrever sem precisar fazer o download do repositório de furos?
13
Você não precisa assinar seus repositórios experimentais particulares ... mas por que não?
Andy Hayden
168
git config --global user.signingKey 9E08524833CB3038FDE385C54C0AFCCFED5CDE14
git config --global commit.gpgSign true

Substitua 9E08524833CB3038FDE385C54C0AFCCFED5CDE14 pelo seu ID da chave. Lembre-se: nunca é uma boa ideia usar o código curto .

ATUALIZAÇÃO: Por um novo edital do git , todas as chaves de configuração devem estar no camelCase.

Felipe
fonte
Você acabou de copiar e colar isso da resposta do VonC ?
Robbie Averill 15/05
19
Não. Como você pode ver no histórico da edição, alguém adicionou meu exemplo em sua resposta. ED5CDE14 é minha própria chave pessoal. Mas não há problema.
1616 Felipe
7
Bizarro. I voltará a mudança amanhã como parece ruim para você
Robbie Averill
Como você encontra seu ID de assinatura de chave? além disso, está tendo apenas 1 chave GPG para todos os meus repositórios git ruins? porque eu preferiria não ter que lidar com 4 chaves diff em projetos bem conectados.
MarcusJ
1
Isso pode ajudar os usuários do Linux: Para fazê-lo funcionar em algumas ocasiões (por exemplo, no Vim, usando uma chave armazenada em um cartão inteligente que requer entrada de PIN), tive que editar ~/.gnupg/gpg-agent.confe adicionar pinentry-program /usr/bin/pinentry-gtk-2(seguindo este guia wiki.archlinux.org/ index.php / GnuPG # pinentry )
iakovos Gurulian
49

Edit: A partir do Git versão 1.7.9, que é possível assinar commits Git ( git commit -S). Atualizando a resposta um pouco para refletir isso.

O título da pergunta é:

Existe uma maneira de "autoassinar" confirmações no Git com uma chave GPG?

Resposta curta: sim, mas não faça isso.

Resolver o erro de digitação na pergunta: git commit -snão assina a confirmação. Pelo contrário, na man git-commitpágina:

-s, --signoff
Adiciona linha assinada pelo confirmador no final da mensagem de log de confirmação.

Isso fornece uma saída de log semelhante à seguinte:


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

Observe o bit "assinado por: ..."; que foi gerado pela -sbandeira no git-commit.

Citando o e - mail do anúncio de lançamento :

  • "git commit" learns -S "para GPG-assine o commit; isso pode ser mostrado com a opção "--show-signature" em "git log".

Então, sim, você pode assinar confirmações. No entanto, peço cautela com esta opção; assinar automaticamente confirmações é quase inútil, veja abaixo:

Apenas uma pergunta secundária: talvez as confirmações não devam ser assinadas, apenas as tags que nunca crio, pois envio confirmações únicas.

Está correto. As confirmações não são assinadas; tags são. A razão para isso pode ser encontrada nesta mensagem por Linus Torvalds , cujo último parágrafo diz:

Assinar cada confirmação é totalmente estúpido. Significa apenas que você a automatiza e faz com que a assinatura valha menos. Ele também não agrega nenhum valor real, já que, da maneira como a cadeia DAG do GIT do SHA1 funciona, você só precisa de uma assinatura para tornar todos os commits acessíveis a partir daquele que são efetivamente cobertos por esse. Portanto, assinar cada confirmação está simplesmente sem entender.

Eu incentivaria uma navegação na mensagem vinculada, que esclarece por que a assinatura confirmada automaticamente não é uma boa idéia de uma maneira muito melhor do que eu poderia.

No entanto , se você quiser assinar automaticamente uma tag , poderá fazê-lo colocando o git-tag -[s|u]alias em um alias; se você fizer isso, provavelmente desejará configurar seu ID de chave ~/.gitconfigou o .git/configarquivo específico do projeto . Mais informações sobre esse processo podem ser vistas no livro da comunidade git . A assinatura de tags é infinitamente mais útil do que a assinatura de cada confirmação que você faz.

simont
fonte
74
"Assinar cada confirmação é totalmente estúpido." -> Qual é a melhor maneira de garantir confirmações quando existe um desenvolvedor de "ratos" que gosta de enviar confirmações com autor e cometer falsos? A menos que haja alguma mágica no servidor, ele pode direcionar git blamepara quem ele quiser.
Vi.
11
0. um artigo , 1. "é suficiente para assinar todos eles" -> Como saber "Eu afirmo que este é realmente o meu diff (mas não tenho certeza sobre quaisquer confirmações anteriores e posteriores). Quero colocar uma assinatura no meu commit sem afirmar nada sobre as confirmações, puxei do servidor central / o que seja 2. No ambiente não confiável, ainda deve haver uma ferramenta confiável para descobrir quem é culpado.Se o servidor verificar se todas as confirmações estão assinadas com a chave do e-mail do autor, é difícil fingir um commit (se você proteger bem o seu computador).
Vi.
9
Assinar uma confirmação é suficiente se o código nunca mudar. Depois de adicionar mais confirmações, você precisará de mais assinaturas. Assinar uma tag está marcando tudo MAIS ANTIGO do que esse commit. Se você precisar de uma verificação granular conforme as confirmações estão chegando, faz sentido assinar cada confirmação. Caso contrário, você teria que usar muitas tags, o que acabaria com o repositório. Nos repositórios git remotos autenticados, é necessário fornecer sua senha ou chave ssh toda vez que você envia um commit, não apenas ao enviar tags. Esta é uma situação semelhante.
Hans-Christoph Steiner
22
Eu sinto que Linus está meio que perdendo o objetivo. Ele parece ter um caso de uso totalmente diferente para confirmações assinadas em mente do que o OP nesse segmento. (Verificação da integridade de todo o projeto, vs verificação da autoria de um único cometer.)
Ajedi32
9
-1 para "Sim, mas não faça isso". A resposta deve ser apenas "SIM". A assinatura de commits prova o autor, algo que pode ser mentido no commit.
Urda
6

Para fazer a assinatura automática funcionar antes da versão 2.0 do git, você precisará adicionar o alias do git para confirmação.

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

Você precisa deixar claro que, se você assinar um commit ou tag, isso não significa que você aprova todo o histórico. No caso de commits, você assina apenas a alteração em mãos e, no caso de tag, bem ... você precisa definir o que quer dizer com isso. Você pode ter efetuado uma alteração que afirma ser sua, mas não foi (porque alguém a colocou no controle remoto). Ou é uma alteração na qual você não deseja participar, mas acabou de assinar a tag.

Em projetos OSS típicos, isso pode ser menos comum, mas em um cenário corporativo em que você apenas toca o código de vez em quando e não lê todo o histórico, isso pode passar despercebido.

Assinar confirmações é um problema se elas forem rebatizadas ou escolhidas a dedo para outros pais. Mas seria bom se um commit modificado pudesse apontar para o commit "original" que realmente verifica.

eckes
fonte
3
Reprovar é como mentir. Deve ser usado com moderação. A outra coisa é que confirmar com uma assinatura é "assinar" o código, portanto, tenha certeza de que é a) não anti-CYA eb) esforço não desperdiçado.
11
@Barry “Rebasing é como mentir. Deve ser usado com moderação ”- isso não é verdade. Os fluxos de trabalho baseados em rebase são tão válidos quanto os fluxos de trabalho baseados em mesclagem. Rebasing é muito poderoso para ser usado com moderação.
Lukas Juhrich 24/10/2015
1
Ao usar isso exclusivamente com o GitHub, isso não é um problema, os commits de mesclagem não serão assinados por você, pois o GitHub não suporta isso. A vantagem de assinar todas as confirmações (sem mesclagem) nesse ambiente é que fica muito óbvio quando uma confirmação não autorizada foi adicionada por meio de um PR, pois não será assinada com sua chave GPG.
Arran Cudbard-Bell
3
"É perigoso se você assinar um commit ou tag (ambos assinarão todo o histórico) que você pode ter efetuado uma alteração que afirma ser sua." Se você estiver assinando um commit, embora eu não o interprete endosso de todos os commit alcançáveis ​​a partir do seu. Você não está necessariamente afirmando que essas alterações passadas são válidas ou endossadas por você, apenas que você criou uma confirmação com base nessas alterações. (Embora com uma tag, eu concordo que você está realmente assinando todos os commits alcançáveis ​​pela tag.)
Ajedi32
1
@ ArranCudbard-Bell Assim como uma atualização, os commits de mesclagem são assinados por você, se você definir commit.gpgsigncomo true, conforme sugerido por @VonC
Jay