Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

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

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

Atsuya Sato

May 18, 2019
Tweet

More Decks by Atsuya Sato

Other Decks in Technology

Transcript

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

    View full-size slide

  2. 始める前に
    「動かして覚える」なので、手元にGitの実
    行環境がある方はスライドを見ながら

    コマンドを叩くと面白いかも?

    (一緒に動かす場合は、gitとzlibを

    インストールしておいてください)

    10分しかないので、LTは割と早口です

    View full-size slide

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

    View full-size slide

  4. Git使ったことありますか?"

    View full-size slide

  5. Gitとは
    • 一言で言うと

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  15. 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

    View full-size slide

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

    View full-size slide

  17. .gitを覗いてみる
    $ cd .git
    $ ls -a
    . .. HEAD config description
    hooks info objects refs
    いろいろでてきた
    わからん!

    View full-size slide

  18. .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/

    View full-size slide

  19. 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)

    View full-size slide

  20. 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

    View full-size slide

  21. 1. git addで
    何が起きているのか

    View full-size slide

  22. 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 ../

    View full-size slide

  23. 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)

    View full-size slide

  24. git addで何が起きているのか?
    • hello.txtをgit addしたことによって
    ‣objects/
    55/7db03de997c86a4a028e1ebd3a1ceb22
    5be238
    ‣index
    • の2つのファイルが生成されたことが分かった

    View full-size slide

  25. objects/
    55/7db03de997c86a4a028e1eb
    d3a1ceb225be238
    とは一体なんなのだろうか

    View full-size slide

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

    の場合
    ‣objects/55/7db03de997c86a4a028e1ebd3a1ceb

    225be238 

    に保存される

    View full-size slide

  27. objects/の正体
    • objects/ の正体はGitオブジェクトと呼ばれるもの
    • GitはGitオブジェクトとして以下のオブジェクト
    を生成する
    ‣blobオブジェクト
    ‣treeオブジェクト
    ‣commitオブジェクト(tagオブジェクト)

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  32. commitとblobとtreeの関係

    View full-size slide

  33. objects/55/7db03de997c86a4a0

    28e1ebd3a1ceb225be238
    を詳しく見てみる

    View full-size slide

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

    a1ceb225be238
    xKOR04bH/IAI%

    View full-size slide

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

    a1ceb225be238
    xKOR04bH/IAI%
    なんだこれは…

    View full-size slide

  36. objects/
    55/7db03de997c86a4a028e1ebd3a1ceb225be238
    を詳しく見てみる
    $ cat objects/55/7db03de997c86a4a028e1ebd3a1

    ceb225be238
    $ zlib -d < objects/55/7db03de997c86a4a028e1eb

    d3a1ceb225be238
    xKOR04bH/IAI%
    blob 12Hello World

    View full-size slide

  37. objects/
    55/7db03de997c86a4a028e1ebd3a1ceb225be238
    を詳しく見てみる
    $ cat objects/55/7db03de997c86a4a028e1ebd3a1

    ceb225be238
    $ zlib -d < objects/55/7db03de997c86a4a028e1eb

    d3a1ceb225be238
    xKOR04bH/IAI%
    blob 12Hello World
    実はzlibで
    圧縮されている
    中身が出てきた

    View full-size slide

  38. 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.

    View full-size slide

  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.
    16進ダンプを
    表示する

    View full-size slide

  40. 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 <データバイト>
    • オブジェクトのフォーマットは
    になっている!

    View full-size slide

  41. ちなみに、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

    View full-size slide

  42. git addをするとblobオブジェクト
    が生成されることが分かった!

    View full-size slide

  43. git addで何が起きているのか?
    • hello.txtをgit addしたことによって
    ‣objects/
    55/7db03de997c86a4a028e1ebd3a1ceb22
    5be238
    ‣index
    • の2つのファイルが生成されたことが分かった

    View full-size slide

  44. indexとはなんなのか

    View full-size slide

  45. indexとは何なのか
    • ステージング情報を保持してるバイナリファイ

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

    View full-size slide

  46. 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:

    View full-size slide

  47. 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

    View full-size slide

  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

    (時間があれば後で読み方を教えます)

    View full-size slide

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

    View full-size slide

  50. 2. git commitで
    何が起きているのか

    View full-size slide

  51. 先に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

    View full-size slide

  52. 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

    View full-size slide

  53. 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")

    View full-size slide

  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")
    たくさんファイル
    が出てきた!!

    View full-size slide

  55. 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
    • が生成された

    View full-size slide

  56. git commitで生成された

    Gitオブジェクトを見てみる
    • git commitで追加された
    ‣objects/87/
    a989174c548a6a8b0e78a017d00db
    3a4e16d12
    ‣objects/97/
    b49d4c943e3715fe30f141cc6f27a8
    548cee0e
    • を見てみる

    View full-size slide

  57. git commitで生成された

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

    View full-size slide

  58. 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)が生成されている

    View full-size slide

  59. 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
    • が生成された

    View full-size slide

  60. refs/heads/masterをみる
    $ cat .git/refs/heads/master
    87a989174c548a6a8b0e78a017d00db3a4e16d12
    commitオブジェクトのSHA-1ハッシュを持ってい
    ることが分かる
    • refs/heads/masterはmasterブランチのHEAD
    コミットへの参照を持っている

    View full-size slide

  61. 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
    • が生成された

    View full-size slide

  62. 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.

    View full-size slide

  63. 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バイト目からバイナリ
    が変化していることが分かる

    View full-size slide

  64. indexをみる
    • git commitによってindexに追加されたのは、
    Cached treeという、Treeの状態を表す情報
    • Cached treeは、現在のGit Workspace内全て
    のtreeの名前・treeのSHA-1ハッシュ・
    subtreeの数・tree内のblobの数を持つ

    View full-size slide

  65. 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

    View full-size slide

  66. 3. gitは本当に差分を保存
    しているのか?

    View full-size slide

  67. 先にgit commitで出来た.git/の

    生成物をコミットしておく
    $ cd .git
    $ git add .
    $ git commit -m “Exec git commit”
    /Users/atsuya-sato/Desktop/git-inside-workshop
    $ pwd

    View full-size slide

  68. 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)ができた

    View full-size slide

  69. .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
    オブジェクト

    View full-size slide

  70. commitオブジェクト

    の中身を見る
    $ git cat-file -p 0741
    tree 702e500c6260d7caaf75f266ac27eb8215108f76
    parent 87a989174c548a6a8b0e78a017d00db3a4e16d12
    author atsuya-sato 1557813718 +0900
    committer atsuya-sato 1557813718 +0900
    Update hello.txt
    $ cd ../
    (702e)というtreeオブジェクトができているのが分かる

    View full-size slide

  71. treeオブジェクト

    の中身を見る
    $ git cat-file -p 702e
    100644 blob 2dccf803893c8e418bdaa03f0c4af005517f8e88 hello.txt
    先ほどとblobオブジェクトのSHA-1
    ハッシュが変わっているのが分かる

    View full-size slide

  72. blobオブジェクト

    の中身を見る
    $ cd .git
    $ zlib -d < objects/55/7db03de997c86a4a028e1eb

    d3a1ceb225be238
    blob 12Hello World
    $ zlib -d < objects/2d/ccf803893c8e418bdaa03f0
    c4af005517f8e88
    blob 10Hello FUN

    View full-size slide

  73. blobオブジェクト

    の中身を見る
    • 実はGitが保存しているのは差分ではなく、「スナップ
    ショット」
    • blobに関してはファイルデータそのものを保存する
    • オブジェクトファイルに対してSHA-1で生成した
    checksumをファイル名にしているので、ファイルに変
    更がなければ、新たなblobオブジェクトは作成されない
    • treeが持つsubtreeやblobが更新されると、新たなtreeオ
    ブジェクトが作成される

    View full-size slide

  74. Gitはスナップショットを保存しておいて、commitオブ
    ジェクトとcommitに紐づくtree/blobの生成によって

    バージョン管理をしている

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  77. Gitの作り方
    • Write yourself a Git

    (https://wyag.thb.lt/)をやる
    • Gitの作り方がPythonのソースコード付
    きで説明されている(ただし英語)
    • 上の記事を見るとinit, hash-object, cat-
    file, log, ls-tree, show-ref, tag, rev-
    parseが作れる

    View full-size slide

  78. 自分もSwiftで作ってみた
    https://github.com/natmark/Gift
    Write yourself a Gitのコマンド + add, commit

    まで実装した

    View full-size slide

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

    View full-size slide

  80. 紹介しなかったファイル
    ・description gitwebがリポジトリーの情報を表示するのに使用
    ・config git config —localするときに読み書きされてるのがここ
    ・info/ info/excludeというファイルがあり、コミット対象外にしたいファイルを記述するのに
    使用(.gitignoreと異なり、他人と共有されない)
    ・hooks/ Gitの処理の各フェーズごとに自動的に実行されるスクリプトを設定するのに使用
    (例: pre-push)
    ・refs/ branchやtagが指しているコミットへの参照を保存

    View full-size slide

  81. おまけ3: indexの読み方

    View full-size slide

  82. 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)

    View full-size slide

  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

    View full-size slide

  84. indexを読む
    • Header
    00000000: 4449 5243 0000 0002 0000 0001
    Signature Format Entries
    D I R C
    (Dircache)
    2
    Indexファイルの

    フォーマット
    1
    Stageされてる
    ファイルの数

    View full-size slide

  85. • 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

    View full-size slide

  86. 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)

    View full-size slide

  87. • 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

    View full-size slide

  88. 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

    View full-size slide

  89. indexの詳しい仕様
    SHA-1 Hash
    https://github.com/git/git/blob/master/
    Documentation/technical/index-format.txt

    View full-size slide