2017/12/12更新

[git] Gitの内部(データ格納 - コミットオブジェクト)

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

こんにちは、@yoheiMuneです。
今日も引き続き、Gitのデータ格納について扱いたいと思います。本日はコミットオブジェクトです。

画像

Special Thanks to http://flic.kr/p/6r2wNh



この記事を読む前に

この記事は、Gitの内部やデータ格納方法について書かれた、以下の記事の続きとして書いています。 以下の記事を先にお読み頂くと、今回の記事をより理解頂けるのではないかと思います。

Gitの内部(はじめに) Gitの内部(データ格納 - データオブジェクト) Gitの内部(データ格納 - ツリーオブジェクト)


この記事で伝えたいこと

この記事では、コミットオブジェクトとは何か、を説明します。 この記事を読む事で、Gitのコミットがどのようなデータで成り立っているのか、を理解できると思います。



コミットオブジェクト

この記事は、前々回前回で作成したgitレポジトリを利用します。

データオブジェクトやツリーオブジェクトを扱うことができるようになりましたが、いまのところ、それらの中から特定のデータにアクセスするためにSHA-1のハッシュ値を利用する必要があります。 このハッシュ値はランダム文字列で、覚えられるような代物ではありません。 またツリーオブジェクトは、誰がいつ作成したのか、といった情報も持っておらず、誰がどのような意図で作成したのか、を知る術がありません。

そこで登場するのがコミットオブジェクトです。 コミットオブジェクトでは、ツリーオブジェクト(ある特定の状況におけるスナップショット)への参照と、誰がいつコミットしたのかといった情報を、保持することができます。

コミットオブジェクトを作成するには、参照する1つのツリーオブジェクトと、(もし存在すれば)直前のコミットの情報を指定する必要があります。 コミットオブジェクトの作成には、git commit-treeという内部コマンドを利用します。まずは、d8329fツリーを参照する、最初のコミットを作成してみましょう。
$ echo 'first commit' | git commit-tree d8329f
fdf4fc3344e67ab068f836878b6c4951e3b15f3d
作成したコミットオブジェクトの中身を、git cat-fileで見ることができます。
$ git cat-file -p fdf4fc3
tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579
author Munesada Yohei <y.munesada@gmail.com> 1393845711 +0900
committer Munesada Yohei <y.munesada@gmail.com> 1393845711 +0900

first commit
コミットオブジェクトの中身が表示されました。参照しているツリーオブジェクト、作成者(author)、コミットした人(committer)、コミットコメントが表示されていることが分かります。

さらに続いて、2つのコミットを作成しましょう。
$ echo 'second commit' | git commit-tree 0155eb -p fdf4fc3
cac0cab538b970a37ea1e769cbbde608743bc96d

$ echo 'third commit'  | git commit-tree 3c4e9c -p cac0cab
1a410efbd13591db07496601ebc7a059dd55cfe9
今回のコミットでは、-pオプションの後に、直前のコミットのハッシュ値を指定しています。 これによりコミットの前後のつながりを作ることができます。 作成したコミットを、git logで確認することができます。
$ git log --stat 1a410e
commit 1a410efbd13591db07496601ebc7a059dd55cfe9
Author: Munesada Yohei <y.munesada@gmail.com>
Date:   Mon Mar 3 18:15:24 2014 +0900

    third commit

 bak/test.txt |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

commit cac0cab538b970a37ea1e769cbbde608743bc96d
Author: Munesada Yohei <y.munesada@gmail.com>
Date:   Mon Mar 3 18:14:29 2014 +0900

    second commit

 new.txt  |    1 +
 test.txt |    2 +-
 2 files changed, 2 insertions(+), 1 deletions(-)

commit fdf4fc3344e67ab068f836878b6c4951e3b15f3d
Author: Munesada Yohei <y.munesada@gmail.com>
Date:   Mon Mar 3 18:09:34 2014 +0900

    first commit

 test.txt |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
Gitのaddcommitといったコマンドを使わなくても、Gitの履歴を構築することができました。 このように、コミットオブジェクトは、ツリーオブジェクトや直前のコミット、作成者やコミッター、コミットメッセージ、といった情報を保持します。

今までに作成したGitのデータを確認してみましょう。
$ find .git/objects -type f
.git/objects/01/55eb4229851634a0f03eb265b69f5a2d56f341
.git/objects/1a/410efbd13591db07496601ebc7a059dd55cfe9
.git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a
.git/objects/3c/4e9cd789d88d8d89c1073707c3585e41b0e614
.git/objects/83/baae61804e65cc73a7201a7252750c76066a30
.git/objects/ca/c0cab538b970a37ea1e769cbbde608743bc96d
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4
.git/objects/d8/329fc1cc938780ffdd9f94e0d364e0ea74f579
.git/objects/fa/49b077972391ad58037050f2a75f74e3671e92
.git/objects/fd/f4fc3344e67ab068f836878b6c4951e3b15f3d
なんのこっちゃ分かりませんね。コメントを付与してみると、以下の感じです。
$ find .git/objects -type f
.git/objects/01/55eb4229851634a0f03eb265b69f5a2d56f341 # tree 2
.git/objects/1a/410efbd13591db07496601ebc7a059dd55cfe9 # commit 3
.git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a # test.txt v2
.git/objects/3c/4e9cd789d88d8d89c1073707c3585e41b0e614 # tree 3
.git/objects/83/baae61804e65cc73a7201a7252750c76066a30 # test.txt v1
.git/objects/ca/c0cab538b970a37ea1e769cbbde608743bc96d # commit 2
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 # 'test content'
.git/objects/d8/329fc1cc938780ffdd9f94e0d364e0ea74f579 # tree 1
.git/objects/fa/49b077972391ad58037050f2a75f74e3671e92 # new.txt
.git/objects/fd/f4fc3344e67ab068f836878b6c4951e3b15f3d # commit 1
今までに作成した、データオブジェクト、ツリーオブジェクト、コミットオブジェクトが格納されていることが分かります。 Gitはこれらの3種類のデータを主に使って、データ管理を行います。上記のオブジェクトを図示すると、以下のようになります。
画像

引用:http://git-scm.com/book/en/Git-Internals-Git-Objects




最後に

今回はコミットオブジェクトについて扱いました。 前々回前回で扱ったデータオブジェクトやツリーオブジェクトも含め、これら3種類のデータで、Gitのデータ管理が行われています。すごくシンプルな仕組みですね。
今後もGitの内部動作について、ブログを書ければと思います(フロントエンドなネタも書く意気込みです!!)。

最後までご覧頂きましてありがとうございました。





こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。