Gitファイル管理の詳細と知っておくべきコマンド

 

Gitサーバ構築と基本的なコマンド備忘録」でGit始めるに辺り、最低限のことを書きました。 私は、ソースコードのような大事なファイルを自分が理解していない仕組みに管理を任せるのがどうも怖くて、その詳細が気になってしまいます。ファイルが情報として管理されているのであれば、何処かにある規則に則って保管されているはずです。 今回は、その辺りを以前調べたことがあるので、思い起こして書いてみます。

Gitを知るには自由に弄る環境が必要と思いますので、そんな環境を自分で立ててみたい方は、「Gitサーバ構築と基本的なコマンド備忘録」から先にどうぞ。

■新リポジトリ作成

まずは、新しくローカルリポジトリを作成するところから。次のように作業ディレクトリを作り、新しくローカルリポジトリを作成してみます。

$ mkdir work
$ cd work
$ git init

workディレクトリに.git ディレクトリができていると思います。

[hoge@engineerspirit work]$ find .
.
./.git
./.git/info
./.git/info/exclude
./.git/description
./.git/HEAD
./.git/branches
./.git/config
./.git/refs
./.git/refs/tags
./.git/refs/heads
./.git/hooks
./.git/hooks/pre-applypatch.sample
./.git/hooks/pre-rebase.sample
./.git/hooks/prepare-commit-msg.sample
./.git/hooks/post-update.sample
./.git/hooks/post-commit.sample
./.git/hooks/update.sample
./.git/hooks/pre-commit.sample
./.git/hooks/post-receive.sample
./.git/hooks/commit-msg.sample
./.git/hooks/applypatch-msg.sample
./.git/objects
./.git/objects/info
./.git/objects/pack

まだ、何のファイルも管理にいれていない状態です。

■ローカルリポジトリ(作業ディレクトリ)でファイル作成

workの配下にtest.cというファイルを作成します。 まだ管理下に入ってないので、git status とコマンドを打つと、「管理に入っていないtest.cというファイルが存在します」のようなメッセージが表示されます。

$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
# (use “git add …” to include in what will be committed)
#
# test.c
nothing added to commit but untracked files present (use “git add” to track)

ローカルリポジトリにファイル追加 (git add)

では、ローカルリポジトリにaddしてみましょう。

$ git add test.c

addすると.gitディレクトリの下に新しく2つのファイルができています。

.git/index
.git/objects/e0/0d8fefa496b2e171d7ef07d0d63db821671a05

git addするとどうやら、そのファイルハッシュ値の一部をファイル名にして.git/objectsディレクトリの下にコピーするようです。また、ハッシュ値の先頭から2文字をディレクトリ名にしています。

■ファイルからハッシュ値を計算するには

もとのファイルからハッシュ値を計算するには hash-objectオプションを付けます。

$ git hash-object test.c
e00d8fefa496b2e171d7ef07d0d63db821671a05

■ファイルのハッシュ値から内容の確認

オブジェクト(objects)ディレクトリにコピーされたファイルは、cat-file -p [ハッシュ値]とするとハッシュ値に対するファイル内容が確認できます。

$ git cat-file -p e00d8fefa496b2e171d7ef07d0d63db821671a05

■ファイルハッシュ値からオブジェクトのタイプを確認

オブジェクトディレクトリに保存されるファイルは、次の3種類あるようです。

  • commit
  • tree
  • blob

cat-file -t [ハッシュ値] とするとそのハッシュ値に対応したタイプが表示されます。

$ git cat-file -t e00d8fefa496b2e171d7ef07d0d63db821671a05
blob

git add では、blobタイプのファイルが作成されることが分かります。 blobタイプのファイルには、管理対象ファイルの中身が圧縮されて入るようです。 commitとtreeについてはこの後に出てきます。

ローカルリポジトリでファイルをコミット (git commit -m”…”)

git addしたtest.cをコミットしてみます。 -m のあとのダブルクオート内にコミットした際のメッセージを記述します。 どのような変更があったか書いておくとよいでしょう。

$ git commit -m”test commit test.c” test.c

コミットすると .git ディレクトリに以下のファイルが追加になっていました。

.git/COMMIT_EDITMSG
.git/logs
.git/objects/1c/ce20c30d6765ea079a4a576a4f2bc1baf53aab
.git/objects/ff/ca01b651cad520deb1ab898349c94389dd1cff
.git/refs/heads/master

COMMIT_EDITMSGには、先ほどコミットした際のメッセージ”test commit test.c”が入っていました。 logsはディレクトリでした。 objectsフォルダに追加になった2つのファイルのタイプと中身を表示してみます。

$ git cat-file -t 1cce20c30d6765ea079a4a576a4f2bc1baf53aab
tree
$ git cat-file -p 1cce20c30d6765ea079a4a576a4f2bc1baf53aab
100644 blob e00d8fefa496b2e171d7ef07d0d63db821671a05 test.c

もう一方のファイルも。

$ git cat-file -t ffca01b651cad520deb1ab898349c94389dd1cff
commit
$ git cat-file -p ffca01b651cad520deb1ab898349c94389dd1cff
tree 1cce20c30d6765ea079a4a576a4f2bc1baf53aab
author hoge <hoge@engineerspirit.(none)> 1493706939 +0900
committer hoge <hoge@engineerspirit.(none)> 1493706939 +0900test commit test.c

treeとcommitタイプのファイルが追加になっていることが分かります。 treeタイプのファイルには、blobタイプのオブジェクトのファイル名とそのハッシュ値を持っているようです。つまりディレクトリのような感じです。commitタイプのファイルには、treeのハッシュ値と作者、コミッターとコミットした際のメッセージが入っています。 ※treeタイプの内容を確認するには、git ls-tree [ハッシュ値] でもOKですね。

分かったこと

以上のようなファイルを追加しては、コミットして.gitディレクトリにどのような変更があり、その変更内容を確認していくとGitのファイル管理構造がそれなりに分かりました。 ファイルを追加・変更してコミットしていく毎にそのコミットにユニークなハッシュ値(sha1)が作成されます。 そのコミットに紐付いたtreeでその配下のディレクトリ(tree)やファイル(blob)を辿っていけるような構造になっているようです。 既にGitを使ってる方は知っている内容だったかもしれませんが、私の備忘録でした。

  • このエントリーをはてなブックマークに追加
  • Pocket

この記事へのコメントはこちら