not good but great

プログラミング、アート、映画・本の感想について書きます。

Githubの中の人に聞いた、commit識別番号を人間でも扱いやすくする3つの工夫

f:id:naoyashiga:20131122012250j:plain
大阪で行われた「GitHub トレーニングチームから学ぶ GitとGitHubの基礎」というセミナーに参加してきた。折角なので質問をした。質問をした背景、その回答を書いてみた。

commit識別番号とは?

gitでコミットしたときに、つけられる番号。グローバルで一意のため英数字の羅列になっている。

ログを出力すると、識別番号を見ることができる。

$git log
commit 0162e65afed22b9fbd4ef915d77f9f67a223f7ec
Author: naoyashiga
Date: Sun Jun 2 18:57:30 2013 +0900

change README.md

commit 57228b29d976075bdf47eb9ea7ead44c8b867632
Author: naoyashiga
Date: Sun Jun 2 18:55:15 2013 +0900

change README.md

GithubのWebページ上でも、識別番号の最初の一部分が掲載されている(赤線のところ)。
f:id:naoyashiga:20131122000725p:plain

質問:commitの識別番号は人間にとって識別しにくいのでは?

英数字の羅列だと、機械は各commitを識別できるけど、人間はわけわからなくなると思った。人間にわかりやすくする工夫はないのかと思って、Githubの中の人、ジョン(@)とマシュー(@)に聞いてみた。3つの工夫を教えてくれた。ありがとうございました!


親切な方が、質問をツイートして下さっていました。ありがとうございました。

工夫1:最初の4文字で検索

showコマンドを使う。

$ git show 0162
commit 0162e65afed22b9fbd4ef915d77f9f67a223f7ec
Author: naoyashiga
Date: Sun Jun 2 18:57:30 2013 +0900


4桁で一意に見つからなかったら、桁数を増やせばよい。今のところ最高8桁らしい。

工夫2:tagをつける

git tag tag-name 識別番号

上の要領でコマンドを入力する。

$ git tag v0.1 0162
$ git tag
v0.1
$ git show v0.1
commit 0162e65afed22b9fbd4ef915d77f9f67a223f7ec
Author: naoyashiga
Date: Sun Jun 2 18:57:30 2013 +0900

change README.md

識別番号が「0162」で始まるcommitに、「v0.1」というタグをつけた。showでタグ名を検索すれば、目的のcommit情報が表示される。


・参考
Git - タグ

工夫3:HEADコマンドを使う

HEADとは「今いるブランチの最新のコミット」のこと。詳しくは参考URLへ。

・参考
Git初心者に捧ぐ!Gitの「これなんで?」を解説します。 | KRAY Inc

$ git show HEAD
commit 0162e65afed22b9fbd4ef915d77f9f67a223f7ec
Author: naoyashiga
Date: Sun Jun 2 18:57:30 2013 +0900

change README.md

「今いるブランチの最新のコミット」を出力している。

$ git show HEAD^

さらに一つ遡るには「^」をつける。

$ git show HEAD^

二つ遡るには「^^」をつける。

$git show HEAD~2

「^^」は面倒でわかりにくいので、上のような書き方で代用できる。

番外編:commitの識別番号の仕組み

勉強会では取り上げられてなかったけど、気になるので自分で調べてみた。

どうやって識別番号を生成するの?

ハッシュを使う。ハッシュ関数の難しさは、重複なく一意にデータと数値を対応づけることにある。簡単なハッシュ関数は、入力データそのものをキーにすることである。

ハッシュ関数のアルゴリズムについての参考ページ
ハッシュ関数 - Wikipedia


commit識別番号には「SHA-1 ハッシュ」という方法で生成されている。

結論から言うと,Keyは(各ファイルに対するハッシュ値を統合したハッシュ値) + (当該コミットのAuthorやコミットメッセージを合わせたもの)になっているようです.
前者の統合されたハッシュ値はインデックス作成時に計算され,後者の情報はコミット時に取得されます.
どうやらコミットの度にファイルを全部なめてるわけではないようです.

参考ページを読んでみると、上のように書いてある。難しそうなのでこれ以上調べるのはやめる笑

SHA-1 ハッシュについての参考ページ
AdventCalendar - Gitのリビジョン番号(SHA-1のアレ)の正体をソースコードを読んで調べてみた - Qiita [キータ]

同じ識別番号になったらどうなるの?

同じになった場合は、最初のcommitが優先され、それ以外は無視される。

しかし参考ページを読んでみると、かぶる心配はしなくても良さそう。

SHA-1 ダイジェストの大きさは 20 バイト (160 ビット) です。ランダムなハッシュ値がつけられた中で、たった一つの衝突が 50% の確率で発生するために必要なオブジェクトの数は約 2^80 となります (衝突の可能性の計算式は p = (n(n-1)/2) * (1/2^160) です)。2^80 は、ほぼ 1.2 x 10^24 、つまり一兆二千億のそのまた一兆倍です。これは、地球上にあるすべての砂粒の数の千二百倍にあたります。

文学的な数値だ・・・。

・参考
Git - リビジョンの選択

f:id:naoyashiga:20131122012558j:plain
おまけ。ステッカーもらった。オードリーヘップバーンとスターウォーズの白い兵士(ストーム・トルーパー)。

いろんなOctcatが見ることができる。
OCTOCATS!
ストーム・トルーパー - Wikipedia