sato.masaki

2014.12.09

Gitの中身を見てみよう!vol.1 – 配管(Plumbing)と磁器(Porcelain)(Advent Calendar 9日目)

こんにちは。アドベントカレンダー9日目を担当する佐藤(ま)です。
アライドでは「大佐」と呼ばれております。

今回から git-scm.com をみながら Git (.git) の中身をみていってみようと思います。(まぁ他にもいろいろ記事はありますが書きたかったので気にせず垂れ流していこうと思います。)現在の Document には、v1v2 がありますが、v2 は途中まで日本語化されていて、日本語で見たい方はこちらに参考サイトがあります。(もちろん英語のままでもだいじょうぶですが)

配管(Plumbing)と磁器(Porcelain)

そもそも Git には大きく配管(Plumbing)コマンドと磁器(Porcelain)コマンドがあり、普段良く使うコマンドは、ユーザフレンドリーなコマンドとして、磁器(porcelain)コマンドとよばれ、下位レベルの仕事を行うためのコマンドが、配管(Plumbing)コマンドと呼ばれます。

配管(Plumbing)コマンドは、

Gitの内部動作にアクセスして、Gitの内部で、何を、どのように、どうして行うのかを確かめるのに役に立つ

9.1 Gitの内側 – 配管(Plumbing)と磁器(Porcelain) より

ということなので、今回からは配管(Plumbing)コマンドを使っていくことになります。コマンドリファレンスでいうところの、こちら↓になります。

Screen_Shot_2014-11-22_at_13_25_25

では早速上記 Document を元に .git の中身をみていこうと思います。

git init を実行した直後のデフォルトリポジトリ

まず、git リポジトリを初期化した直後の .git 内の構成を確認してみます。

HEAD ファイル

現在チェックアウトしているブランチ

中は以下のように書かれています。

config ファイル

自分のプロジェクト固有の設定オプション

remote 情報などはここに記載されます。

description ファイル

GitWeb プログラムのみで使用

hooks ディレクトリ

クライアントサイド、またはサーバサイドのフックスクリプトが含まれる。

hooks の下は、以下のようにサンプルスクリプトが用意されているので利用する際は、.sample をコピーして使ったりします。フックについては、こちら(7.3 Git のカスタマイズ – Git フック) に詳細が書かれています。

info ディレクトリ

追跡されている .gitignore ファイルには記述したくない無視パターンを書くための、グローバルレベルの除外設定ファイルを保持する。

.gitignore で共有したくなく、自分のローカル環境でのみ無視したい場合に使えます。

objects ディレクトリ

データベースのすべてのコンテンツを保管

refs ディレクトリ

ブランチ内のコミットオブジェクトを指すポインターを保管

index ファイル

Git がステージングエリアの情報の保管する場所を示す
※ 初期化時には作成されない

中でもGit の中核(コア)部分に相当するのが、HEAD,objects,refs,indexで、これらが .git の中でも重要なエントリとなります。

Git は連想記憶ファイル・システム

Git は連想記憶ファイル・システムです。素晴らしい。…で、それはどういう意味なのでしょう?それは、Git のコアの部分が単純なキーバリューから成り立つデータストアである。

9.2 Gitの内側 – Gitオブジェクト より

記述にあるように、Git が単純なキーバリューストアであるというのを簡単に確認してみようと思います。

hash-object コマンド

hash-object コマンドでは、.git/objects/ ディレクトリに、オブジェクトを格納することができます。まず、.git/objects ディレクトリに移動してみると空の info と pack が存在しているのがわかります。

そこで以下のコマンドを発行すると、40文字から成るチェックサムのハッシュ値が出力されます(SHA-1ハッシュ)。サブディレクトリは、SHA-1ハッシュのはじめの2文字で名付けられ、残りの38文字でファイル名が決まります。

d6 と 70460b4b4aece5915caf5c68d12f560a9fe3e4 を合わせると40文字となります。

cat-file コマンド

cat-file コマンドは、格納したオブジェクトのコンテンツを Git の外に引き出すことができます。

hash-object コマンドで Git にコンテンツを追加し、cat-file でそれを出力しました。

では、これらを使って、あるファイルのバージョン管理の動作を確認してみようと思います。

test.txt ファイルに version 1 と version 2 を書き込みましたが、objects ディレクトリ配下にデータを保持しているので、ファイルを最初のバージョンにしたり、2つ目のバージョンにしたり切り替えることができます。

オブジェクトのタイプ

また、cat-file -t コマンドに SHA-1キーを渡すことで、あなたは Git 内にあるあらゆるオブジェクトのタイプを問い合わせることができます。

9.2 Gitの内側 – Gitオブジェクト より

これらのオブジェクトにはタイプがあり、今回作成したオブジェクトは、バイナリデータを扱うデータ型である blob となります。

オブジェクトのタイプは他にも存在しますが、次回以降に確認してみようと思います。

今回 git-csm.com の Documentをみながら確認していきましたが、結果的にほとんど Document の内容をなぞる形になってしまいました。ただ、読むだけじゃなくて、読みながら色々試したりしたことで Git の仕組みへの理解が深まりましたので、興味のある方は是非試してみてください。

明日は、 sekine の番です。