Pro Yearly is on sale from $80 to $50! »

動かして理解するGitの内側

 動かして理解するGitの内側

2019.05.18 未来大×企業エンジニア 春のLT大会 発表スライド

8db1f2958e24accef8412659656fc8dc?s=128

Atsuya Sato

May 18, 2019
Tweet

Transcript

  1. 動かして理解する Gitの内側 @natmark / Cookpad Inc. 2019.05.18 未来大×企業エンジニア 春のLT大会

  2. 始める前に 「動かして覚える」なので、手元にGitの実 行環境がある方はスライドを見ながら
 コマンドを叩くと面白いかも?
 (一緒に動かす場合は、gitとzlibを
 インストールしておいてください) 
 10分しかないので、LTは割と早口です

  3. 佐藤 敦也 さとう あつや クックパッド株式会社 買物事業部 エンジニア 未来大卒業生(2018年度) / 松原克弥研究室

    !O@BUNBSL !OBUNBSL
  4. Git使ったことありますか?"

  5. Gitとは • 一言で言うと
 「分散型バージョン管理システム」 (使ったことない人が多かった時用の説明資料) 分散型の説明は省きます

  6. バージョン管理とは (使ったことない人が多かった時用の説明資料)

  7. バージョン管理とは (使ったことない人が多かった時用の説明資料) どれが最新なの…

  8. Gitを使うと (使ったことない人が多かった時用の説明資料) フォルダには最新 のファイルだけ

  9. Gitを使うと (使ったことない人が多かった時用の説明資料) 変更の履歴を 確認できる

  10. Gitを使うと (使ったことない人が多かった時用の説明資料) 変更差分が見れる

  11. Gitは差分情報を保存しておいて、 差分情報からバージョン管理が できる便利なやつ!!!

  12. None
  13. 果たして、これは本当にそうなのだろうか?

  14. 動かして理解する Gitの内側 (ここから本番)

  15. (ちなみに) .git の中を 覗いたことがある人"

  16. Gitのリポジトリを作る $ mkdir git-inside-workshop $ cd git-inside-workshop $ git init

    Initialized empty Git repository in /Users/atsuya-sato/ Desktop/git-inside-workshop/.git/ $ ls -a . .. .git
  17. .gitを覗いてみる $ cd .git $ ls -a . .. HEAD

    config description hooks info objects refs
  18. .gitを覗いてみる $ cd .git $ ls -a . .. HEAD

    config description hooks info objects refs いろいろでてきた わからん!
  19. .gitをGit管理する $ pwd /Users/atsuya-sato/Desktop/git-inside-workshop/.git $ git init Initialized empty Git

    repository in /Users/atsuya-sato/ Desktop/git-inside-workshop/.git/.git/
  20. git initの生成物をCommit $ git status On branch master No commits

    yet Untracked files: (use "git add <file>..." to include in what will be committed) HEAD config description hooks/ info/ nothing added to commit but untracked files present (use "git add" to track)
  21. git initの生成物をCommit $ git add . $ git commit -m

    “Initial Commit” [master (root-commit) 7349f42] Initial Commit 15 files changed, 655 insertions(+) create mode 100644 HEAD create mode 100644 config create mode 100644 description create mode 100755 hooks/applypatch-msg.sample create mode 100755 hooks/commit-msg.sample create mode 100755 hooks/fsmonitor-watchman.sample create mode 100755 hooks/post-update.sample create mode 100755 hooks/pre-applypatch.sample create mode 100755 hooks/pre-commit.sample create mode 100755 hooks/pre-push.sample create mode 100755 hooks/pre-rebase.sample create mode 100755 hooks/pre-receive.sample create mode 100755 hooks/prepare-commit-msg.sample create mode 100755 hooks/update.sample create mode 100644 info/exclude
  22. 1. git addで 何が起きているのか

  23. git addで何が起きているのか? $ echo “Hello World” > hello.txt On branch

    master Untracked files: (use "git add <file>..." to include in what will be committed) hello.txt nothing added to commit but untracked files present (use "git add" to track) $ git status $ pwd /Users/atsuya-sato/Desktop/git-inside-workshop/ $ cd ../
  24. git addで何が起きているのか? $ git add hello.txt $ cd .git $

    git status -uall On branch master Untracked files: (use "git add <file>..." to include in what will be committed) index objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238 nothing added to commit but untracked files present (use "git add" to track)
  25. git addで何が起きているのか? • hello.txtをgit addしたことによって ‣objects/ 55/7db03de997c86a4a028e1ebd3a1ceb22 5be238 ‣index •

    の2つのファイルが生成されたことが分かった
  26. objects/ 55/7db03de997c86a4a028e1eb d3a1ceb225be238 とは一体なんなのだろうか

  27. objects/の正体 • objects/ の正体はGitオブジェクトと呼ばれるもの • Gitオブジェクトのヘッダ部とデータ部に対してSHA-1の チェックサムを用いたファイル名で格納する(SHA-1ハッ シュの初めの2文字がサブディレクトリ・残りの38文字を ファイル名とする) ‣Gitオブジェクトのチェックサムが

    557db03de997c86a4a028e1ebd3a1ceb225be238 
 の場合 ‣objects/55/7db03de997c86a4a028e1ebd3a1ceb
 225be238 
 に保存される
  28. objects/の正体 • objects/ の正体はGitオブジェクトと呼ばれるもの • GitはGitオブジェクトとして以下のオブジェクト を生成する ‣blobオブジェクト ‣treeオブジェクト ‣commitオブジェクト(tagオブジェクト)

  29. blobオブジェクト • ファイルのデータそのもの • ファイル名や属性は含まれない

  30. treeオブジェクト • フォルダ構造を表す • treeオブジェクトは以下のようなものを持つ ‣ファイルの属性 ‣blobオブジェクト(サブフォルダが存在する場 合はtreeオブジェクト)への参照 ‣ファイル名

  31. blobとtreeの関係 . ├── new.txt ├── test.txt └── bak └── test.txt

  32. commitオブジェクト • git commitした時のCommit情報 • commitオブジェクトが持つものは ‣親commitへの参照 ‣トップレベルのtreeへの参照 ‣コミットしたユーザーの情報 ‣タイムスタンプ

    ‣コミットメッセージ
  33. commitとblobとtreeの関係

  34. objects/55/7db03de997c86a4a0
 28e1ebd3a1ceb225be238 を詳しく見てみる

  35. objects/ 55/7db03de997c86a4a028e1ebd3a1ceb225be238 を詳しく見てみる $ pwd /Users/atsuya-sato/Desktop/git-inside-workshop/.git $ cat objects/55/7db03de997c86a4a028e1ebd3
 a1ceb225be238

    xKOR04bH/IAI%
  36. objects/ 55/7db03de997c86a4a028e1ebd3a1ceb225be238 を詳しく見てみる $ pwd /Users/atsuya-sato/Desktop/git-inside-workshop/.git $ cat objects/55/7db03de997c86a4a028e1ebd3
 a1ceb225be238

    xKOR04bH/IAI% なんだこれは…
  37. objects/ 55/7db03de997c86a4a028e1ebd3a1ceb225be238 を詳しく見てみる $ cat objects/55/7db03de997c86a4a028e1ebd3a1
 ceb225be238 $ zlib -d

    < objects/55/7db03de997c86a4a028e1eb
 d3a1ceb225be238 xKOR04bH/IAI% blob 12Hello World
  38. objects/ 55/7db03de997c86a4a028e1ebd3a1ceb225be238 を詳しく見てみる $ cat objects/55/7db03de997c86a4a028e1ebd3a1
 ceb225be238 $ zlib -d

    < objects/55/7db03de997c86a4a028e1eb
 d3a1ceb225be238 xKOR04bH/IAI% blob 12Hello World 実はzlibで 圧縮されている 中身が出てきた
  39. objects/ 55/7db03de997c86a4a028e1ebd3a1ceb225be238 をさらに詳しく見てみる $ zlib -d < objects/55/7db03de997c86a4a028e1eb
 d3a1ceb225be238 |

    xxd 00000000: 626c 6f62 2031 3200 4865 6c6c 6f20 576f 00000010: 726c 640a blob 12.Hello Wo rld.
  40. objects/ 55/7db03de997c86a4a028e1ebd3a1ceb225be238 をさらに詳しく見てみる $ zlib -d < objects/55/7db03de997c86a4a028e1eb
 d3a1ceb225be238 |

    xxd 00000000: 626c 6f62 2031 3200 4865 6c6c 6f20 576f 00000010: 726c 640a blob 12.Hello Wo rld. 16進ダンプを 表示する
  41. objects/ 55/7db03de997c86a4a028e1ebd3a1ceb225be238 をさらに詳しく見てみる 00000000: 62 6c 6f 62 20 31

    32 00 48 65 6c 6c 6f 20 57 6f 00000010: 72 6c 64 0a b b l o (Space) 1 2 (NUL) H e l l o W o r l d (改行) (Space) • ASCIIコードと照らし合わせると… <オブジェクトタイプ> 0x20 <ファイルバイト数> 0x00 <データバイト> • オブジェクトのフォーマットは になっている!
  42. ちなみに、Gitオブジェクトは git cat-file コマンドでもみることができる $ cd ../ /Users/atsuya-sato/Desktop/git-inside-workshop/.git $ git

    cat-file -t 557db03de997c86a4a028e1ebd3
 a1ceb225be238 $ pwd blob $ git cat-file -p 557d Hello World SHA-1ハッシュの 先頭4文字だけでも 名前解決できる $ git cat-file -s 557d 12
  43. git addをするとblobオブジェクト が生成されることが分かった!

  44. git addで何が起きているのか? • hello.txtをgit addしたことによって ‣objects/ 55/7db03de997c86a4a028e1ebd3a1ceb22 5be238 ‣index •

    の2つのファイルが生成されたことが分かった
  45. indexとはなんなのか

  46. indexとは何なのか • ステージング情報を保持してるバイナリファイ ル • コンフリクトした際の競合の情報などもindex が持っている • ステージング領域とは「次にコミットしたとき にコンテンツとして登録されるもの」

  47. indexを見てみる…? $ cat .git/index | xxd /Users/atsuya-sato/Desktop/git-inside-workshop $ pwd 00000000:

    4449 5243 0000 0002 0000 0001 5cda 3fb1 00000010: 195f eaed 5cda 3fb1 195f eaed 0100 0004 00000020: 008c a4c2 0000 81a4 0000 01f6 0000 0014 00000030: 0000 000c 557d b03d e997 c86a 4a02 8e1e 00000040: bd3a 1ceb 225b e238 0009 6865 6c6c 6f2e 00000050: 7478 7400 7990 bb91 d0e6 ff77 8de7 af5b 00000060: a6ea fb95 c5b9 643a DIRC........\.?. ._..\.?.._...... ................ ....U}.=...jJ... .:..”[.8..hello. txt......y.w...[ ......d:
  48. indexを見てみる…? 00000000: 4449 5243 0000 0002 0000 0001 5cda 3fb1

    00000010: 195f eaed 5cda 3fb1 195f eaed 0100 0004 00000020: 008c a4c2 0000 81a4 0000 01f6 0000 0014 00000030: 0000 000c 557d b03d e997 c86a 4a02 8e1e 00000040: bd3a 1ceb 225b e238 0009 6865 6c6c 6f2e 00000050: 7478 7400 7990 bb91 d0e6 ff77 8de7 af5b 00000060: a6ea fb95 c5b9 643a
  49. indexを見てみる…? 00000000: 4449 5243 0000 0002 0000 0001 5cda 3fb1

    00000010: 195f eaed 5cda 3fb1 195f eaed 0100 0004 00000020: 008c a4c2 0000 81a4 0000 01f6 0000 0014 00000030: 0000 000c 557d b03d e997 c86a 4a02 8e1e 00000040: bd3a 1ceb 225b e238 0009 6865 6c6c 6f2e 00000050: 7478 7400 7990 bb91 d0e6 ff77 8de7 af5b 00000060: a6ea fb95 c5b9 643a (時間があれば後で読み方を教えます)
  50. indexを見てみる $ git ls-files -s 100644 557db03de997c86a4a028e1ebd3a1ceb225be238 0 hello.txt •

    ls-files -sでステージング領域にキャッシュされているファイル の一覧を見ることができる • ステージフラグ: 普段は0、マージコンフリクトの解消(3-way マージ)の際にステージ1, 2, 3としてインデックスに保存 • indexファイルは他にもいろいろ情報を持っているが省略(後で 時間があれば紹介) FileMode (Permission) blobのSHA1ハッシュ ステージフラグ ファイルパス
  51. 2. git commitで 何が起きているのか

  52. 先にgit addで出来た.git/の
 生成物をコミットしておく $ cd .git On branch master Untracked

    files: (use "git add <file>..." to include in what will be committed) index objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238 nothing added to commit but untracked files present (use "git add" to track) $ git status -uall $ git add . $ git commit -m “Exec git add hello.txt” /Users/atsuya-sato/Desktop/git-inside-workshop $ pwd
  53. git commitで何が起きているのか $ cd ../ /Users/atsuya-sato/Desktop/git-inside-workshop/.git $ pwd $ git

    status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: hello.txt $ git commit -m “Add hello.txt” [master (root-commit) 87a9891] Add hello.txt 1 file changed, 1 insertion(+) create mode 100644 hello.txt
  54. git commitで何が起きているのか $ cd .git $ git status -uall On

    branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: index Untracked files: (use "git add <file>..." to include in what will be committed) COMMIT_EDITMSG logs/HEAD logs/refs/heads/master objects/87/a989174c548a6a8b0e78a017d00db3a4e16d12 objects/97/b49d4c943e3715fe30f141cc6f27a8548cee0e refs/heads/master no changes added to commit (use "git add" and/or "git commit -a")
  55. git commitで何が起きているのか $ cd .git $ git status -uall On

    branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: index Untracked files: (use "git add <file>..." to include in what will be committed) COMMIT_EDITMSG logs/HEAD logs/refs/heads/master objects/87/a989174c548a6a8b0e78a017d00db3a4e16d12 objects/97/b49d4c943e3715fe30f141cc6f27a8548cee0e refs/heads/master no changes added to commit (use "git add" and/or "git commit -a") たくさんファイル が出てきた!!
  56. git commitで 何が起きているのか? • hello.txtをgit addした後、git commitしたことによって ‣index • が更新された

    ‣COMMIT_EDITMSGS (説明省略) ‣logs/HEAD (説明省略) ‣logs/refs/heads/master (説明省略) ‣objects/87/a989174c548a6a8b0e78a017d00db3a4e16d12 ‣objects/97/b49d4c943e3715fe30f141cc6f27a8548cee0e ‣refs/heads/master • が生成された
  57. git commitで生成された
 Gitオブジェクトを見てみる • git commitで追加された ‣objects/87/ a989174c548a6a8b0e78a017d00db 3a4e16d12 ‣objects/97/

    b49d4c943e3715fe30f141cc6f27a8 548cee0e • を見てみる
  58. git commitで生成された
 Gitオブジェクトを見てみる $ git cat-file -t 87a9 commit $

    git cat-file -s 87a9 tree 97b49d4c943e3715fe30f141cc6f27a8548cee0e author atsuya-sato <atsuya-sato@cookpad.jp> 1557809638 +0900 committer atsuya-sato <atsuya-sato@cookpad.jp> 1557809638 +0900 Add hello.txt git commitで追加されたtreeオブジェクト(97b4)を ルートに持つcommitオブジェクトが生成されている $ cd ../ $ pwd /Users/atsuya-sato/Desktop/git-inside-workshop
  59. git commitで生成された
 Gitオブジェクトを見てみる $ git cat-file -t 97b4 tree $

    git cat-file -s 97b4 100644 blob 557db03de997c86a4a028e1ebd3a1ceb225be238 hello.txt git addで追加されたhello.txtのblobオブジェクト (557d)を持つtreeオブジェクト(97b4)が生成されている
  60. git commitで 何が起きているのか? • hello.txtをgit addした後、git commitしたことによって ‣index • が更新された

    ‣COMMIT_EDITMSGS (説明省略) ‣logs/HEAD (説明省略) ‣logs/refs/heads/master (説明省略) ‣objects/87/a989174c548a6a8b0e78a017d00db3a4e16d12 ‣objects/97/b49d4c943e3715fe30f141cc6f27a8548cee0e ‣refs/heads/master • が生成された
  61. refs/heads/masterをみる $ cat .git/refs/heads/master 87a989174c548a6a8b0e78a017d00db3a4e16d12 commitオブジェクトのSHA-1ハッシュを持ってい ることが分かる • refs/heads/masterはmasterブランチのHEAD コミットへの参照を持っている

  62. git commitで 何が起きているのか? • hello.txtをgit addした後、git commitしたことによって ‣index • が更新された

    ‣COMMIT_EDITMSGS (説明省略) ‣logs/HEAD (説明省略) ‣logs/refs/heads/master (説明省略) ‣objects/87/a989174c548a6a8b0e78a017d00db3a4e16d12 ‣objects/97/b49d4c943e3715fe30f141cc6f27a8548cee0e ‣refs/heads/master • が生成された
  63. indexを見てみる $ cat .git/index | xxd 00000000: 4449 5243 0000

    0002 0000 0001 5cda 3fb1 00000010: 195f eaed 5cda 3fb1 195f eaed 0100 0004 00000020: 008c a4c2 0000 81a4 0000 01f6 0000 0014 00000030: 0000 000c 557d b03d e997 c86a 4a02 8e1e 00000040: bd3a 1ceb 225b e238 0009 6865 6c6c 6f2e 00000050: 7478 7400 5452 4545 0000 0019 0031 2030 00000060: 0a97 b49d 4c94 3e37 15fe 30f1 41cc 6f27 00000070: a854 8cee 0e94 aef3 b413 ed22 4737 8e4b 00000080: 95c5 ea68 cafa 4937 f4 DIRC........\.?. ._..\.?.._...... ................ ....U}.=...jJ... .:.."[.8..hello. txt.TREE.....1 0 ....L.>7..0.A.o' .T........."G7.K ...h..I7.
  64. indexを見てみる 00000000: 4449 5243 0000 0002 0000 0001 5cda 3fb1

    00000010: 195f eaed 5cda 3fb1 195f eaed 0100 0004 00000020: 008c a4c2 0000 81a4 0000 01f6 0000 0014 00000030: 0000 000c 557d b03d e997 c86a 4a02 8e1e 00000040: bd3a 1ceb 225b e238 0009 6865 6c6c 6f2e 00000050: 7478 7400 5452 4545 0000 0019 0031 2030 00000060: 0a97 b49d 4c94 3e37 15fe 30f1 41cc 6f27 00000070: a854 8cee 0e94 aef3 b413 ed22 4737 8e4b 00000080: 95c5 ea68 cafa 4937 f4 00000000: 4449 5243 0000 0002 0000 0001 5cda 3fb1 00000010: 195f eaed 5cda 3fb1 195f eaed 0100 0004 00000020: 008c a4c2 0000 81a4 0000 01f6 0000 0014 00000030: 0000 000c 557d b03d e997 c86a 4a02 8e1e 00000040: bd3a 1ceb 225b e238 0009 6865 6c6c 6f2e 00000050: 7478 7400 7990 bb91 d0e6 ff77 8de7 af5b 00000060: a6ea fb95 c5b9 643a • git add後 • git commit後 85バイト目からバイナリ が変化していることが分かる
  65. indexをみる • git commitによってindexに追加されたのは、 Cached treeという、Treeの状態を表す情報 • Cached treeは、現在のGit Workspace内全て

    のtreeの名前・treeのSHA-1ハッシュ・ subtreeの数・tree内のblobの数を持つ
  66. indexをみる • https://github.com/yoichi/git-cat-index • というツールを使うと、indexをいい感じ に見ることができる DIRC (dircache), 1 entries

    557db03de997c86a4a028e1ebd3a1ceb225be238 (stage:0) 100644 hello.txt TREE 97b49d4c943e3715fe30f141cc6f27a8548cee0e (0/1) $ git_cat_index.py .git/index これがCached tree
  67. 3. gitは本当に差分を保存 しているのか?

  68. 先にgit commitで出来た.git/の
 生成物をコミットしておく $ cd .git $ git add .

    $ git commit -m “Exec git commit” /Users/atsuya-sato/Desktop/git-inside-workshop $ pwd
  69. hello.txtを編集してadd & commitする $ cd ../ $ git add hello.txt

    $ echo “Hello FUN” > hello.txt $ cat hello.txt Hello FUN Hello Worldを Hello FUNに編集 $ git commit -m “Update hello.txt” [master 0741a4a] Update hello.txt 1 file changed, 1 insertion(+), 1 deletion(-) commitオブジェクト
 (0741)ができた
  70. .gitの変更を見る $ cd .git $ git status -uall On branch

    master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: COMMIT_EDITMSG modified: index modified: logs/HEAD modified: logs/refs/heads/master modified: refs/heads/master Untracked files: (use "git add <file>..." to include in what will be committed) objects/07/41a4a634a5c550e59ed013275ebea2b5bedef6 objects/2d/ccf803893c8e418bdaa03f0c4af005517f8e88 objects/70/2e500c6260d7caaf75f266ac27eb8215108f76 一番上がcommit オブジェクト
  71. commitオブジェクト
 の中身を見る $ git cat-file -p 0741 tree 702e500c6260d7caaf75f266ac27eb8215108f76 parent

    87a989174c548a6a8b0e78a017d00db3a4e16d12 author atsuya-sato <atsuya-sato@cookpad.jp> 1557813718 +0900 committer atsuya-sato <atsuya-sato@cookpad.jp> 1557813718 +0900 Update hello.txt $ cd ../ (702e)というtreeオブジェクトができているのが分かる
  72. treeオブジェクト
 の中身を見る $ git cat-file -p 702e 100644 blob 2dccf803893c8e418bdaa03f0c4af005517f8e88

    hello.txt 先ほどとblobオブジェクトのSHA-1 ハッシュが変わっているのが分かる
  73. blobオブジェクト
 の中身を見る $ cd .git $ zlib -d < objects/55/7db03de997c86a4a028e1eb


    d3a1ceb225be238 blob 12Hello World $ zlib -d < objects/2d/ccf803893c8e418bdaa03f0 c4af005517f8e88 blob 10Hello FUN
  74. blobオブジェクト
 の中身を見る • 実はGitが保存しているのは差分ではなく、「スナップ ショット」 • blobに関してはファイルデータそのものを保存する • オブジェクトファイルに対してSHA-1で生成した checksumをファイル名にしているので、ファイルに変

    更がなければ、新たなblobオブジェクトは作成されない • treeが持つsubtreeやblobが更新されると、新たなtreeオ ブジェクトが作成される
  75. Gitはスナップショットを保存しておいて、commitオブ ジェクトとcommitに紐づくtree/blobの生成によって
 バージョン管理をしている

  76. おまけ1: Gitの作り方

  77. Gitの作り方 • Gitの内側を学ぶ • .gitをgit管理して挙動を見る • Gitの内側(https://git-scm.com/ book/ja/v1/ Git%E3%81%AE%E5%86%85%E 5%81%B4)を見る

  78. Gitの作り方 • Write yourself a Git
 (https://wyag.thb.lt/)をやる • Gitの作り方がPythonのソースコード付 きで説明されている(ただし英語)

    • 上の記事を見るとinit, hash-object, cat- file, log, ls-tree, show-ref, tag, rev- parseが作れる
  79. 自分もSwiftで作ってみた https://github.com/natmark/Gift Write yourself a Gitのコマンド + add, commit
 まで実装した

  80. おまけ2: 紹介しなかった ディレクトリ

  81. 紹介しなかったファイル ・description gitwebがリポジトリーの情報を表示するのに使用 ・config git config —localするときに読み書きされてるのがここ ・info/ info/excludeというファイルがあり、コミット対象外にしたいファイルを記述するのに 使用(.gitignoreと異なり、他人と共有されない)

    ・hooks/ Gitの処理の各フェーズごとに自動的に実行されるスクリプトを設定するのに使用 (例: pre-push) ・refs/ branchやtagが指しているコミットへの参照を保存
  82. おまけ3: indexの読み方

  83. indexを読む 00000000: 4449 5243 0000 0002 0000 0001 5cda 3fb1

    00000010: 195f eaed 5cda 3fb1 195f eaed 0100 0004 00000020: 008c a4c2 0000 81a4 0000 01f6 0000 0014 00000030: 0000 000c 557d b03d e997 c86a 4a02 8e1e 00000040: bd3a 1ceb 225b e238 0009 6865 6c6c 6f2e 00000050: 7478 7400 5452 4545 0000 0019 0031 2030 00000060: 0a97 b49d 4c94 3e37 15fe 30f1 41cc 6f27 00000070: a854 8cee 0e94 aef3 b413 ed22 4737 8e4b 00000080: 95c5 ea68 cafa 4937 f4 DIRC (dircache), 1 entries 557db03de997c86a4a028e1ebd3a1ceb225be238 (stage:0) 100644 hello.txt TREE 97b49d4c943e3715fe30f141cc6f27a8548cee0e (0/1)
  84. indexを読む 00000000: 4449 5243 0000 0002 0000 0001 5cda 3fb1

    00000010: 195f eaed 5cda 3fb1 195f eaed 0100 0004 00000020: 008c a4c2 0000 81a4 0000 01f6 0000 0014 00000030: 0000 000c 557d b03d e997 c86a 4a02 8e1e 00000040: bd3a 1ceb 225b e238 0009 6865 6c6c 6f2e 00000050: 7478 7400 5452 4545 0000 0019 0031 2030 00000060: 0a97 b49d 4c94 3e37 15fe 30f1 41cc 6f27 00000070: a854 8cee 0e94 aef3 b413 ed22 4737 8e4b 00000080: 95c5 ea68 cafa 4937 f4
  85. indexを読む • Header 00000000: 4449 5243 0000 0002 0000 0001

    Signature Format Entries D I R C (Dircache) 2 Indexファイルの
 フォーマット 1 Stageされてる ファイルの数
  86. • Index entry(1/2) indexを読む 00000000: 5cda 3fb1 00000010: 195f eaed

    5cda 3fb1 195f eaed 0100 0004 00000020: 008c a4c2 0000 81a4 0000 01f6 0000 0014 00000030: 0000 000c created_at sec created_at msec updated_at msec updated_at sec deviceID inode mode uid gid file size 12 bytes 9217218 9217218 502 20 16777220 1557807025 425716461 1557807025 425716461
  87. 00000030: 557d b03d e997 c86a 4a02 8e1e 00000040: bd3a 1ceb

    225b e238 0009 6865 6c6c 6f2e 00000050: 7478 7400 • Index entry(2/2) indexを読む SHA-1 Hash SHA-1 Hash 557db03de997c86a4a028e1e bd3a1ceb225be238 Flag File path File path zero padding hello. txt Flag: 0009!0000000000001001 assume valid flag(1bit) | extended flag(1bit) | stageFlag(2bit) | nameLength(12bit)
  88. • Cached tree indexを読む 00000050: 5452 4545 0000 0019 0031

    2030 00000060: 0a97 b49d 4c94 3e37 15fe 30f1 41cc 6f27 00000070: a854 8cee 0e SHA-1 Hash SHA-1 Hash (LF) (Space) (NUL) Signature T R E E size 25 bytes 1 0 index entries count subtrees 
 count 97b49d4c943e3715fe30f141cc6f27 root tree以外は(LF)の後に ディレクトリ名が来る a8548cee0e
  89. 00000070: 94 aef3 b413 ed22 4737 8e4b 00000080: 95c5 ea68

    cafa 4937 f4 • Checksum indexを読む • 117バイト目までのバイナリデータの SHA-1ハッシュ SHA-1 Hash SHA-1 Hash 94aef3b413ed2247378e4b 95c5ea68cafa4937f4
  90. indexの詳しい仕様 SHA-1 Hash https://github.com/git/git/blob/master/ Documentation/technical/index-format.txt