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のリポジトリを作る $ 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
  2. .gitを覗いてみる $ cd .git $ ls -a . .. HEAD

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

    config description hooks info objects refs いろいろでてきた わからん!
  4. 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)
  5. 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
  6. 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 ../
  7. 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)
  8. objects/ 55/7db03de997c86a4a028e1ebd3a1ceb225be238 を詳しく見てみる $ cat objects/55/7db03de997c86a4a028e1ebd3a1
 ceb225be238 $ zlib -d

    < objects/55/7db03de997c86a4a028e1eb
 d3a1ceb225be238 xKOR04bH/IAI% blob 12Hello World 実はzlibで 圧縮されている 中身が出てきた
  9. 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進ダンプを 表示する
  10. 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 <データバイト> • オブジェクトのフォーマットは になっている!
  11. ちなみに、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
  12. 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:
  13. 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
  14. 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 (時間があれば後で読み方を教えます)
  15. indexを見てみる $ git ls-files -s 100644 557db03de997c86a4a028e1ebd3a1ceb225be238 0 hello.txt •

    ls-files -sでステージング領域にキャッシュされているファイル の一覧を見ることができる • ステージフラグ: 普段は0、マージコンフリクトの解消(3-way マージ)の際にステージ1, 2, 3としてインデックスに保存 • indexファイルは他にもいろいろ情報を持っているが省略(後で 時間があれば紹介) FileMode (Permission) blobのSHA1ハッシュ ステージフラグ ファイルパス
  16. 先に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
  17. 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
  18. 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")
  19. 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") たくさんファイル が出てきた!!
  20. 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 • が生成された
  21. git commitで生成された
 Gitオブジェクトを見てみる $ git cat-file -t 87a9 commit $

    git cat-file -s 87a9 tree 97b49d4c943e3715fe30f141cc6f27a8548cee0e author atsuya-sato <[email protected]> 1557809638 +0900 committer atsuya-sato <[email protected]> 1557809638 +0900 Add hello.txt git commitで追加されたtreeオブジェクト(97b4)を ルートに持つcommitオブジェクトが生成されている $ cd ../ $ pwd /Users/atsuya-sato/Desktop/git-inside-workshop
  22. 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)が生成されている
  23. 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 • が生成された
  24. 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 • が生成された
  25. 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.
  26. 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バイト目からバイナリ が変化していることが分かる
  27. 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
  28. 先にgit commitで出来た.git/の
 生成物をコミットしておく $ cd .git $ git add .

    $ git commit -m “Exec git commit” /Users/atsuya-sato/Desktop/git-inside-workshop $ pwd
  29. 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)ができた
  30. .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 オブジェクト
  31. commitオブジェクト
 の中身を見る $ git cat-file -p 0741 tree 702e500c6260d7caaf75f266ac27eb8215108f76 parent

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

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


    d3a1ceb225be238 blob 12Hello World $ zlib -d < objects/2d/ccf803893c8e418bdaa03f0 c4af005517f8e88 blob 10Hello FUN
  34. 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)
  35. 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
  36. indexを読む • Header 00000000: 4449 5243 0000 0002 0000 0001

    Signature Format Entries D I R C (Dircache) 2 Indexファイルの
 フォーマット 1 Stageされてる ファイルの数
  37. • 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
  38. 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)
  39. • 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
  40. 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