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

視覚的なGit内部入門

 視覚的なGit内部入門

Git内部の働きを視覚的に説明する。
Gitを使う時に内部で何が起きるかを理解することで、日常的な利用を促進するのがこのプレゼンの目的です。

前職で発表したLTの資料です。当時はSVNからGitへの移動を始めたところで、Gitのコマンド一覧だけで苦労していた社員が各コマンドの理解を高めるつもりで発表した。

英語版は https://speakerdeck.com/desseim/visual-introduction-to-git-internals へ。

Guillaume Legrand

February 22, 2012
Tweet

More Decks by Guillaume Legrand

Other Decks in Programming

Transcript

  1. Gitを理解しよう Bare repository !? squash !? rebase !? refs !?

    detached head !? ハッ!? ファーストフォウウァ アァド!? HEAD !? Legrand Guillaume 2012/02/22
  2. $ git add ./src_dir Working directory src_dir src_file.pl print “txet”;

    .git/ objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; staged
  3. $ git commit -m “First commit” Working directory src_dir src_file.pl

    print “txet”; .git/ objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; 5fs342w 0f4de32 scr_file .pl c92a25a e6fae02 User.name 2012-02-22 First commit e6fae02 5fs342w scr_dir HEAD heads/master heads/master c92a25a
  4. $ Working directory src_dir src_file.pl print “txet”; .git/ objects/ refs/

    Blobs Trees Commits 0f4de32 print “txet”; 5fs342w c92a25a First commit e6fae02 HEAD heads/master heads/master c92a25a
  5. $ vim ./src_dir/src_file.pl Working directory src_dir src_file.pl print “text”; .git/

    objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit modified 5fs342w e6fae02 HEAD heads/master heads/master c92a25a
  6. $ git add ./src_dir Working directory src_dir src_file.pl print “text”;

    .git/ objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit staged 8e27be7 print “text”; 5fs342w e6fae02 HEAD heads/master heads/master c92a25a
  7. $ git reset HEAD ./src_dir #unstage Working directory src_dir src_file.pl

    print “text”; .git/ objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 modified HEAD heads/master heads/master c92a25a
  8. $ git checkout -- ./src_dir Working directory .git/ objects/ refs/

    Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 src_dir src_file.pl print “txet”; HEAD heads/master heads/master c92a25a
  9. $ git cat-file -p 8e27be7 print “text”; $ Working directory

    .git/ objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 src_dir src_file.pl print “txet”; HEAD heads/master heads/master c92a25a
  10. $ vim ./src_dir/src_file.pl Working directory src_dir src_file.pl print “text”; .git/

    objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit modified 5fs342w e6fae02 8e27be7 print “text”; HEAD heads/master heads/master c92a25a
  11. $ git add ./src_dir Working directory src_dir src_file.pl print “text”;

    .git/ objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit staged 8e27be7 print “text”; 5fs342w e6fae02 HEAD heads/master heads/master c92a25a
  12. $ git commit -m “2nd commit” Working directory .git/ objects/

    refs/ Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 136b9d6 2nd commit parent 8e27be7 699022a src_dir src_file.pl print “text”; HEAD heads/master heads/master 136b9d6
  13. $ git branch first c92a25a Working directory .git/ objects/ refs/

    Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 136b9d6 2nd commit parent 8e27be7 699022a src_dir src_file.pl print “text”; HEAD heads/master heads/master 136b9d6 heads/first c92a25a
  14. $ git checkout first Working directory .git/ objects/ refs/ Blobs

    Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 136b9d6 2nd commit parent 8e27be7 699022a src_dir src_file.pl print “txet”; HEAD heads/first heads/master 136b9d6 heads/first c92a25a
  15. $ git branch -D master Working directory .git/ objects/ refs/

    Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 136b9d6 2nd commit parent 8e27be7 699022a src_dir src_file.pl print “txet”; HEAD heads/first heads/first c92a25a
  16. $ git checkout 136b9d6 Working directory .git/ objects/ refs/ Blobs

    Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 136b9d6 2nd commit parent 8e27be7 699022a src_dir src_file.pl print “text”; HEAD 136b9d6 heads/first c92a25a detached head
  17. $ git fetch origin #originにpushしてあった 前提 Working directory .git/ objects/

    refs/ Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 136b9d6 2nd commit parent 8e27be7 699022a src_dir src_file.pl print “text”; heads/first c92a25a remotes/origin /master 136b9d6 HEAD 136b9d6 detached head
  18. $ git checkout master Working directory .git/ objects/ refs/ Blobs

    Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 136b9d6 2nd commit parent 8e27be7 699022a src_dir src_file.pl print “text”; heads/first c92a25a remotes/origin /master 136b9d6 HEAD Heads/master heads/master 136b9d6
  19. $ echo 'c92a25a' > ./.git/refs/heads/master #やるな! @see git-update-ref Working directory

    .git/ objects/ refs/ Blobs Trees Commits 0f4de32 print “txet”; c92a25a First commit 8e27be7 print “text”; 5fs342w e6fae02 136b9d6 2nd commit parent 8e27be7 699022a src_dir src_file.pl print “text”; heads/first c92a25a remotes/origin /master 136b9d6 HEAD Heads/master heads/master c92a25a
  20. まとめ • Gitリポ == .git/ディレクトリ – cp -R でバックアップ –

    これがあればどんな過去な状況が復活可能 • Gitは情報をなくさない – COWで、変更は複製 – 何失敗しても、git addさえやった事があればなくなって ない – 差分を保存するのではない • すべてzlibで圧縮
  21. まとめ • 履歴管理付きのファイルシステムみたいな • Content ⇔ SHA-1 hash ⇔ 履歴

    – 例えばrebaseすると、commitのparentが変わる ⇒ commitの内容が変わる ⇒ commitのhashが変わる ⇒ 子commitのparentが変わる ⇒ … == 履歴が変わ る – SHA-1 == unique ID • バックアップツールとしてGitは◎ – ソースコードではなくても