ログ日記

作業ログと日記とメモ

gitのソースコードを読む

C言語の書き方を調べていて、やはりここは何かのソースを読むべきだと思ってgitを読むことにした。


http://cdn8.atwikiimg.com/git_jp/pub/git-manual-jp/Documentation/chunked/ch10s02.html
ここも参考にしつつ。


https://github.com/git/git ここからソースを取ってきて取りあえず

git checkout e83c5163

を実行する。

zsh % wc -l *.[hc]
   93 cache.h
   23 cat-file.c
  172 commit-tree.c
   51 init-db.c
  259 read-cache.c
   43 read-tree.c
   81 show-diff.c
  248 update-cache.c
   66 write-tree.c
 1036 合計

これなら全てのファイルを読める。


最初のバージョンの使い方

zsh % make

zsh % ./init-db
zsh % ./update-cache README
zsh % ./write-tree
cdad72b321282004f373339d2700847b96be7de3
zsh % echo "first commit" | ./commit-tree cdad72b321282004f373339d2700847b96be7de3
Committing initial tree cdad72b321282004f373339d2700847b96be7de3
362aabbed1eb2033282d8035837d5f4292572381


zsh % find .dircache/ -type f
.dircache/index
.dircache/objects/cd/ad72b321282004f373339d2700847b96be7de3
.dircache/objects/36/2aabbed1eb2033282d8035837d5f4292572381
.dircache/objects/66/5025b11ce8fb16fadb7daebf77cb54a2ae39a1

このファイルはzlib圧縮されていて直接読めないので http://www.zlib.net/zpipe.c これを取ってきて読む。

zsh % zpipe -d < .dircache/objects/cd/ad72b321282004f373339d2700847b96be7de3   
tree 34100644 READMEfP%&#65533;&#65533;&#65533;&#65533;&#65533;}&#65533;&#65533;w&#65533;T&#65533;&#65533;9&#65533;%



zsh % zpipe -d < .dircache/objects/36/2aabbed1eb2033282d8035837d5f4292572381 
commit 197tree cdad72b321282004f373339d2700847b96be7de3
author nishimura,,, <nishimura@menomosso> Thu Sep  5 19:27:02 2013
committer nishimura,,, <nishimura@menomosso> Thu Sep  5 19:27:02 2013

first commit


zsh % zpipe -d < .dircache/objects/66/5025b11ce8fb16fadb7daebf77cb54a2ae39a1
blob 8392^@
        GIT - the stupid content tracker

"git" can mean anything, depending on your mood.

...

最初のファイルが文字化けしているので16進数表示する。

zsh % zpipe -d < .dircache/objects/cd/ad72b321282004f373339d2700847b96be7de3 | od -t x -c
0000000        65657274        00343320        36303031        52203434
          t   r   e   e       3   4  \0   1   0   0   6   4   4       R
0000020        4d444145        50660045        e81cb125        dbfa16fb
          E   A   D   M   E  \0   f   P   % 261 034 350 373 026 372 333
0000040        77bfae7d        aea254cb        0000a139
          } 256 277   w 313   T 242 256   9 241
0000052

emacsのhexl-modeの方が分かりやすいかも。
形式は

種類(commit, tree, blob) [スペース] サイズ [\0] モード [スペース] ファイル名 [\0] 0x665025b1...

だと分かる。

zsh % ./cat-file cdad72b321282004f373339d2700847b96be7de3
temp_git_file_dIoMiK: tree

zsh % ./read-tree cdad72b321282004f373339d2700847b96be7de3
100644 README (665025b11ce8fb16fadb7daebf77cb54a2ae39a1)

cat-file はこの時点ではデータを表示するのではなくて一時ファイルに書き出すようだ。


大体の流れが分かってきたところで、コミットを少し進める。

zsh % make clean

zsh % git checkout 7fa6b4e

zsh % wc -l *.[hc]
   24 blob.c
   14 blob.h
  128 cache.h
   45 cat-file.c
   47 check-files.c
  183 checkout-cache.c
  363 commit-tree.c
   85 commit.c
   27 commit.h
  204 diff-tree.c
  171 fsck-cache.c
   56 init-db.c
  114 ls-tree.c
   92 merge-base.c
  106 merge-cache.c
   96 object.c
   29 object.h
  259 read-cache.c
  260 read-tree.c
  145 rev-tree.c
  164 revision.h
  247 sha1_file.c
  212 show-diff.c
  193 show-files.c
   67 tree.c
   17 tree.h
   34 unpack-file.c
  338 update-cache.c
   40 usage.c
  130 write-tree.c
 3890 合計

55979コミット中の153コミット目なので、まだまだ初期。

zsh % make

エラーが出たのでcommit.cに #include を追加して再make。

zsh % ./update-cache COPYING
fatal: unable to create new cachefile

ローカルDBディレクトリが.gitになった。

zsh % mv .dircache/ .git
zsh % ./update-cache COPYING
error: bad signature
error: verify header failed
fatal: cache corrupted

indexが違ってダメぽい。他にもコマンドが多少変わっている。


作り直す。

zsh % rm -rf .git/
zsh % ./init-db
zsh % ./update-cache --add README
zsh % echo test1 > test.txt
zsh % ./update-cache --add test.txt
zsh % ./write-tree
1afff28ca8fdf94d4dd43e4f61391f3ae36c5d95

zsh % echo "first commit" | ./commit-tree 1afff28ca8fdf94d4dd43e4f61391f3ae36c5d95 > .git/HEAD
Committing initial tree 1afff28ca8fdf94d4dd43e4f61391f3ae36c5d95


zsh % ./update-cache --add COPYING
zsh % echo test2 >> test.txt
zsh % ./update-cache test.txt

zsh % ./write-tree
8a235d62917e5769dd91a55277a2a0f0d213ce3f

zsh % echo "second commit" | ./commit-tree 8a235d62917e5769dd91a55277a2a0f0d213ce3f -p $(cat .git/HEAD) > .git/HEAD 


zsh % ./cat-file commit $(cat .git/HEAD)
tree 8a235d62917e5769dd91a55277a2a0f0d213ce3f
parent ef1faf1165edb8de9fda4f948fc73b5e6fea7719
author nishimura <nishimura@menomosso.(none)> 1378378730 +0900
committer nishimura <nishimura@menomosso.(none)> 1378378730 +0900


zsh % find .git/ -type f
.git/index
.git/HEAD
.git/objects/8a/235d62917e5769dd91a55277a2a0f0d213ce3f
.git/objects/ef/1faf1165edb8de9fda4f948fc73b5e6fea7719
.git/objects/65/212d3324a089abd0b9ef62f5867ac7c44fc268
.git/objects/1a/fff28ca8fdf94d4dd43e4f61391f3ae36c5d95
.git/objects/fe/2a4177a760fd110e78788734f167bd633be8de
.git/objects/0c/8f66a82ac03c86646d8a5538f7ace811d83417
.git/objects/67/9bab7e4796f7e8befb71363bfc53eda778dcb5
.git/objects/b9/ea68dc9f9a51c759b056aaa895ca6176e963e9
.git/objects/f4/3d04b5d74afebc5e8aa2ae2452fbbe034299ac


zsh % ./ls-tree 8a235d62917e5769dd91a55277a2a0f0d213ce3f
100644	blob	fe2a4177a760fd110e78788734f167bd633be8de	COPYING
100644	blob	0c8f66a82ac03c86646d8a5538f7ace811d83417	README
100644	blob	679bab7e4796f7e8befb71363bfc53eda778dcb5	test.txt

gitの一番最初のコミットと現在のバージョンでデータの内部構造がほとんど変わっていないのがすごい。



ソースコードの中身をメモしていこうと思っていたけど、初期gitの使い方メモになってしまった。