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

commits in git

けんご
November 28, 2014

commits in git

けんご

November 28, 2014
Tweet

More Decks by けんご

Other Decks in Programming

Transcript

  1. @tkengo Internal of git 内部動作と実装を学ぶことは、git がどうしてこんなに便利で有効な のかを根本的に理解するのに重要です。 ! 初期のgit(主として1.5以前)は、洗練されたVCS というよりもむし

    ろファイル・システムであることを(gitの特徴として)強調してお り、それ故に、ユーザー・インターフェイスは今よりも複雑なもので した。 ! 連想記憶ファイル・システム層は驚くほど素晴らしいので、この章の 最初にそれをカバーすることにします。 by Pro Git
  2. @tkengo blob tree R reference Objects in git 今日は主にblob tree

    commitについて詳しく見ていきます。reference headはちょっとだけ出てきます。tagは今回でてきません。 commit H head tag 今日の登場人物 -
  3. @tkengo Objects in git gitはcommitしたその時点でのファイルツリーのスナップショットを持っており、スナップショットにはtreeとblobが含まれていま す。referenceはある特定のcommitを指しており、さらにheadは特定のreferenceを指しています。 R reference H head

    blob tree commit tree blob blob blob tree commit tree blob blob blob tree commit tree blob blob commit 省略... commit 省略... commit 省略... commit 省略... commit 省略... R reference 親 親 親 親 親 親 親
  4. @tkengo Objects in git コミットはご存知の通りSHA1のハッシュ値を持っています。referenceは実は普段使っているブランチのことです。そしてHEADは今 の作業位置を示しています。 R feature-branch H HEAD

    blob tree 6d025cd tree blob blob blob tree 8d4a726 tree blob blob blob tree 5bd7d91 tree blob blob 96caf5f 省略... 31e5f34 省略... edd97e4 省略... fdf793c 省略... 1d09b9b 省略... R master 親 親 親 親 親 親 親
  5. @tkengo Objects in git 実はスナップショットのtreeとblobにもそれぞれSHA1のハッシュ値がついています。 R feature-branch H HEAD 1e11458

    358a4b5 6d025cd 100d7a6 8d4a726 5bd7d91 96caf5f 省略... 31e5f34 省略... edd97e4 省略... fdf793c 省略... 1d09b9b 省略... R master 親 親 親 親 親 親 親 ddf3ec9 3d4b084 2629bfc a25b132 100d7a6 ddf3ec9 3d4b084 2629bfc 2125db4 0926525 ddf3ec9 a214dca
  6. @tkengo Objects in git そしてスナップショットには、そのスナップショットを一意に識別するrootツリーがあり、commitはそのrootツリーのSHA1ハッ シュ値を知っています。 H HEAD 1e11458 358a4b5

    6d025cd 100d7a6 8d4a726 5bd7d91 96caf5f 省略... edd97e4 省略... fdf793c 省略... R master 親 親 親 親 親 ddf3ec9 3d4b084 2629bfc a25b132 100d7a6 ddf3ec9 3d4b084 2629bfc 2125db4 0926525 ddf3ec9 a214dca rootツリー
  7. @tkengo Detail of a blob blobは、ヘッダに対して実際のファイルの内容をくっつけたものを準備して、その内容をzlibで圧縮したものがblobの中身に、そして SHA1に通したものがblobのハッシュ値になります。 ddf3ec9 ヘッダ #include

    <stdio.h>! ! /* ϝΠϯؔ਺ */! int main() {! /* ग़ྗจࣈྻ */! char *str;! str = “Hello World!”;! ! printf(str);! return 0;! } blob 161/0 固定で “blob” スペース + ファイル ヌル 文字 zlib SHA1ハッシュ (161byte)
  8. @tkengo Detail of a tree treeもblobと同じく、ヘッダにツリーのコンテンツをくっつけたものがtreeになります。treeのコンテンツは、そのtreeに含まれる tree及びblobの一覧をもっています。 9aeb4c2 ヘッダ 100644

    tree 652e759… builtin! 100644 blob 7ba2ba7… main.c! 100644 blob e6c1c39… mem.c! ...! tree 177/0 固定で “tree” スペース + (177byte) ヌル 文字 treeのコンテンツ zlib SHA1ハッシュ オブジェクトのモード オブジェクトの種類 tree or blob SHA1ハッシュ値 ファイル名 or ディレクトリ名 ※実際はちょっと違うかも
  9. @tkengo Detail of a commit commitも同じく、ヘッダにコンテンツをくっつけたものです。commitのコンテンツは、rootツリーのSHA1ハッシュ値、親commitの SHA1ハッシュ値、コミットした人の情報、そしてコミットメッセージを持っています。 ヘッダ tree 9aeb4c2...!

    parent 5d5de46...! author kengo <[email protected]> ..! committer kengo <[email protected]> ..! ! first commit commit 180/0 固定で “commit” スペース + ヌル 文字 commitのコンテンツ zlib SHA1ハッシュ rootツリーのSHA1ハッシュ値 user.name と user.email の値 コミットメッセージ 親commitのSHA1ハッシュ値 6d025cd (180byte)
  10. @tkengo Summary of snapshot • commitはその時点のスナップショットのrootツリーを知っている • commitは自分の親のcommitも知っている • treeはそのtreeに含まれているtree及びblobを全部知っている

    • blobはファイル内容を知っている ヘッダ #include <stdio.h>! ! /* ϝΠϯؔ਺ */! int main() {! /* ग़ྗจࣈྻ */! char *str;! str = “Hello World!”;! ! printf(str);! return 0;! } コンテンツ tree 161/0 blob
  11. @tkengo Summary of snapshot このようにファイルやディレクトリにSHA1ハッシュをつけてblobやtreeとして管理する方法こそgitが連想記憶ファイルシステムと言 われる所以だと言えます。それを発展させ、スナップショットとしてcommitと紐付けることでVCSとしての機能を実現しています。 1e11458 358a4b5 100d7a6 ddf3ec9

    3d4b084 358a4b5 という名前を持ったディレクトリ その実態は子ファイル及び子ディレクトリのSHA1ハッシュ値を並べたテキストデータを圧縮したもの 上に同じ 3d4b084 という名前を持ったファイル その実態はファイル内容そのものを圧縮したもの 上に同じ スナップショットはファイルシステムに似ています
  12. @tkengo blob tree R reference Objects in git blobはファイル、treeはディレクトリ、commitはスナップショットを指し示すもの、referenceは特定のcommitを参照する、headは 特定のreferenceを参照する、でした。

    commit H head tag 彼らのこと少しはわかりましたか? - ファイル ディレクトリ スナップショット へのポインタ commit へのポインタ reference へのポインタ
  13. @tkengo Save the disk space それにしても、このようにcommit毎にスナップショットを持っていたら大変なことにならないでしょうか。とても効率が悪そうな気 がします。 blob tree commit

    tree blob blob 親 blob tree commit tree blob blob 親 blob tree commit tree blob blob 親 blob tree commit tree blob blob 親 blob tree commit tree blob blob 親 blob tree commit tr blob b blob tree commit tree blob blob 親
  14. @tkengo Save the disk space 確かに効率は悪いですが、それはディスク容量の部分です。差分計算やcheckoutなどはスナップショットで管理した方が圧倒的に早 いですし、ディスク容量もなるべく節約できるように工夫されています。 blob tree commit

    tree blob blob 親 blob tree commit tree blob blob 親 blob tree commit tree blob blob 親 blob tree commit tree blob blob 親 blob tree commit tree blob blob 親 blob tree commit tr blob b blob tree commit tree blob blob 親 ディスク容量は確かに非効率
  15. @tkengo Save the disk space この2つのcommitのスナップショットを見ていきます。 1e11458 358a4b5 6d025cd 100d7a6

    ddf3ec9 3d4b084 8d4a726 2629bfc a25b132 100d7a6 ddf3ec9 3d4b084 5bd7d91 2629bfc 2125db4 0926525 ddf3ec9 a214dca
  16. @tkengo Save the disk space もう少し詳しく見ていきます。まずはblobの方です。たとえばblobは上記のようなファイル内容を持っており、ビックリマークを2つ 追加する変更が加えられているとします。すると 1e11458 のblobの内容が変わって新たに 2629bfc

    のblobが作られます。 1e11458 358a4b5 6d025cd 100d7a6 ddf3ec9 3d4b084 8d4a726 2629bfc a25b132 100d7a6 ddf3ec9 3d4b084 5bd7d91 2629bfc 2125db4 0926525 ddf3ec9 a214dca blob 11/0Hello World blob 13/0Hello World!!
  17. @tkengo Save the disk space すると、そのblobのSHA1ハッシュ値をしっている親のtreeも、子供のblobのハッシュ値を書き換えなければなりません。つまり新し く a25b132 のtreeが作られます。 1e11458

    358a4b5 6d025cd 100d7a6 ddf3ec9 3d4b084 8d4a726 2629bfc a25b132 100d7a6 ddf3ec9 3d4b084 5bd7d91 2629bfc 2125db4 0926525 ddf3ec9 a214dca tree 113/0! 100644 blob 1e11458..! 040000 tree 100d7a6.. tree 113/0! 100644 blob 2629bfc..! 040000 tree 100d7a6..
  18. @tkengo Save the disk space しかし変更のない他の 100d7a6 ddf3ec9 3d4b084 はそのまま再利用されています。

    1e11458 358a4b5 6d025cd 100d7a6 ddf3ec9 3d4b084 8d4a726 2629bfc a25b132 100d7a6 ddf3ec9 3d4b084 5bd7d91 2629bfc 2125db4 0926525 ddf3ec9 a214dca