LoginSignup
9
9

More than 5 years have passed since last update.

Git の内部構造 - Objects

Last updated at Posted at 2015-07-23

Pro Git - 10.2 Git Internals - Git Objects を読んだメモ。

.git/objects は key value ストア。キーは SHA1 ハッシュ。上 2 桁がディレクトリ名、それ以降がファイル名。値には以下の種類がある。

  • blob: ファイルの中身。
  • tree: tree, blob の一覧。それらの名前やパーミッションなどを持っている。
  • commit: いわゆるコミット。親コミット、tree、日時やコミットした人などを持っている。

コミットの SHA1 ハッシュはコミットだけのものではなく、ファイルの中身やディレクトリ構成も持っているのだった。.git/objects を覗いてみたところ、ファイルの内容を差分じゃなくてそのまま全部持っているように見える。どうなっているんだろう?(Packfiles に書いてあるっぽい。)

Object ファイルの中身

Ruby で書くと blob の場合はこんな感じ。

type = 'blob'
content = 'hello, world!'

header = "#{type} #{content.size}\0"
store = header + content

file_name = Digest::SHA1::hexdigest(store)
file_content = Zlib::Deflate.deflate(store)

ローレベルなコマンド

  • git hash-object: write an object to the key value store?
  • git cat-file: read an object from the key value store
  • git update-index: add file or data from tree to index
  • git write-tree: write data on index to tree
  • git read-tree: read data from tree and add it to index
  • git commit-tree: make a commit with tree

やってみた

$ cat .git/HEAD
ref: refs/heads/master
$ cat .git/refs/heads/master
2420f123e6963ba7f4bbf269ccd855010ff9c324
$ cat .git/objects/24/20f123e6963ba7f4bbf269ccd855010ff9c324
****

バイナリなのでよくわかりません。git cat-file で中身を見ます。

$ git cat-file -t 2420f123e6963ba7f4bbf269ccd855010ff9c324
commit
$ git cat-file -p 2420f123e6963ba7f4bbf269ccd855010ff9c324
tree 75b1c654dbe7baa6c28d5e31b369bdc663cc36e8
parent 251c63a932f2f1681345a584ef0f8ac67538e057
author Shuhei Kagawa <shuhei.kagawa@gmail.com> 1437581686 +0900
committer Shuhei Kagawa <shuhei.kagawa@gmail.com> 1437581686 +0900

Implement Huffman coding for hierarchical softmax.

コミットでした。そのコミットの中身は tree で表現されているようです。

$ git cat-file -p 75b1c654dbe7baa6c28d5e31b369bdc663cc36e8
100644 blob 8ee1bf9489a3223e94d55bf46fcfed98bdbf38c2    .gitignore
100644 blob c1f4f2fb6d3479db059139ac62a66bde8d96f5ea    LICENSE
100644 blob d585d0c7ff977a7c30758ad1d95967de7838d98b    README.md
100644 blob 9a994af677b0dfd41b4e3b76b3e7e604003d64e1    Setup.hs
040000 tree e6d14e6e74b8434223600b64f90016023b11fd58    app
040000 tree ba4215e8cc5450ba64beb73e97834efdd1b0cc69    src
100644 blob 4d231cdcf36997b97a2a54bc02fd857ab36680e3    stack.yaml
040000 tree 0d4a53b6a6584fadf889c9b1ccafbd5445b73e4a    test
100644 blob 1614394782333d44c4da2a5013ece2a29bd8bc32    wv.cabal

wv.cabal を見てみます。

$ git cat-file -p 1614394782333d44c4da2a5013ece2a29bd8bc32
name:                wv
version:             0.1.0.0
synopsis:            Initial project template from stack
description:         Please see README.md
...

Q. diff でなく、ファイルの内容が全部入っている?よくわからない。

ディレクトリは tree で表現されているようです。

$ git cat-file -t e6d14e6e74b8434223600b64f90016023b11fd58
tree
$ git cat-file -p e6d14e6e74b8434223600b64f90016023b11fd58
100644 blob fdcefe22a449011b0c1944d088b6265370d089b4    Main.hs
9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9