2010-01-19

Git の根本

Git の SHA-1 名のことを調べていたら Git の根本について書いてあったのでまとめておく.簡単のため正確さを犠牲にしているので注意.

オブジェクト

Git のオブジェクトは,(type, length) というヘッダと,データ部分をつなげたバイナリである.このバイナリから SHA-1 ハッシュを計算して得られた 160 bit の値(表記は 40 桁の 16 進数)を名前とする.

オブジェクトには以下のものがある.

blob. これはファイルを表す.データ部分はファイルの内容そのものである.

tree. これはディレクトリを表す.データ部分は (type, name, object) をレコードとするリストで,name でソートされている.type に blob と tree とを取ることによりディレクトリツリーを表現できる.

commit. これはあるディレクトリツリーから別のディレクトリツリーへの変更を表す.データ部分は (before-tree, after-tree, time, author) である.

オブジェクトデータベースとリファレンス

これらのオブジェクトは全て .git/objects に格納されている.この中から所望のデータを取り出す手がかりが必要だが,それらは .git/refs/heads に commit オブジェクトの SHA-1 名を内容とするファイルとして格納されている.これらを,そのファイル名を名前とするブランチと呼ぶ.

その他

  • .git/objects に格納されているオブジェクトの名前は,ディレクトリ名とファイル名をつなげたものである.例えばオブジェクト .git/objects/4d/97bf636e78366658f2aaa80389c581e4cee9c0 の名前は 4d97bf636e78366658f2aaa80389c581e4cee9c0.
  • オブジェクトの情報,内容を表示するにはコマンド git show を用いる.
  • blob の定義から,同一内容を持つファイルのオブジェクトの SHA-1 名は常に同じとなる.
  • commit オブジェクトの before-tree は複数存在する場合がある.merge した場合におきるが,conflict のない merge の場合などには複数にならないこともあって正確にはまだよくわからない.→ git merge --squash とすると merge しても before-tree が複数にならないことが判明 hmmm...
    • 著者 JCH さんのコメントにより判明.「conflict のない merge の場合など...」は fast-forward のケースで,この場合には merge-commit とならず before-tree が複数にならない.
    • merge --squash は man git-merge の当該項目に記述してあるとおり merge-commit とならない仕様である.

情報源

入門Git pp. 8--19

0 件のコメント:

コメントを投稿