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

たぶんもう怖くないGit/maybe-not-afraid-of-git-anymore

marchin
February 10, 2022

 たぶんもう怖くないGit/maybe-not-afraid-of-git-anymore

marchin

February 10, 2022
Tweet

More Decks by marchin

Other Decks in Technology

Transcript

  1. 自己紹介 - 名前: 阿部 真之 - 仕事: 主にAndroidエンジニア - 最近はサーバサイド

    Kotlinの仕事も始めました - 趣味 - コーヒー、ビール、アニメ、ゲーム、読書、 etc… - Twitter: @marchin_1989
  2. そもそもバージョン管理システム(VCS) - 集中型 - CVS, Subversion, SVN - みんなで1つのリポジトリにネットワーク接続。 -

    最新のソースコードを手元に持ってきて編集。 - 各自が中央のリポジトリに変更を直接反映する。 - 変更履歴を見たい場合は、中央リポジトリにアクセスする必要がある。 - 分散型(DVCS) - Git - 各自がリポジトリを持つ。 - リモートリポジトリにネットワーク接続不要 で、 各自のリポジトリで変更、履歴の確認ができる。 - 他の人に影響を与えず、各自のリポジトリで変更を反映できる。 - 例: 各自のローカルマシン内にリポジトリがある。 - リモートリポジトリに、後からまとめて変更を反映。 自分で送りたいものだけ共有できる。 集中型 分散型
  3. よくある疑問 - どうやってGitは履歴を管理してるんだ? - よくブランチみたいな複雑そうなものうまく動いてんな。 - ブランチ is 何?枝なの? -

    HEAD is 何? - detached headみたいなログが出たけど、これなに? => 毎日Git使ってるのに、よくわかってない。。。
  4. git内部の仕組みを知っていると役立つこと - gitのコマンドを間違って実行してしまった時の対処 - 例 - 作業していたブランチを消してしまった。。 - revert、reset、rebaseなど使ったけど、期待した状態にならなかった。。 =>

    戻したいけど、毎回なんとなくググってやってる。 合ってるのかよくわからないけど、okにしてませんか? => git内部の仕組みを知ることで、gitコマンドが何をやっているのか理解しやすい
  5. gitのデータ保存の仕組み(いきなり結論) - gitは、オブジェクトモデルでデータを保存している。 - gitオブジェクトの集まりで、単なるDAG(有向非巡回グラフ)とポストイットで履歴を管理 している。 - DAG: Directed Acyclic

    Graph(有向非巡回グラフ) - https://ja.wikipedia.org/wiki/%E6%9C%89%E5%90%91%E9%9D%9E%E5%B7%A1%E5%9B %9E%E3%82%B0%E3%83%A9%E3%83%95 - コミットは差分ではなく、スナップショット。 - gitの数あるコマンドは、DAGのオブジェクトの追加、ポストイットの移動を行ってい るだけ。
  6. キーワード - Gitオブジェクト - blob, tree, commit, tag - リファレンス

    - branch, HEAD, tag => Gitオブジェクト と リファレンスの存在を強く意識すると理解しやすいです。
  7. gitオブジェクト(objects) - すべてzlibライブラリで可逆圧縮されたもの。 - SHA-1ハッシュによって識別子がついている。 - オブジェクトは4種類。 - 「.git/objects」ディレクトリを見ると確認できる。 -

    イミュータブル。一度作られたらなかなか消えない。 ※アノテーションタグ hash: e732... hash: 4g35... hash: k35g... hash: 245f... リファレンスにも「tag」があ る。ややこしいので、リファレ ンスの時に一緒に見る。
  8. treeオブジェクト - ディレクトリを表す。 - ファイル名、blobオブジェクト or 別のtreeオブジェクトへの参照を持っている。 5r8d20 0be9e3 c5ac20

    93db38 Procfile README.md app 参照先のgitオブジェクトと、タイプ、それぞ れのファイル名(ディレクトリ名)を保持して いることわかる。
  9. - 以下の情報を持つ。 - トップレベルのtreeオブジェクトへの参照 - コミットしたユーザの情報 - タイムスタンプ - コミットメッセージ

    - 親コミットへの参照 commitオブジェクト 1aaa また、git cat-fileコマンドで、 内容を見てみる。
  10. - 以下の情報を持つ。 - トップレベルのtreeオブジェクトへの参照 - コミットしたユーザの情報 - タイムスタンプ - コミットメッセージ

    - 親コミットへの参照 commitオブジェクト 1aaa トップレベルのtreeオブジェク トを指している。 5f8d20
  11. - 以下の情報を持つ。 - トップレベルのtreeオブジェクトへの参照 - コミットしたユーザの情報 - タイムスタンプ - コミットメッセージ

    - 親コミットへの参照 commitオブジェクト 1aaa 親commitオブジェクトのハッ シュ値を指している。 e6c06e
  12. - 以下の情報を持つ。 - トップレベルのtreeオブジェクトへの参照 - コミットしたユーザの情報 - タイムスタンプ - コミットメッセージ

    - 親コミットへの参照 commitオブジェクト 1aaa 親がないcommitは、initial commit。 親が2つあるのは?(問題) e6c06e
  13. - 以下の情報を持つ。 - トップレベルのtreeオブジェクトへの参照 - コミットしたユーザの情報 - タイムスタンプ - コミットメッセージ

    - 親コミットへの参照 commitオブジェクト 1aaa 親がないcommitは、initial commit。 親が2つあるのは?(問題) e6c06e マージコミット(正解)
  14. - 以下の情報を持つ。 - トップレベルのtreeオブジェクトへの参照 - コミットしたユーザの情報 - タイムスタンプ - コミットメッセージ

    - 親コミットへの参照 commitオブジェクト 1aaa コミットから辿れば、 この時点の プロジェクトを再構成できる。
  15. gitオブジェクトの作り方 - ハッシュ値 - ヘッダー: オブジェクトのタイプ (blob, tree, commit) +

    スペース + コンテンツのサイズ + ヌルバイト - 「ヘッダー」と「コンテンツ」を連結、 sha1 hashをとったもの。 - gitオブジェクト - 「ヘッダー」と「コンテンツ」を連結、 zlibで可逆圧縮したもの。
  16. gitオブジェクトの作り方 - ハッシュ値 - ヘッダー: オブジェクトのタイプ (blob, tree, commit) +

    スペース + コンテンツのサイズ + ヌルバイト - 「ヘッダー」と「コンテンツ」を連結、 sha1 hashをとったもの。 - gitオブジェクト - 「ヘッダー」と「コンテンツ」を連結、 zlibで可逆圧縮したもの。 出典: git documentation https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-Git%E 3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88 ハッシュ値、gitオブジェ クトを作ってみる。
  17. gitオブジェクトの作り方 - ハッシュ値 - ヘッダー: オブジェクトのタイプ (blob, tree, commit) +

    スペース + コンテンツのサイズ + ヌルバイト - 「ヘッダー」と「コンテンツ」を連結、 sha1 hashをとったもの。 - gitオブジェクト - 「ヘッダー」と「コンテンツ」を連結、 zlibで可逆圧縮したもの。 出典: git documentation https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-Git%E 3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88 コンテンツ
  18. gitオブジェクトの作り方 - ハッシュ値 - ヘッダー: オブジェクトのタイプ (blob, tree, commit) +

    スペース + コンテンツのサイズ + ヌルバイト - 「ヘッダー」と「コンテンツ」を連結、 sha1 hashをとったもの。 - gitオブジェクト - 「ヘッダー」と「コンテンツ」を連結、 zlibで可逆圧縮したもの。 出典: git documentation https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-Git%E 3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88 コンテンツ ヘッダー
  19. gitオブジェクトの作り方 - ハッシュ値 - ヘッダー: オブジェクトのタイプ (blob, tree, commit) +

    スペース + コンテンツのサイズ + ヌルバイト - 「ヘッダー」と「コンテンツ」を連結、 sha1 hashをとったもの。 - gitオブジェクト - 「ヘッダー」と「コンテンツ」を連結、 zlibで可逆圧縮したもの。 出典: git documentation https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-Git%E 3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88 ヘッダー コンテンツ ヘッダー+コンテンツ
  20. gitオブジェクトの作り方 - ハッシュ値 - ヘッダー: オブジェクトのタイプ (blob, tree, commit) +

    スペース + コンテンツのサイズ + ヌルバイト - 「ヘッダー」と「コンテンツ」を連結、 sha1 hashをとったもの。 - gitオブジェクト - 「ヘッダー」と「コンテンツ」を連結、 zlibで可逆圧縮したもの。 出典: git documentation https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-Git%E 3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88 ヘッダー コンテンツ ヘッダー+コンテンツ ハッシュ値
  21. gitオブジェクトの作り方 - ハッシュ値 - ヘッダー: オブジェクトのタイプ (blob, tree, commit) +

    スペース + コンテンツのサイズ + ヌルバイト - 「ヘッダー」と「コンテンツ」を連結、 sha1 hashをとったもの。 - gitオブジェクト - 「ヘッダー」と「コンテンツ」を連結、 zlibで可逆圧縮したもの。 出典: git documentation https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-Git%E 3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88 ヘッダー コンテンツ ヘッダー+コンテンツ ハッシュ値 gitオブジェクト
  22. gitオブジェクトの作り方 - ハッシュ値 - ヘッダー: オブジェクトのタイプ (blob, tree, commit) +

    スペース + コンテンツのサイズ + ヌルバイト - 「ヘッダー」と「コンテンツ」を連結、 sha1 hashをとったもの。 - gitオブジェクト - 「ヘッダー」と「コンテンツ」を連結、 zlibで可逆圧縮したもの。 出典: git documentation https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-Git%E 3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88 ヘッダー コンテンツ ヘッダー+コンテンツ ハッシュ値 gitオブジェクト 【重要】 「ヘッダー」と「コンテンツ」が同じ内容なら、 同じgitオブジェクト、同じハッシュ値になる。
  23. gitオブジェクト ※アノテーションタグ hash: e732... hash: 4g35... hash: k35g... hash: 245f...

    以上、gitオブジェクトでした。 タグはリファレンスで説明します。
  24. tag - 軽量タグ - コミットを参照するリファレンス。 - アノテートタグ - tagオブジェクト(gitオブジェクト)へのリファレンス。 -

    tagオブジェクトは、commitオブジェクトへの参照を持つ。 アノテートタグ(リファレンス) tagオブジェクト(gitオブジェクト)
  25. tag - 軽量タグ - コミットを参照するリファレンス。 - アノテートタグ - tagオブジェクト(gitオブジェクト)へのリファレンス。 -

    tagオブジェクトは、commitオブジェクトへの参照を持つ。 - 軽量タグは、コミットのハッシュしか指せないが、 tagオブジェクトでアノテート(注釈)情報を保持できる アノテートタグ(リファレンス) tagオブジェクト(gitオブジェクト)
  26. tag - 軽量タグ - コミットを参照するリファレンス。 - アノテートタグ - tagオブジェクト(gitオブジェクト)へのリファレンス。 -

    tagオブジェクトは、commitオブジェクトへの参照を持つ。 - 軽量タグは、コミットのハッシュしか指せないが、 tagオブジェクトでアノテート(注釈)情報を保持できる アノテートタグ(リファレンス) tagオブジェクト(gitオブジェクト) a3da72 tagオブジェクトの内容(コンテンツ) 1aaa21
  27. gitオブジェクトとリファレンスの視点でgit操作を見る - gitコマンドによって、Gitオブジェクトが作成される様子や、リファレンスが作成され たり、移動する様子をみる。 - 確認するgitコマンド - git init -

    git add - git commit - git log - git branch - git checkout - git clone - git fetch - git merge(fast forward, non fast forward) - git rebase ※コンフリクトは起きない前提です
  28. git fetch xxx xxx yyy yyy zzz リモートリポジトリの方が、 commitオブジェクトが作成さ れていて、mainブランチが進

    んでいる状態。 さらにdevelopブランチが作 成されている。 git fetchしてみる。
  29. git fetch xxx xxx yyy yyy zzz git fetchを行うと、リモートリ ポジトリのgitオブジェクトやリ

    ファレンスがローカルリポジ トリに反映される。 ただし、ローカルのbranchや HEADのリファレンスは動か ない。 zzz
  30. 参考文献 - Git for Computer Scientists - https://eagain.net/articles/git-for-computer-scientists/ - Gitの内側

    - gitオブジェクト - https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-Git%E3%82%AA%E3%83%96%E3 %82%B8%E3%82%A7%E3%82%AF%E3%83%88 - Gitの参照 - https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-Git%E3%81%AE%E5%8F%82%E7 %85%A7 - コミットはスナップショットであり差分ではない - https://github.blog/jp/2021-01-06-commits-are-snapshots-not-diffs/