Dec 11, 2010

git object

git 裡,所有的檔案、文件與資料匝都是以 hash 來表示"身份" (object),而 hash 是使用 SAH1,這樣每一個 object 幾呼是唯一性的。git 中所謂的 object 指的是,content 本身加上 hash,而 content 分為下面四種 blob, tree, commit, and tag.
blob : the data is the contents of a file
tree : To store a directory, Git writes out an object describing the directory's contents

實際測試看看 :
$ echo "hello" > hello
$ git add .
$ git commit -am 'hello'
[master (root-commit) 21039e0] hello
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 hello

$ mkdir foo
$ echo "bar" > foo/bar
$ echo "world" >> hello
$ git add .
$ git commit -am 'foo/bar and hello world'
[master ab4c151] foo/bar and hello world
2 files changed, 2 insertions(+), 0 deletions(-)
create mode 100644 foo/bar

$ git log
commit ab4c151820a51da73eb00381472a4774475bcf66
Author: Yao-Po Wang
Date: Sat Dec 11 16:07:27 2010 +0800

foo/bar and hello world

commit 21039e0f12ebf539275346566982566c3bcd9217
Author: Yao-Po Wang
Date: Sat Dec 11 16:06:32 2010 +0800

hello

利用 git cat-file 來得到更多資訊
git-cat-file - Provide content or type and size information for repository objects
Option:
-t : show the object type.
-s : show the object size.
-p : Pretty-print based on its type.


$ git cat-file -t 21039
commit

$ git cat-file -s ab4c1
234

$ git cat-file -s 21039
168

可利用 -p or commit 來提到,此 commit 的 tree object
$ git cat-file commit 21039
$ git cat-file -p 21039
tree b4d01e9b0c4a9356736dfddf8830ba9a54f5271c
author Yao-Po Wang 1292054792 +0800
committer Yao-Po Wang 1292054792 +0800

hello

從上面,我們可以得到 commit 的 tree object 利用 tree object 可得知,在這個 commit 的情況下目錄包含的
git ls-tree - List the contents of a tree object
$ git ls-tree 21039e0
100644 blob ce013625030ba8dba906f756967f9e9ca394464a hello

$ git ls-tree ab4c151
040000 tree ee314a31b622b027c10981acaed7903a3607dbd4 foo
100644 blob 94954abda49de8615a048f8d2e64b5de848e27a1 hello

$ git ls-tree -r ab4c151 <-- recurse 100644 blob 5716ca5987cbf97d6bb54920bea6adde242d87e6 foo/bar 100644 blob 94954abda49de8615a048f8d2e64b5de848e27a1 hello


從 git ls-tree 我們可以知道,tree 下所有的 blob (補 SHA-1 的 content), 利用 cat-file blob 就可得知在些 commit 下的 blob 的內容
$ git cat-file -p ce0136
hello

$ git cat-file blob 94954
hello
world

到這裡,因該可以大約的知道, 放在 git 裡的檔案是如果被儲存與 object 的架構, 而這些 object 是被存放在 .git/objects 下
$ tree .git/objects/
.git/objects/
├── 21
│   └── 039e0f12ebf539275346566982566c3bcd9217
├── 55
│   └── 9dbaeba4c3e2fff4ac4bf4323b13a5ed1616c7
├── 57
│   └── 16ca5987cbf97d6bb54920bea6adde242d87e6
├── 94
│   └── 954abda49de8615a048f8d2e64b5de848e27a1
├── ab
│   └── 4c151820a51da73eb00381472a4774475bcf66
├── b4
│   └── d01e9b0c4a9356736dfddf8830ba9a54f5271c
├── ce
│   └── 013625030ba8dba906f756967f9e9ca394464a
├── ee
│   └── 314a31b622b027c10981acaed7903a3607dbd4
├── info
└── pack

10 directories, 8 files