This site is an archive of ama.ne.jp.

Git署名のウソホント

みなさんはGitで署名していますか?

Gitで署名する

Gitで作業内容に署名を行うには、タグまたはコミットに対してGPGで署名を行わなければなりませんでした。

参考: Git - 作業内容への署名

タグに署名する

-sオプションを使用します。

$ git tag -s v0.1 -m 'release'

コミットに署名する

-Sオプションを使用します。コミットへの署名は、タグへの署名よりも新しい機能です。

$ git commit -S -m 'commit message'

「Gitで署名」の謎

ところで、みなさんが大好きなQiitaで次のようなコメントを見かけました。

後々rebase+squashする予定があるなら、それぞれのコミットに自動で署名するよりも、rebaseした後で git commit --amend -Sとして署名するのが賢明かもしれません。pushするまでは署名していようがいまいが、さほど問題ではありませんので。やたらと署名したら署名の価値が落ちる、とリーナスは言っています
http://git.661346.n2.nabble.com/GPG-signing-for-git-commit-td2582986.html

GitHubでGPGによりデジタル署名されたコミットにバッジが表示されるようになったので設定してみる

署名の価値が落ちる、とはどういうことでしょうか? 作業内容にしっかり署名をするのが悪いというのは、明らかに直感に反しています。

「やたらと署名したら署名の価値が落ちる」の謎

このコメントでは、リーナスが

やたらと署名したら署名の価値が落ちる

と言っているとのことでしたので、とりあえず元のスレッドを漁ってみましょう。この章での以下の引用はGPG signing for git commit?からのものです。

On Sat, 4 Apr 2009, Chow Loong Jin wrote:

It crossed my mind that currently git commits cannot actually be verified to be authentic, due to the fact that I can just set my identity to be someone else, and then commit under their name.

You can't do that.

Well, you can, but it's always going to be inferior to just adding a tag.

話題としては、コミットに署名することでコミッタ情報の正当性を保証したいというものらしく、一方でリーナスはタグへの署名を推していますね。

Anything else is always bound to only sign a part of the commit. What part do you feel like protecting? Or put another way, what part do you feel like not protecting?

So the way git does signatures protects everything. When you do a tag with "git tag -s" on a commit, you can absolutely know that nobody will ever modify that commit in any way without the tag signature becoming invalid.

コミットへの署名は一部の情報しか保護できないのに対し、タグへ署名することでコミット全体(すなわち全ての情報)を保護できるとのことです。どういうこと?

ここからいくつかタグへの署名を用いるメリットが続きます。タグへ署名することでコミットと署名を明確に分けることができるため、それにより多数のメリットを享受できるようです。

You can do none of these things sanely if you put the signatures into the commits themselves.

コミットへの署名では、タグへの署名で得られるはずの多数のメリットも失ってしまうとのこと。コミットと署名を分離できなくなってしまったので、確かにそうですね。

Signing each commit is totally stupid. It just means that you automate it, and you make the signature worth less. It also doesn't add any real value, since the way the git DAG-chain of SHA1's work, you only ever need one signature to make all the commits reachable from that one be effectively covered by that one. So signing each commit is simply missing the point.

最後にそれっぽいことが書いてありました。全てのコミットに署名するのはアホだし、自動で署名するのは署名の価値が落ちると。「署名の価値が落ちる」と書いてありますが、ここでいう「価値」はいまいちよく分かりません。stupidくらいの意味でしょうか。その後に、自動署名はコミットから過去を簡単に辿れるGitの仕様上意味のない行為であるとも述べていますので、そういう点で価値がないと言っているのかもしれません。

IOW, you don't ever have a reason to sign anythign but the "tip". The only exception is the "go back and re-sign", but that's the one that requires external signatures anyway.

So be happy with 'git tag -s'. It really is the right way.

という感じです。自動で全部のコミットに署名するのはアホだし、単一のコミットに署名するくらいならタグに署名する方がすごく良いとのこと。

Gitで正しく署名する

リーナスが悪いと言っていたのは、

  • タグへ署名せずにコミットへ署名すること
  • あまつさえコミットへの署名を自動化してしまうこと

みたいですね。タグへの署名が本当に最適解かどうかはまぁ分からんけど。

とりあえず、元のコメントではタグへの署名の話を全く引用してくれなかったので、意味が分からなかった。rebaseしてから署名し直したほうが良いよというアドバイスもあんまり本質的なものではなさそう。うーん。

コミットに署名するのをやめろ。今すぐタグに署名をしろ。

さいごに

いくらググってもコミットへの署名の話しか出てこないし、タグへの署名を知らないんじゃないの? 僕も知らなかった。