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

Git研修【ミクシィ22新卒技術研修】

 Git研修【ミクシィ22新卒技術研修】

22新卒技術研修で実施したGit研修の講義資料です。
動画:https://youtu.be/AQwj5z9TOJM

MIXI ENGINEERS

April 13, 2022
Tweet

More Decks by MIXI ENGINEERS

Other Decks in Programming

Transcript

  1. 自己紹介
 
 登内 雅人 (26)
 株式会社ミクシィ 2020 年度新卒 
 


    
 • みてね事業部(家族アルバム みてね)でMLエンジニアやってます 
 ◦ CV系の研究開発したり、MLOps整備したり 
 ◦ #machine-learning でML系書籍の輪読会やってます(宣伝) 
 • 業務外では DDDとかマイクロサービスアーキテクチャらへんにハマってる 
 • 趣味は最近は筋トレ、ランニング、将棋、ポーカーとかにハマってる 
 3 github pages: https://github.com/tonouchi510 普段使っている技術とか その他の活動はこちら
  2. 事前アンケートについて
 今日は、事前アンケートの要望も取り入れつつ
 - Git の基礎
 - Git によるチーム開発のいろは
 - Git

    の内部構造
 についてやっていきます。
 最後に、今日学んだことを生かして GitChallenge に挑戦してもらいます。
 7
  3. 今日の予定
 9 shumon.fujita
 10:30 Git の基礎
 11:30 Git によるチーム開発のいろは
 12:00

    昼食
 13:00 Git の内部構造
 15:00 GitChallenge に挑戦
 17:30 解説
 18:30 終了

  4. Git の基礎
 Git はバージョン管理システム(VCS) の 1 つ。
 バージョン管理とは?
 卒論.pdf /

    卒論(1).pdf / 卒論_最新.pdf / 卒論_修正版.pdf / 卒論_最終稿.pdf / 卒論_提出用.pdf 
 
 13 shumon.fujita

  5. Git の基礎
 Git はバージョン管理システム(VCS) の 1 つ。
 バージョン管理とは?
 卒論.pdf /

    卒論(1).pdf / 卒論_最新.pdf / 卒論_修正版.pdf / 卒論_最終稿.pdf / 卒論_提出用.pdf 
 → どれが最新?
 14 shumon.fujita

  6. Git の基礎
 Git はバージョン管理システム(VCS) の 1 つ。
 バージョン管理とは?
 卒論.pdf /

    卒論(1).pdf / 卒論_最新.pdf / 卒論_修正版.pdf / 卒論_最終稿.pdf / 卒論_提出用.pdf 
 → どれが最新? 1 つ前の版は? 
 
 15 shumon.fujita

  7. Git の基礎
 Git はバージョン管理システム(VCS) の 1 つ。
 バージョン管理とは?
 卒論.pdf /

    卒論(1).pdf / 卒論_最新.pdf / 卒論_修正版.pdf / 卒論_最終稿.pdf / 卒論_提出用.pdf 
 → どれが最新? 1 つ前の版は? 5 つ前の版は? 
 
 
 16 shumon.fujita

  8. Git の基礎
 Git はバージョン管理システム(VCS) の 1 つ。
 バージョン管理とは?
 卒論.pdf /

    卒論(1).pdf / 卒論_最新.pdf / 卒論_修正版.pdf / 卒論_最終稿.pdf / 卒論_提出用.pdf 
 → どれが最新? 1 つ前の版は? 5 つ前の版は? 
 卒論_20210118.pdf / 卒論_20210120.pdf / 卒論20210201.pdf 
 
 
 17 shumon.fujita

  9. Git の基礎
 Git はバージョン管理システム(VCS) の 1 つ。
 バージョン管理とは?
 卒論.pdf /

    卒論(1).pdf / 卒論_最新.pdf / 卒論_修正版.pdf / 卒論_最終稿.pdf / 卒論_提出用.pdf 
 → どれが最新? 1 つ前の版は? 5 つ前の版は? 
 卒論_20210118.pdf / 卒論_20210120.pdf / 卒論20210201.pdf 
 → 新しいバージョン保存するたびに容量が 2 倍 3 倍になっていく...... 
 
 
 18 shumon.fujita

  10. Git の基礎
 Git はバージョン管理システム(VCS) の 1 つ。
 バージョン管理とは?
 卒論.pdf /

    卒論(1).pdf / 卒論_最新.pdf / 卒論_修正版.pdf / 卒論_最終稿.pdf / 卒論_提出用.pdf 
 → どれが最新? 1 つ前の版は? 5 つ前の版は? 
 卒論_20210118.pdf / 卒論_20210120.pdf / 卒論20210201.pdf 
 → 新しいバージョン保存するたびに容量が 2 倍 3 倍になっていく...... 
 
 1 人で書いている卒論ならこれでもなんとかなるけど、100 人で数年かけて開発するソフトウェアならヤバイ 
 
 19 shumon.fujita

  11. Git の基礎
 Git はバージョン管理システム(VCS) の 1 つ。
 バージョン管理とは?
 卒論.pdf /

    卒論(1).pdf / 卒論_最新.pdf / 卒論_修正版.pdf / 卒論_最終稿.pdf / 卒論_提出用.pdf 
 → どれが最新? 1 つ前の版は? 5 つ前の版は? 
 卒論_20210118.pdf / 卒論_20210120.pdf / 卒論20210201.pdf 
 → 新しいバージョン保存するたびに容量が 2 倍 3 倍になっていく...... 
 
 1 人で書いている卒論ならこれでもなんとかなるけど、100 人で数年かけて開発するソフトウェアならヤバイ 
 Git を始めとする VCS を使えばこんな問題とはおさらば! 
 
 20 shumon.fujita

  12. Git の基礎
 Git はバージョン管理システム(VCS) の 1 つ。
 バージョン管理とは?
 卒論.pdf /

    卒論(1).pdf / 卒論_最新.pdf / 卒論_修正版.pdf / 卒論_最終稿.pdf / 卒論_提出用.pdf 
 → どれが最新? 1 つ前の版は? 5 つ前の版は? 
 卒論_20210118.pdf / 卒論_20210120.pdf / 卒論20210201.pdf 
 → 新しいバージョン保存するたびに容量が 2 倍 3 倍になっていく...... 
 
 1 人で書いている卒論ならこれでもなんとかなるけど、100 人で数年かけて開発するソフトウェアならヤバイ 
 Git を始めとする VCS を使えばこんな問題とはおさらば! 
 簡単に履歴を辿れて、容量も抑えつつ、おまけに改ざんにも強い神ツール! 
 21 shumon.fujita

  13. Git の基礎
 Git を使う上で重要な機能として branch と merge がある。 
 


    Git は単に時系列順にバージョンを管理するだけでなく、別々の時間軸のバージョンを管理できる。 
 
 23 shumon.fujita

  14. Git の基礎
 Git を使う上で重要な機能として branch と merge がある。 
 


    Git は単に時系列順にバージョンを管理するだけでなく、別々の時間軸のバージョンを管理できる。 
 さらにそれらを統合することができる。 
 24 shumon.fujita

  15. Git の基礎
 Git を使う上で重要な機能として branch と merge がある。 
 


    Git は単に時系列順にバージョンを管理するだけでなく、別々の時間軸のバージョンを管理できる。 
 さらにそれらを統合することができる。 
 別々の時間軸のことを branch と呼び、それらを統合することを merge と言う。 
 25 shumon.fujita

  16. Git の基礎
 Git を使う上で重要な機能として branch と merge がある。 
 


    Git は単に時系列順にバージョンを管理するだけでなく、別々の時間軸のバージョンを管理できる。 
 さらにそれらを統合することができる。 
 別々の時間軸のことを branch と呼び、それらを統合することを merge と言う。 
 
 
 
 この merge ができるので、branchを分けて独立に進めることができる。 
 26 shumon.fujita
 元バージョン
 A
 A’
 元バージョンに
 A A’ B B’ を足したもの
 B
 B’

  17. Git の基礎
 branch と merge を経験してみる。 
 まずは Git リポジトリを作って、適当に

    commit を作る。 $ mkdir hoge && cd hoge $ git init $ echo Hello > README.md $ git add README.md $ git commit -m "first commit" $ git log --oneline 45e2f9c (HEAD -> master) first commit 
 28 shumon.fujita

  18. Git の基礎
 git branch で現在作られている branch 一覧を見たり、新しい branch を作ったりできる。 


    
 $ git branch * master 
 31 shumon.fujita
 master はデフォルトで
 作られる branch

  19. Git の基礎
 git branch で現在作られている branch 一覧を見たり、新しい branch を作ったりできる。 


    ちなみに Git 2.28 以降なら git config --global init.defaultBranch で init 時に作られる branch を変更できる。 
 $ git branch * master 
 32 shumon.fujita
 master はデフォルトで
 作られる branch

  20. Git の基礎
 git branch で現在作られている branch 一覧を見たり、新しい branch を作ったりできる。 


    ちなみに Git 2.28 以降なら git config --global init.defaultBranch で init 時に作られる branch を変更できる。 
 $ git branch * master $ git branch develop 
 33 shumon.fujita
 master はデフォルトで
 作られる branch

  21. Git の基礎
 git branch で現在作られている branch 一覧を見たり、新しい branch を作ったりできる。 


    ちなみに Git 2.28 以降なら git config --global init.defaultBranch で init 時に作られる branch を変更できる。 
 $ git branch * master $ git branch develop $ git branch develop * master 
 34 shumon.fujita
 master はデフォルトで
 作られる branch

  22. Git の基礎
 git branch で現在作られている branch 一覧を見たり、新しい branch を作ったりできる。 


    ちなみに Git 2.28 以降なら git config --global init.defaultBranch で init 時に作られる branch を変更できる。 
 $ git branch * master $ git branch develop $ git branch develop * master 
 35 shumon.fujita
 master はデフォルトで
 作られる branch
 develop という新しい
 branch が作られている

  23. Git の基礎
 git branch で現在作られている branch 一覧を見たり、新しい branch を作ったりできる。 


    ちなみに Git 2.28 以降なら git config --global init.defaultBranch で init 時に作られる branch を変更できる。 
 $ git branch * master $ git branch develop $ git branch develop * master 新しい branch を作っただけで、まだ master にいることは注意。 
 36 shumon.fujita
 master はデフォルトで
 作られる branch
 develop という新しい
 branch が作られている

  24. Git の基礎
 branch を移動したい場合は、 git checkout を使う。
 
 $ git

    branch develop * master $ git checkout develop 
 39 shumon.fujita

  25. Git の基礎
 branch を移動したい場合は、 git checkout を使う。
 
 $ git

    branch develop * master $ git checkout develop $ git branch * develop master 
 40 shumon.fujita

  26. Git の基礎
 branch を移動したい場合は、 git checkout を使う。
 
 $ git

    branch develop * master $ git checkout develop $ git branch * develop master 
 41 shumon.fujita
 * が現在の branch を
 表している

  27. Git の基礎
 branch を移動したい場合は、 git checkout を使う。
 あとは、それぞれの branch を好きに移動しながら開発を進めていく。

    
 $ git branch develop * master $ git checkout develop $ git branch * develop master 
 42 shumon.fujita
 * が現在の branch を
 表している

  28. Git の基礎
 master と develop でそれぞれ開発を進める。 
 $ git log

    --oneline master e0d4607 (master) README.md に「master」と追記 76d6092 master.txt を追加 45e2f9c first commit 44 shumon.fujita

  29. Git の基礎
 master と develop でそれぞれ開発を進める。 
 $ git log

    --oneline master e0d4607 (master) README.md に「master」と追記 76d6092 master.txt を追加 45e2f9c first commit $ git log --oneline develop a81fbd0 (develop) README.md に「develop」と追記 52ad527 develop.txt を追加 45e2f9c first commit 45 shumon.fujita

  30. Git の基礎
 master と develop でそれぞれ開発を進める。 
 $ git log

    --oneline master e0d4607 (master) README.md に「master」と追記 76d6092 master.txt を追加 45e2f9c first commit $ git log --oneline develop a81fbd0 (develop) README.md に「develop」と追記 52ad527 develop.txt を追加 45e2f9c first commit first commit から、それぞれの branch に 2 コミットずつ積まれている。 46 shumon.fujita

  31. Git の基礎
 図で表すとこんな感じ。
 
 
 
 
 
 47 shumon.fujita


    first commit
 master.txt を追加
 README.md に
 「master」と追記
 develop.txt を追加
 master
 README.md に
 「develop」と追記
 develop

  32. Git の基礎
 図で表すとこんな感じ。次はこれを merge してみる。 
 
 
 
 


    
 48 shumon.fujita
 first commit
 master.txt を追加
 README.md に
 「master」と追記
 develop.txt を追加
 master
 README.md に
 「develop」と追記
 develop

  33. Git の基礎
 図で表すとこんな感じ。次はこれを merge してみる。 
 
 
 
 


    Git では、「merge する branch」= “theirs”、「merge される branch」= “ours” と呼ぶ。
 
 49 shumon.fujita
 first commit
 master.txt を追加
 README.md に
 「master」と追記
 develop.txt を追加
 master
 README.md に
 「develop」と追記
 develop

  34. Git の基礎
 図で表すとこんな感じ。次はこれを merge してみる。 
 
 
 
 


    Git では、「merge する branch」= “theirs”、「merge される branch」= “ours” と呼ぶ。
 今回は theirs = develop, ours = master として merge していく。
 
 50 shumon.fujita
 first commit
 master.txt を追加
 README.md に
 「master」と追記
 develop.txt を追加
 master
 README.md に
 「develop」と追記
 develop

  35. Git の基礎
 merge するには、ours に checkout している状態で、 git merge <theirs>

    とする。
 
 $ git branch develop * master 
 51 shumon.fujita

  36. Git の基礎
 merge するには、ours に checkout している状態で、 git merge <theirs>

    とする。
 
 $ git branch develop * master 
 52 shumon.fujita

  37. Git の基礎
 merge するには、ours に checkout している状態で、 git merge <theirs>

    とする。
 
 $ git branch develop * master $ git merge develop 
 53 shumon.fujita

  38. Git の基礎
 merge するには、ours に checkout している状態で、 git merge <theirs>

    とする。
 
 $ git branch develop * master $ git merge develop Auto-merging README.md CONFLICT (content): Merge conflict in README.md Automatic merge failed; fix conflicts and then commit the result. 
 54 shumon.fujita

  39. Git の基礎
 merge するには、ours に checkout している状態で、 git merge <theirs>

    とする。
 
 $ git branch develop * master $ git merge develop Auto-merging README.md CONFLICT (content): Merge conflict in README.md Automatic merge failed; fix conflicts and then commit the result. 
 55 shumon.fujita

  40. Git の基礎
 merge するには、ours に checkout している状態で、 git merge <theirs>

    とする。
 README.md でコンフリクト(競合)を起こして、Automatic merge に失敗した。 
 $ git branch develop * master $ git merge develop Auto-merging README.md CONFLICT (content): Merge conflict in README.md Automatic merge failed; fix conflicts and then commit the result. 
 56 shumon.fujita

  41. Git の基礎
 merge すると、Git は theirs で開発した差分を自動的に ours に取り込んでくれる。 


    しかし、ours と theirs で同じ箇所を変更していた場合、どちらの変更を残すべきか自動的に判定できない。 
 
 
 
 58 shumon.fujita

  42. Git の基礎
 merge すると、Git は theirs で開発した差分を自動的に ours に取り込んでくれる。 


    しかし、ours と theirs で同じ箇所を変更していた場合、どちらの変更を残すべきか自動的に判定できない。 
 → これがコンフリクト
 
 
 
 59 shumon.fujita

  43. Git の基礎
 merge すると、Git は theirs で開発した差分を自動的に ours に取り込んでくれる。 


    しかし、ours と theirs で同じ箇所を変更していた場合、どちらの変更を残すべきか自動的に判定できない。 
 → これがコンフリクト
 
 コンフリクトが起きたら、人間が手動で差分を取り込んで、コンフリクトを解消させる必要がある。 
 
 
 60 shumon.fujita

  44. Git の基礎
 merge すると、Git は theirs で開発した差分を自動的に ours に取り込んでくれる。 


    しかし、ours と theirs で同じ箇所を変更していた場合、どちらの変更を残すべきか自動的に判定できない。 
 → これがコンフリクト
 
 コンフリクトが起きたら、人間が手動で差分を取り込んで、コンフリクトを解消させる必要がある。 
 
 やってみる。
 
 61 shumon.fujita

  45. Git の基礎
 git status で、どのファイルでコンフリクトしているか確認できる。 
 
 $ git status

    On branch master -- 省略 -- Unmerged paths: (use "git add <file>..." to mark resolution) both modified: README.md 
 63 shumon.fujita

  46. Git の基礎
 git status で、どのファイルでコンフリクトしているか確認できる。 
 both modified となっているファイルがコンフリクト中。 


    $ git status On branch master -- 省略 -- Unmerged paths: (use "git add <file>..." to mark resolution) both modified: README.md 
 64 shumon.fujita

  47. Git の基礎
 git status で、どのファイルでコンフリクトしているか確認できる。 
 both modified となっているファイルがコンフリクト中。 


    $ git status On branch master -- 省略 -- Unmerged paths: (use "git add <file>..." to mark resolution) both modified: README.md 今回は README.md だけがコンフリクトしていることが分かる。 
 65 shumon.fujita

  48. Git の基礎
 コンフリクト中のファイルを開けば、どの行がどのようにコンフリクトしているのか Git が教えてくれるが、 
 自動で検出していることもあって、あまり適切でないことが多い。 
 
 コンフリクト解消の基本は、それぞれの

    branch がそのファイルに対して、 どのような修正を施したのかの、 
 意図や内容をきちんと確認してから手を付ける こと。
 ついついコンフリクト行だけを眺めて、手癖でコンフリクト解消したくなるけど、先に確認するコストと、 
 不適切な merge になってしまった場合の後始末のコストを比べたら、 絶対先に確認するべき。
 
 
 68 shumon.fujita

  49. Git の基礎
 コンフリクト中のファイルを開けば、どの行がどのようにコンフリクトしているのか Git が教えてくれるが、 
 自動で検出していることもあって、あまり適切でないことが多い。 
 
 コンフリクト解消の基本は、それぞれの

    branch がそのファイルに対して、 どのような修正を施したのかの、 
 意図や内容をきちんと確認してから手を付ける こと。
 ついついコンフリクト行だけを眺めて、手癖でコンフリクト解消したくなるけど、先に確認するコストと、 
 不適切な merge になってしまった場合の後始末のコストを比べたら、 絶対先に確認するべき。
 → そもそもコンフリクトしている時点でプチ事故なので、めんどくさがらず慎重に 
 
 
 69 shumon.fujita

  50. Git の基礎
 コンフリクト中のファイルを開けば、どの行がどのようにコンフリクトしているのか Git が教えてくれるが、 
 自動で検出していることもあって、あまり適切でないことが多い。 
 
 コンフリクト解消の基本は、それぞれの

    branch がそのファイルに対して、 どのような修正を施したのかの、 
 意図や内容をきちんと確認してから手を付ける こと。
 ついついコンフリクト行だけを眺めて、手癖でコンフリクト解消したくなるけど、先に確認するコストと、 
 不適切な merge になってしまった場合の後始末のコストを比べたら、 絶対先に確認するべき。
 → そもそもコンフリクトしている時点でプチ事故なので、めんどくさがらず慎重に 
 
 その上で、具体的にどう merge すれば、両方の branch の修正を上手に取り込めるかを考えていく。 
 
 70 shumon.fujita

  51. Git の基礎
 ours と theirs の変更を比較したい場合、まずそれぞれの branch がどこから分岐しているかを調べる。 
 git

    merge-base <branch1> <branch2> で分岐した commit を調べられる。 
 
 
 72 shumon.fujita

  52. Git の基礎
 ours と theirs の変更を比較したい場合、まずそれぞれの branch がどこから分岐しているかを調べる。 
 git

    merge-base <branch1> <branch2> で分岐した commit を調べられる。 
 $ git merge-base master develop 45e2f9c8827024f53ca982c70676614f781205d7 
 
 
 73 shumon.fujita

  53. Git の基礎
 ours と theirs の変更を比較したい場合、まずそれぞれの branch がどこから分岐しているかを調べる。 
 git

    merge-base <branch1> <branch2> で分岐した commit を調べられる。 
 $ git merge-base master develop 45e2f9c8827024f53ca982c70676614f781205d7 
 
 
 74 shumon.fujita
 first commit
 master.txt を追加
 README.md に
 「master」と追記
 develop.txt を追加
 master
 README.md に
 「develop」と追記
 develop

  54. Git の基礎
 ours と theirs の変更を比較したい場合、まずそれぞれの branch がどこから分岐しているかを調べる。 
 git

    merge-base <branch1> <branch2> で分岐した commit を調べられる。 
 $ git merge-base master develop 45e2f9c8827024f53ca982c70676614f781205d7 
 
 
 75 shumon.fujita
 first commit
 master.txt を追加
 README.md に
 「master」と追記
 develop.txt を追加
 master
 README.md に
 「develop」と追記
 develop
 この commit ハッシュが分かる

  55. Git の基礎
 git diff で、merge-base から README.md にどんな修正を加えたのか確認する。 
 $

    git diff 45e2f9c8827024f53ca982c70676614f781205d7 develop README.md 
 77 shumon.fujita

  56. Git の基礎
 git diff で、merge-base から README.md にどんな修正を加えたのか確認する。 
 $

    git diff 45e2f9c8827024f53ca982c70676614f781205d7 develop README.md diff --git a/README.md b/README.md index e965047..214c073 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -Hello +Hello develop 
 78 shumon.fujita

  57. Git の基礎
 git diff で、merge-base から README.md にどんな修正を加えたのか確認する。 
 $

    git diff 45e2f9c8827024f53ca982c70676614f781205d7 develop README.md diff --git a/README.md b/README.md index e965047..214c073 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -Hello +Hello develop $ git diff 45e2f9c8827024f53ca982c70676614f781205d7 master README.md 
 79 shumon.fujita

  58. Git の基礎
 git diff で、merge-base から README.md にどんな修正を加えたのか確認する。 
 $

    git diff 45e2f9c8827024f53ca982c70676614f781205d7 develop README.md diff --git a/README.md b/README.md index e965047..214c073 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -Hello +Hello develop $ git diff 45e2f9c8827024f53ca982c70676614f781205d7 master README.md diff --git a/README.md b/README.md index e965047..1ffbd88 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@ -Hello +Hello master
 80 shumon.fujita

  59. Git の基礎
 結果、master と develop でやりたかったことは次の通り。 
 - master :

    Hello → Hello master に変更 
 - develop : Hello → Hello develop に変更 
 
 
 
 
 81 shumon.fujita

  60. Git の基礎
 結果、master と develop でやりたかったことは次の通り。 
 - master :

    Hello → Hello master に変更 
 - develop : Hello → Hello develop に変更 
 
 今回は ours が master なので、Hello master にすることにしたとする。 
 
 
 
 82 shumon.fujita

  61. Git の基礎
 結果、master と develop でやりたかったことは次の通り。 
 - master :

    Hello → Hello master に変更 
 - develop : Hello → Hello develop に変更 
 
 今回は ours が master なので、Hello master にすることにしたとする。 
 $ emacs README.md # README.md を修正する 
 
 
 83 shumon.fujita

  62. Git の基礎
 結果、master と develop でやりたかったことは次の通り。 
 - master :

    Hello → Hello master に変更 
 - develop : Hello → Hello develop に変更 
 
 今回は ours が master なので、Hello master にすることにしたとする。 
 $ emacs README.md # README.md を修正する $ cat README.md Hello master 
 
 
 84 shumon.fujita

  63. Git の基礎
 結果、master と develop でやりたかったことは次の通り。 
 - master :

    Hello → Hello master に変更 
 - develop : Hello → Hello develop に変更 
 
 今回は ours が master なので、Hello master にすることにしたとする。 
 $ emacs README.md # README.md を修正する $ cat README.md Hello master $ git merge --continue 
 
 
 85 shumon.fujita

  64. Git の基礎
 結果、master と develop でやりたかったことは次の通り。 
 - master :

    Hello → Hello master に変更 
 - develop : Hello → Hello develop に変更 
 
 今回は ours が master なので、Hello master にすることにしたとする。 
 $ emacs README.md # README.md を修正する $ cat README.md Hello master $ git merge --continue 
 これで無事コンフリクトを解消して merge できた。 
 
 86 shumon.fujita

  65. Git の基礎
 コンフリクト解消は人間の手が入るため、必要な差分が消えたり、不要な差分が混入したりする可能性がある。 
 → 大前提として、コンフリクトは起きないのが 1 番。 
 


    Git には fast-forward merge という絶対にコンフリクトが起きない merge がある。 
 fast-forward merge とは、 merge-base が ours のときに起こる merge のこと。 
 
 
 
 
 90 shumon.fujita

  66. Git の基礎
 コンフリクト解消は人間の手が入るため、必要な差分が消えたり、不要な差分が混入したりする可能性がある。 
 → 大前提として、コンフリクトは起きないのが 1 番。 
 


    Git には fast-forward merge という絶対にコンフリクトが起きない merge がある。 
 fast-forward merge とは、 merge-base が ours のときに起こる merge のこと。 
 さっきの例で言うと、↓のような状態で merge すると fast-foward merge が発生する。 
 
 
 
 
 91 shumon.fujita
 first commit
 master.txt を追加
 README.md に
 「master」と追記
 develop.txt を追加
 master
 README.md に
 「develop」と追記
 develop

  67. Git の基礎
 コンフリクト解消は人間の手が入るため、必要な差分が消えたり、不要な差分が混入したりする可能性がある。 
 → 大前提として、コンフリクトは起きないのが 1 番。 
 


    Git には fast-forward merge という絶対にコンフリクトが起きない merge がある。 
 fast-forward merge とは、 merge-base が ours のときに起こる merge のこと。 
 さっきの例で言うと、↓のような状態で merge すると fast-foward merge が発生する。 
 
 
 
 この状態で merge すると、Git は merge 作業をサボって、master の向き先を develop にするだけになる。 
 92 shumon.fujita
 first commit
 master.txt を追加
 README.md に
 「master」と追記
 develop.txt を追加
 master
 README.md に
 「develop」と追記
 develop

  68. Git の基礎
 コンフリクト解消は人間の手が入るため、必要な差分が消えたり、不要な差分が混入したりする可能性がある。 
 → 大前提として、コンフリクトは起きないのが 1 番。 
 


    Git には fast-forward merge という絶対にコンフリクトが起きない merge がある。 
 fast-forward merge とは、 merge-base が ours のときに起こる merge のこと。 
 さっきの例で言うと、↓のような状態で merge すると fast-foward merge が発生する。 
 
 
 
 この状態で merge すると、Git は merge 作業をサボって、master の向き先を develop にするだけになる。 
 93 shumon.fujita
 first commit
 master.txt を追加
 README.md に
 「master」と追記
 develop.txt を追加
 master
 README.md に
 「develop」と追記
 develop

  69. Git の基礎
 98 要望の多かったrebaseについて 
 rebaseでできること その1
 • ブランチの分岐元を変更する 


    
 
 
 
 developブランチを、最新のmasterから分岐したことにする。 
 
 
 

  70. Git の基礎
 99 要望の多かったrebaseについて 
 rebaseでできること その1
 • ブランチの分岐元を変更する 


    
 
 
 
 developブランチを、最新のmasterから分岐したことにする。 
 こうすると、masterにマージする際に fast-forward merge できる。 
 

  71. Git の基礎
 100 要望の多かったrebaseについて 
 rebaseでできること その1
 • ブランチの分岐元を変更する 


    
 
 
 
 developブランチを、最新のmasterから分岐したことにする。 
 こうすると、masterにマージする際に fast-forward merge できる。 
 pushしてからだとややこしいことになる可能性もあるので、やるならpush前のブランチの方が良いかも 
 

  72. Git の基礎
 102 要望の多かったrebaseについて 
 rebaseでできること その2
 • コミット履歴の修正(-iオプション) 


    ◦ コミットの並び替え
 ◦ いくつかのコミットを一つに合体 
 ◦ コミットメッセージを変更
 ◦ 過去のコミットに戻って修正 

  73. Git の基礎
 103 要望の多かったrebaseについて 
 rebaseでできること その2
 • コミット履歴の修正(-iオプション) 


    ◦ コミットの並び替え
 ◦ いくつかのコミットを一つに合体 
 ◦ コミットメッセージを変更
 ◦ 過去のコミットに戻って修正 
 $ git rebase -i HEAD~3 # 修正を行うコミットと修正コマンドを選ぶ。コミットごとに修正が完了したら以下 $ git rebase --continue # 全て修正が終わったら完了
  74. Git の基礎
 104 $ git rebase -i HEAD~3 1 pick

    2ff810a 2st commit 2 pick 80e4e22 3rd commit 3 pick 6bb05cb 4th commit 4 5 # Rebase 17c2008..6bb05cb onto 17c2008 (3 commands) 6 # 7 # Commands: 8 # p, pick <commit> = use commit 9 # r, reword <commit> = use commit, but edit the commit message 10 # e, edit <commit> = use commit, but stop for amending 11 # s, squash <commit> = use commit, but meld into previous commit 12 # f, fixup <commit> = like "squash", but discard this commit's log message 13 # x, exec <command> = run command (the rest of the line) using shell 14 # b, break = stop here (continue rebase later with 'git rebase --continue') 15 # d, drop <commit> = remove commit 16 # l, label <label> = label current HEAD with a name 17 # t, reset <label> = reset HEAD to a label ・・・
  75. Git の基礎
 105 $ git rebase -i HEAD~3 1 pick

    2ff810a 2st commit 2 pick 80e4e22 3rd commit 3 pick 6bb05cb 4th commit 4 5 # Rebase 17c2008..6bb05cb onto 17c2008 (3 commands) 6 # 7 # Commands: 8 # p, pick <commit> = use commit 9 # r, reword <commit> = use commit, but edit the commit message 10 # e, edit <commit> = use commit, but stop for amending 11 # s, squash <commit> = use commit, but meld into previous commit 12 # f, fixup <commit> = like "squash", but discard this commit's log message 13 # x, exec <command> = run command (the rest of the line) using shell 14 # b, break = stop here (continue rebase later with 'git rebase --continue') 15 # d, drop <commit> = remove commit 16 # l, label <label> = label current HEAD with a name 17 # t, reset <label> = reset HEAD to a label ・・・ ここ目的のコマンドに変 更する
  76. bisectについて
 バグが混入したコミットを二分探索で効率的に特定するためのコマンド 
 
 
 
 
 
 
 


    
 
 
 Git の基礎
 108 $ git bisect start <bad-commit> <good-commit> #チェックアウトした時点でテスト実行、もしくは動作確認 $ git bisect good (もしくは git bisect bad) #次の版にチェックアウト 1st commit 
 2nd commit 
 3rd commit 
 4th commit 
 5th commit 
 6th commit 
 7th commit 
 8th commit 
 9th commit 
 bad good checkout
  77. bisectについて
 バグが混入したコミットを二分探索で効率的に特定するためのコマンド 
 
 
 
 
 
 
 チェックは自動化させることも可

    
 
 
 
 Git の基礎
 109 $ git bisect start <bad-commit> <good-commit> #チェックアウトした時点でテスト実行、もしくは動作確認 $ git bisect good (もしくは git bisect bad) #次の版にチェックアウト 1st commit 
 2nd commit 
 3rd commit 
 4th commit 
 5th commit 
 6th commit 
 7th commit 
 8th commit 
 9th commit 
 bad good checkout $ git bisect start <bad-commit> <good-commit> $ git bisect run <テストスクリプトのファイル名 >
  78. submoduleについて
 あるプロジェクトから、別のプロジェクトを使用する必要がある時に使用 
 • サードパーティが開発したモジュール 
 • 複数のリポジトリから使われる共通モジュール 
 


    
 
 
 
 
 Git の基礎
 114 $ git submodule add https://github.com/chaconinc/DbConnector $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: .gitmodules new file: DbConnector $ git submodule status # submoduleのどのコミットハッシュを参照しているか確認できる
  79. submoduleについて
 あるプロジェクトから、別のプロジェクトを使用する必要がある時に使用 
 • サードパーティが開発したモジュール 
 • 複数のリポジトリから使われる共通モジュール 
 


    
 
 
 
 
 Git の基礎
 115 $ git submodule add https://github.com/chaconinc/DbConnector $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: .gitmodules new file: DbConnector $ git submodule status # submoduleのどのコミットハッシュを参照しているか確認できる 個人的にはパッケージングできるならその 方が好み
  80. Git 誕生秘話
 チーム開発の話をする前に、なぜこの世に Git が存在するかご存知ですか 
 → Linux を開発するため
 


    もともと Linux はメーリスに投稿されたパッチを、気合いで適用しながら開発していた 
 
 120 shumon.fujita

  81. Git 誕生秘話
 チーム開発の話をする前に、なぜこの世に Git が存在するかご存知ですか 
 → Linux を開発するため
 


    もともと Linux はメーリスに投稿されたパッチを、気合いで適用しながら開発していた 
 → 2002 年、「BitKeeper」という有料の VCS を無料で使わせてもらえることになった 
 
 121 shumon.fujita

  82. Git 誕生秘話
 チーム開発の話をする前に、なぜこの世に Git が存在するかご存知ですか 
 → Linux を開発するため
 


    もともと Linux はメーリスに投稿されたパッチを、気合いで適用しながら開発していた 
 → 2002 年、「BitKeeper」という有料の VCS を無料で使わせてもらえることになった 
 → 2005 年、なんやかんやあって、あくまで厚意で無料で使えていただけの BitKeeper を有料化されてしまった 
 
 122 shumon.fujita

  83. Git 誕生秘話
 チーム開発の話をする前に、なぜこの世に Git が存在するかご存知ですか 
 → Linux を開発するため
 


    もともと Linux はメーリスに投稿されたパッチを、気合いで適用しながら開発していた 
 → 2002 年、「BitKeeper」という有料の VCS を無料で使わせてもらえることになった 
 → 2005 年、なんやかんやあって、あくまで厚意で無料で使えていただけの BitKeeper を有料化されてしまった 
 → 他の VCS を探す必要がある 
 
 123 shumon.fujita

  84. Git 誕生秘話
 チーム開発の話をする前に、なぜこの世に Git が存在するかご存知ですか 
 → Linux を開発するため
 


    もともと Linux はメーリスに投稿されたパッチを、気合いで適用しながら開発していた 
 → 2002 年、「BitKeeper」という有料の VCS を無料で使わせてもらえることになった 
 → 2005 年、なんやかんやあって、あくまで厚意で無料で使えていただけの BitKeeper を有料化されてしまった 
 → 他の VCS を探す必要がある 
 → 他の VCS は Linux ぐらいデカいプロジェクトを扱うには遅すぎるし、開発者が大勢いる状態に対応できない 
 
 124 shumon.fujita

  85. Git 誕生秘話
 チーム開発の話をする前に、なぜこの世に Git が存在するかご存知ですか 
 → Linux を開発するため
 


    もともと Linux はメーリスに投稿されたパッチを、気合いで適用しながら開発していた 
 → 2002 年、「BitKeeper」という有料の VCS を無料で使わせてもらえることになった 
 → 2005 年、なんやかんやあって、あくまで厚意で無料で使えていただけの BitKeeper を有料化されてしまった 
 → 他の VCS を探す必要がある 
 → 他の VCS は Linux ぐらいデカいプロジェクトを扱うには遅すぎるし、開発者が大勢いる状態に対応できない 
 → リーナス・トーバルズ「自作するぞ」 
 
 125 shumon.fujita

  86. Git 誕生秘話
 チーム開発の話をする前に、なぜこの世に Git が存在するかご存知ですか 
 → Linux を開発するため
 


    もともと Linux はメーリスに投稿されたパッチを、気合いで適用しながら開発していた 
 → 2002 年、「BitKeeper」という有料の VCS を無料で使わせてもらえることになった 
 → 2005 年、なんやかんやあって、あくまで厚意で無料で使えていただけの BitKeeper を有料化されてしまった 
 → 他の VCS を探す必要がある 
 → 他の VCS は Linux ぐらいデカいプロジェクトを扱うには遅すぎるし、開発者が大勢いる状態に対応できない 
 → リーナス・トーバルズ「自作するぞ」 
 詳しくは Git の公式ドキュメントにある Git略史 を読んでみてね
 126 shumon.fujita

  87. Git の特徴
 というわけで、Git には Linux 並にデカいソフトウェアを大人数で開発するために生まれた。 
 
 その結果、Git 以前の

    VCS に比べて次のような特徴がある。 
 - 高速な merge と checkout 
 - 分散型
 - branch
 129 shumon.fujita

  88. 高速な merge と checkout
 Git の merge と checkout は、実はかなり高速

    
 特に、「履歴の遠さ」は merge や checkout の時間に 影響を与えない
 
 
 131 shumon.fujita

  89. 高速な merge と checkout
 Git の merge と checkout は、実はかなり高速

    
 特に、「履歴の遠さ」は merge や checkout の時間に 影響を与えない
 変更されているファイルの数 が支配的なのが特徴
 
 
 132 shumon.fujita

  90. 高速な merge と checkout
 Git の merge と checkout は、実はかなり高速

    
 特に、「履歴の遠さ」は merge や checkout の時間に 影響を与えない
 変更されているファイルの数 が支配的なのが特徴
 
 → 理由は後述の Git の内部構造を聞くと分かります 
 133 shumon.fujita

  91. 分散型
 Git の解説で毎回聞くやつ。 
 
 世の中のVCS(バージョン管理システム/Version Control System)には大きく分けて集中型と分散型の2つがある。 
 分散型のVCSは「リポジトリの全履歴を含めた完全なコピーをローカルに持つ」

    という意味。
 
 例えば集中型のSubversionは、リポジトリは完全にサーバが管理してる。 
 自分が触りたいファイルだけをローカルにコピーし、修正後サーバにpushする 。 
 
 138 shumon.fujita

  92. 分散型
 Git の解説で毎回聞くやつ。 
 
 世の中のVCS(バージョン管理システム/Version Control System)には大きく分けて集中型と分散型の2つがある。 
 分散型のVCSは「リポジトリの全履歴を含めた完全なコピーをローカルに持つ」

    という意味。
 
 例えば集中型のSubversionは、リポジトリは完全にサーバが管理してる。 
 自分が触りたいファイルだけをローカルにコピーし、修正後サーバにpushする 。 
 その間は他人は自分が使ってるファイルを編集することはできない。 
 
 139 shumon.fujita

  93. 分散型
 Git の解説で毎回聞くやつ。 
 
 世の中のVCS(バージョン管理システム/Version Control System)には大きく分けて集中型と分散型の2つがある。 
 分散型のVCSは「リポジトリの全履歴を含めた完全なコピーをローカルに持つ」

    という意味。
 
 例えば集中型のSubversionは、リポジトリは完全にサーバが管理してる。 
 自分が触りたいファイルだけをローカルにコピーし、修正後サーバにpushする 。 
 その間は他人は自分が使ってるファイルを編集することはできない。 
 → 大人数で開発すると開発速度が落ちる 
 
 140 shumon.fujita

  94. 分散型
 Git の解説で毎回聞くやつ。 
 
 世の中のVCS(バージョン管理システム/Version Control System)には大きく分けて集中型と分散型の2つがある。 
 分散型のVCSは「リポジトリの全履歴を含めた完全なコピーをローカルに持つ」

    という意味。
 
 例えば集中型のSubversionは、リポジトリは完全にサーバが管理してる。 
 自分が触りたいファイルだけをローカルにコピーし、修正後サーバにpushする 。 
 その間は他人は自分が使ってるファイルを編集することはできない。 
 → 大人数で開発すると開発速度が落ちる 
 → でも分散型のGitは誰がどんな修正をしていても無視して進めることができる 
 141 shumon.fujita

  95. branch
 Git は branch 機能のおかげで、大人数で並行して開発を進めることができる。 
 でも無秩序に branch を使うとコンフリクトしまくるし、どこでどの機能が実装されているのか分からない。 


    → 複雑なコンフリクトの仕方をすると、解消に失敗してバグが混入するかも。 
 → どの branch にどの機能が実装されているか分からないので、最新版がどれなのか分からない。 
 
 145 shumon.fujita

  96. branch
 Git は branch 機能のおかげで、大人数で並行して開発を進めることができる。 
 でも無秩序に branch を使うとコンフリクトしまくるし、どこでどの機能が実装されているのか分からない。 


    → 複雑なコンフリクトの仕方をすると、解消に失敗してバグが混入するかも。 
 → どの branch にどの機能が実装されているか分からないので、最新版がどれなのか分からない。 
 → そういった問題を防ぐため、branch運用には、いくつかの方法論がある。 
 146 shumon.fujita

  97. Git Flow
 Git では、おそらく最も一般的な branch 運用。 
 皆でリモートリポジトリを1つに決めて、Git を中央集権的に扱えるようにした。 


    → 集中型と分散型の良いとこ取りができる。 
 
 
 150 shumon.fujita
 https://nvie.com/posts/a-successful-git-branching-model/
  98. Git Flow
 Git では、おそらく最も一般的な branch 運用。 
 皆でリモートリポジトリを1つに決めて、Git を中央集権的に扱えるようにした。 


    → 集中型と分散型の良いとこ取りができる。 
 
 大体のチームは、Git Flow をちょっとアレンジして使ってるんじゃないかな。 
 
 151 shumon.fujita
 https://nvie.com/posts/a-successful-git-branching-model/
  99. Git Flow
 Git では、おそらく最も一般的な branch 運用。 
 皆でリモートリポジトリを1つに決めて、Git を中央集権的に扱えるようにした。 


    → 集中型と分散型の良いとこ取りができる。 
 
 大体のチームは、Git Flow をちょっとアレンジして使ってるんじゃないかな。 
 Git Flow という名前を知らなくても、慣習として Git Flow と同じようなことを 
 している人も多いと思う。
 152 shumon.fujita
 https://nvie.com/posts/a-successful-git-branching-model/
  100. Git Flow
 Git Flow では、まずリモートリポジトリを1つに決める必要がある。 
 GitHub なり GitLab なり

    BitBucket なりなんでもいい。ちなみに弊社では基本的にGitHub。 
 
 154 shumon.fujita

  101. Git Flow
 Git Flow では、まずリモートリポジトリを1つに決める必要がある。 
 GitHub なり GitLab なり

    BitBucket なりなんでもいい。ちなみに弊社では基本的にGitHub。 
 とにかくそのリモートリポジトリを開発者同士で口裏を合わせて常に正とみなす。 
 
 155 shumon.fujita

  102. Git Flow
 Git Flow では、まずリモートリポジトリを1つに決める必要がある。 
 GitHub なり GitLab なり

    BitBucket なりなんでもいい。ちなみに弊社では基本的にGitHub。 
 とにかくそのリモートリポジトリを開発者同士で口裏を合わせて常に正とみなす。 
 
 そんなの当たり前すぎて、逆にリモートリポジトリが複数ある状態なんて、よく分からない人もいるかも。 
 
 156 shumon.fujita

  103. Git Flow
 Git Flow では、まずリモートリポジトリを1つに決める必要がある。 
 GitHub なり GitLab なり

    BitBucket なりなんでもいい。ちなみに弊社では基本的にGitHub。 
 とにかくそのリモートリポジトリを開発者同士で口裏を合わせて常に正とみなす。 
 
 そんなの当たり前すぎて、逆にリモートリポジトリが複数ある状態なんて、よく分からない人もいるかも。 
 でも Git では、複数のリモートリポジトリを持つことができる。 
 157 shumon.fujita

  104. Git Flow
 Git Flow では、まずリモートリポジトリを1つに決める必要がある。 
 GitHub なり GitLab なり

    BitBucket なりなんでもいい。ちなみに弊社では基本的にGitHub。 
 とにかくそのリモートリポジトリを開発者同士で口裏を合わせて常に正とみなす。 
 
 そんなの当たり前すぎて、逆にリモートリポジトリが複数ある状態なんて、よく分からない人もいるかも。 
 でも Git では、複数のリモートリポジトリを持つことができる。 
 - GitHub ができる前から Git 使ってる OSS は自前 Git 鯖と GitHub を両方使ってたりする。 
 158 shumon.fujita

  105. Git Flow
 Git Flow では、まずリモートリポジトリを1つに決める必要がある。 
 GitHub なり GitLab なり

    BitBucket なりなんでもいい。ちなみに弊社では基本的にGitHub。 
 とにかくそのリモートリポジトリを開発者同士で口裏を合わせて常に正とみなす。 
 
 そんなの当たり前すぎて、逆にリモートリポジトリが複数ある状態なんて、よく分からない人もいるかも。 
 でも Git では、複数のリモートリポジトリを持つことができる。 
 - GitHub ができる前から Git 使ってる OSS は自前 Git 鯖と GitHub を両方使ってたりする。 
 - fork したリポジトリを、fork 元のリポジトリに追従したいときも使ったりする。 
 159 shumon.fujita

  106. Git Flow - developとmaster
 Git Flowで最も重要なのが、masterとdevelopの関係。 
 (去年 master じゃなくて

    main を使おうという動きがありましたが、 原典 は master を使っているのでこのまま行きます) 
 
 
 160 shumon.fujita
 https://nvie.com/posts/a-successful-git-branching-model/
  107. Git Flow - developとmaster
 Git Flowで最も重要なのが、masterとdevelopの関係。 
 (去年 master じゃなくて

    main を使おうという動きがありましたが、 原典 は master を使っているのでこのまま行きます) 
 
 開発は develop で行い、 master はリリース時に初めて commit される。 
 
 161 shumon.fujita
 https://nvie.com/posts/a-successful-git-branching-model/
  108. Git Flow - developとmaster
 Git Flowで最も重要なのが、masterとdevelopの関係。 
 (去年 master じゃなくて

    main を使おうという動きがありましたが、 原典 は master を使っているのでこのまま行きます) 
 
 開発は develop で行い、 master はリリース時に初めて commit される。 
 master の commit にはリリースごとに tag を打つ。 
 
 162 shumon.fujita
 https://nvie.com/posts/a-successful-git-branching-model/
  109. Git Flow - developとmaster
 Git Flowで最も重要なのが、masterとdevelopの関係。 
 (去年 master じゃなくて

    main を使おうという動きがありましたが、 原典 は master を使っているのでこのまま行きます) 
 
 開発は develop で行い、 master はリリース時に初めて commit される。 
 master の commit にはリリースごとに tag を打つ。 
 masterの先頭が常にプロダクトの最新のリリースになる。 
 
 163 shumon.fujita
 https://nvie.com/posts/a-successful-git-branching-model/
  110. Git Flow - feature
 ここから先は、全部 develop と master をサポートするための branch

    。 
 
 feature は複数人で develop を開発するときに使う。 
 
 
 165 shumon.fujita
 https://nvie.com/posts/a-successful-git-branching-model/
  111. Git Flow - feature
 ここから先は、全部 develop と master をサポートするための branch

    。 
 
 feature は複数人で develop を開発するときに使う。 
 1機能ごとに develop から branch を切る。機能の開発が終われば develop に merge する。 
 
 
 166 shumon.fujita
 https://nvie.com/posts/a-successful-git-branching-model/
  112. Git Flow - feature
 ここから先は、全部 develop と master をサポートするための branch

    。 
 
 feature は複数人で develop を開発するときに使う。 
 1機能ごとに develop から branch を切る。機能の開発が終われば develop に merge する。 
 「1 機能 = 1 feature」ルールは守ろう。複数の機能にまたがる feature はデメリットが多い。 
 
 
 167 shumon.fujita
 https://nvie.com/posts/a-successful-git-branching-model/
  113. Git Flow - feature
 ここから先は、全部 develop と master をサポートするための branch

    。 
 
 feature は複数人で develop を開発するときに使う。 
 1機能ごとに develop から branch を切る。機能の開発が終われば develop に merge する。 
 「1 機能 = 1 feature」ルールは守ろう。複数の機能にまたがる feature はデメリットが多い。 
 - どの機能がどの branch に入っているのか分かりにくい。 
 
 
 168 shumon.fujita
 https://nvie.com/posts/a-successful-git-branching-model/
  114. Git Flow - feature
 ここから先は、全部 develop と master をサポートするための branch

    。 
 
 feature は複数人で develop を開発するときに使う。 
 1機能ごとに develop から branch を切る。機能の開発が終われば develop に merge する。 
 「1 機能 = 1 feature」ルールは守ろう。複数の機能にまたがる feature はデメリットが多い。 
 - どの機能がどの branch に入っているのか分かりにくい。 
 - 差分が大きくなってコンフリクトしやすい。 
 
 
 169 shumon.fujita
 https://nvie.com/posts/a-successful-git-branching-model/
  115. Git Flow - feature
 ここから先は、全部 develop と master をサポートするための branch

    。 
 
 feature は複数人で develop を開発するときに使う。 
 1機能ごとに develop から branch を切る。機能の開発が終われば develop に merge する。 
 「1 機能 = 1 feature」ルールは守ろう。複数の機能にまたがる feature はデメリットが多い。 
 - どの機能がどの branch に入っているのか分かりにくい。 
 - 差分が大きくなってコンフリクトしやすい。 
 - revert する際は、機能単位で revert したいことがほとんど。 
 
 
 170 shumon.fujita
 https://nvie.com/posts/a-successful-git-branching-model/
  116. Git Flow - feature
 ここから先は、全部 develop と master をサポートするための branch

    。 
 
 feature は複数人で develop を開発するときに使う。 
 1機能ごとに develop から branch を切る。機能の開発が終われば develop に merge する。 
 「1 機能 = 1 feature」ルールは守ろう。複数の機能にまたがる feature はデメリットが多い。 
 - どの機能がどの branch に入っているのか分かりにくい。 
 - 差分が大きくなってコンフリクトしやすい。 
 - revert する際は、機能単位で revert したいことがほとんど。 
 
 大きい機能の場合は feature からさらに feature を切ったりもする。 
 
 171 shumon.fujita
 https://nvie.com/posts/a-successful-git-branching-model/
  117. Git Flow - feature
 ここから先は、全部 develop と master をサポートするための branch

    。 
 
 feature は複数人で develop を開発するときに使う。 
 1機能ごとに develop から branch を切る。機能の開発が終われば develop に merge する。 
 「1 機能 = 1 feature」ルールは守ろう。複数の機能にまたがる feature はデメリットが多い。 
 - どの機能がどの branch に入っているのか分かりにくい。 
 - 差分が大きくなってコンフリクトしやすい。 
 - revert する際は、機能単位で revert したいことがほとんど。 
 
 大きい機能の場合は feature からさらに feature を切ったりもする。 
 概念実証のような、最終的に製品に入れるか分からないものもここ。 
 172 shumon.fujita
 https://nvie.com/posts/a-successful-git-branching-model/
  118. Git Flow - release
 release は develop から master へ

    merge するための準備をする branch 。 
 
 
 
 
 173 shumon.fujita

  119. Git Flow - release
 release は develop から master へ

    merge するための準備をする branch 。 
 チームによっては、staging という名前で呼んでるかも。 
 
 
 
 
 174 shumon.fujita

  120. Git Flow - release
 release は develop から master へ

    merge するための準備をする branch 。 
 チームによっては、staging という名前で呼んでるかも。 
 
 具体的にどんな「準備」をするかは、プロジェクトによってまちまち 
 
 
 
 175 shumon.fujita

  121. Git Flow - release
 release は develop から master へ

    merge するための準備をする branch 。 
 チームによっては、staging という名前で呼んでるかも。 
 
 具体的にどんな「準備」をするかは、プロジェクトによってまちまち 
 - 新規実装を凍結し、bugfix のみに使う 
 
 
 
 176 shumon.fujita

  122. Git Flow - release
 release は develop から master へ

    merge するための準備をする branch 。 
 チームによっては、staging という名前で呼んでるかも。 
 
 具体的にどんな「準備」をするかは、プロジェクトによってまちまち 
 - 新規実装を凍結し、bugfix のみに使う 
 - version 表記やタイムスタンプを更新する 
 
 
 
 177 shumon.fujita

  123. Git Flow - release
 release は develop から master へ

    merge するための準備をする branch 。 
 チームによっては、staging という名前で呼んでるかも。 
 
 具体的にどんな「準備」をするかは、プロジェクトによってまちまち 
 - 新規実装を凍結し、bugfix のみに使う 
 - version 表記やタイムスタンプを更新する 
 - Apple や Google の審査のために使う 
 
 
 
 178 shumon.fujita

  124. Git Flow - release
 release は develop から master へ

    merge するための準備をする branch 。 
 チームによっては、staging という名前で呼んでるかも。 
 
 具体的にどんな「準備」をするかは、プロジェクトによってまちまち 
 - 新規実装を凍結し、bugfix のみに使う 
 - version 表記やタイムスタンプを更新する 
 - Apple や Google の審査のために使う 
 
 いずれにしても、release は master へ commit する( = ユーザの手に渡る)までの、最終段階にあたるので、 
 release で新機能を追加するのはご法度。 
 179 shumon.fujita

  125. Git Flow - hotfix
 hotfix は本番環境で発生したバグの内、緊急性の高いものを修正するための branch。 
 
 develop

    以外で、唯一 master から切られる branch 。 
 
 181 shumon.fujita
 https://nvie.com/posts/a-successful-git-branching-model/
  126. Git Flow - hotfix
 hotfix は本番環境で発生したバグの内、緊急性の高いものを修正するための branch。 
 
 develop

    以外で、唯一 master から切られる branch 。 
 修正が完了したら master と develop (or release)に merge する。 
 
 182 shumon.fujita
 https://nvie.com/posts/a-successful-git-branching-model/
  127. Git Flow - hotfix
 hotfix は本番環境で発生したバグの内、緊急性の高いものを修正するための branch。 
 
 develop

    以外で、唯一 master から切られる branch 。 
 修正が完了したら master と develop (or release)に merge する。 
 
 hotfix から master を更新した場合は、patch バージョンを上げることが多い。 
 (1.2 → 1.3 ではなく、1.2 → 1.2.1) 
 183 shumon.fujita
 https://nvie.com/posts/a-successful-git-branching-model/
  128. Git Flow
 ここまでの話を全部まとめると、右の図になる。 
 
 前述の通り、大体のチームでは Git Flowをそのままではなく、 
 ちょっとアレンジして使っていると思う。

    
 
 他にもGitHub Flowとか、トランクベース開発などの手法もある。 
 
 
 
 187 https://nvie.com/posts/a-successful-git-branching-model/
  129. Git Flow
 ここまでの話を全部まとめると、右の図になる。 
 
 前述の通り、大体のチームでは Git Flowをそのままではなく、 
 ちょっとアレンジして使っていると思う。

    
 
 他にもGitHub Flowとか、トランクベース開発などの手法もある。 
 
 組織やリポジトリの特性などから適したものを選んで行ってください。 
 
 
 
 188 https://nvie.com/posts/a-successful-git-branching-model/
  130. GitHub について
 Git 単体で使うのではなく、リポジトリホスティングサービスと併用することで Git は真価を発揮する。 
 弊社では GitHub を使っているので、GitHub

    の機能について話します。 
 
 GitHub は Git をチームで使うにあたって便利な機能がいっぱい入っている 
 
 
 
 192 shumon.fujita

  131. GitHub について
 Git 単体で使うのではなく、リポジトリホスティングサービスと併用することで Git は真価を発揮する。 
 弊社では GitHub を使っているので、GitHub

    の機能について話します。 
 
 GitHub は Git をチームで使うにあたって便利な機能がいっぱい入っている 
 基本的な機能はリポジトリのトップページのタブでまとめられている。 
 
 
 
 193 shumon.fujita

  132. GitHub について
 Git 単体で使うのではなく、リポジトリホスティングサービスと併用することで Git は真価を発揮する。 
 弊社では GitHub を使っているので、GitHub

    の機能について話します。 
 
 GitHub は Git をチームで使うにあたって便利な機能がいっぱい入っている 
 基本的な機能はリポジトリのトップページのタブでまとめられている。 
 でも意外と全部のタブ開いたことない人もいるんじゃないかな。 
 
 
 
 194 shumon.fujita

  133. GitHub について
 Git 単体で使うのではなく、リポジトリホスティングサービスと併用することで Git は真価を発揮する。 
 弊社では GitHub を使っているので、GitHub

    の機能について話します。 
 
 GitHub は Git をチームで使うにあたって便利な機能がいっぱい入っている 
 基本的な機能はリポジトリのトップページのタブでまとめられている。 
 でも意外と全部のタブ開いたことない人もいるんじゃないかな。 
 
 
 まずはIssuesの機能から解説していく。 
 
 195 shumon.fujita

  134. Issue について
 気になったことをなんでもMarkdownで書いておくところ。 
 (実際の運用はチームによるけど大体のところは何書いても良いと思う) 
 ここに実タスクを並べて、後述の Projectsで管理するチームもあれば、
 「テストが遅いから改善したい」とか「あの負債をどうやって解消しよう」とかの 


    相談事を書いて議論の土台にするチームもある。
 ラベルをつけて、種類別に整理しやすくしたり、
 マイルストーンをつけて、いつまでに対応するべきなのかを明確化 したり、
 特定のissueに誰かをassignして対応を任せたり。
 
 202 shumon.fujita

  135. Issue について
 気になったことをなんでもMarkdownで書いておくところ。 
 (実際の運用はチームによるけど大体のところは何書いても良いと思う) 
 ここに実タスクを並べて、後述の Projectsで管理するチームもあれば、
 「テストが遅いから改善したい」とか「あの負債をどうやって解消しよう」とかの 


    相談事を書いて議論の土台にするチームもある。
 ラベルをつけて、種類別に整理しやすくしたり、
 マイルストーンをつけて、いつまでに対応するべきなのかを明確化 したり、
 特定のissueに誰かをassignして対応を任せたり。
 まあいっぱいできる。
 203 shumon.fujita

  136. Pull Request について
 GitHub 関連の機能で一番重要。 
 
 特定の branch や、fork

    元のリポジトリに、「私がやった作業を取り込んでくれ」とお願いを出せる機能。 
 
 
 205 shumon.fujita

  137. Pull Request について
 GitHub 関連の機能で一番重要。 
 
 特定の branch や、fork

    元のリポジトリに、「私がやった作業を取り込んでくれ」とお願いを出せる機能。 
 → 元々は fork 元のリポジトリにお願いする機能なので “Merge Request” ではなく “Pull Request”
 
 
 206 shumon.fujita

  138. Pull Request について
 GitHub 関連の機能で一番重要。 
 
 特定の branch や、fork

    元のリポジトリに、「私がやった作業を取り込んでくれ」とお願いを出せる機能。 
 → 元々は fork 元のリポジトリにお願いする機能なので “Merge Request” ではなく “Pull Request”
 
 お願いされた側は取り込む前に差分をよく吟味し、大丈夫そうなら merge して差分を取り込む。 
 
 207 shumon.fujita

  139. Pull Request について
 GitHub 関連の機能で一番重要。 
 
 特定の branch や、fork

    元のリポジトリに、「私がやった作業を取り込んでくれ」とお願いを出せる機能。 
 → 元々は fork 元のリポジトリにお願いする機能なので “Merge Request” ではなく “Pull Request”
 
 お願いされた側は取り込む前に差分をよく吟味し、大丈夫そうなら merge して差分を取り込む。 
 ダメそうならダメなポイントを指摘してあげる。 
 
 208 shumon.fujita

  140. Pull Request について
 GitHub 関連の機能で一番重要。 
 
 特定の branch や、fork

    元のリポジトリに、「私がやった作業を取り込んでくれ」とお願いを出せる機能。 
 → 元々は fork 元のリポジトリにお願いする機能なので “Merge Request” ではなく “Pull Request”
 
 お願いされた側は取り込む前に差分をよく吟味し、大丈夫そうなら merge して差分を取り込む。 
 ダメそうならダメなポイントを指摘してあげる。 
 ↑いわゆるコードレビュー
 209 shumon.fujita

  141. PR を出す側の注意点
 - できるだけ細かい単位で PR を出すよう心がける 
 - 巨大 PR

    はレビューに時間がかかる 
 - レビューに時間がかかると merge までの時間も当然伸びる 
 213 shumon.fujita

  142. PR を出す側の注意点
 - できるだけ細かい単位で PR を出すよう心がける 
 - 巨大 PR

    はレビューに時間がかかる 
 - レビューに時間がかかると merge までの時間も当然伸びる 
 - 別の PR がどんどん先に merge されていく 
 
 214 shumon.fujita

  143. PR を出す側の注意点
 - できるだけ細かい単位で PR を出すよう心がける 
 - 巨大 PR

    はレビューに時間がかかる 
 - レビューに時間がかかると merge までの時間も当然伸びる 
 - 別の PR がどんどん先に merge されていく 
 - その結果コンフリクトする
 215 shumon.fujita

  144. PR を出す側の注意点
 - できるだけ細かい単位で PR を出すよう心がける 
 - 巨大 PR

    はレビューに時間がかかる 
 - レビューに時間がかかると merge までの時間も当然伸びる 
 - 別の PR がどんどん先に merge されていく 
 - その結果コンフリクトする
 - さらにコンフリクトの解消に失敗してバグるかも 
 
 216 shumon.fujita

  145. PR を出す側の注意点
 - できるだけ細かい単位で PR を出すよう心がける 
 - 巨大 PR

    はレビューに時間がかかる 
 - レビューに時間がかかると merge までの時間も当然伸びる 
 - 別の PR がどんどん先に merge されていく 
 - その結果コンフリクトする
 - さらにコンフリクトの解消に失敗してバグるかも 
 - 巨大にならざるをえないときは、途中でレビューしてもらう 
 217 shumon.fujita

  146. PR を出す側の注意点
 - できるだけ細かい単位で PR を出すよう心がける 
 - 巨大 PR

    はレビューに時間がかかる 
 - レビューに時間がかかると merge までの時間も当然伸びる 
 - 別の PR がどんどん先に merge されていく 
 - その結果コンフリクトする
 - さらにコンフリクトの解消に失敗してバグるかも 
 - 巨大にならざるをえないときは、途中でレビューしてもらう 
 - Git Flow で少し話をした、feature から feature を切るテク 
 
 218 shumon.fujita

  147. PR を出す側の注意点
 - できるだけ細かい単位で PR を出すよう心がける 
 - 巨大 PR

    はレビューに時間がかかる 
 - レビューに時間がかかると merge までの時間も当然伸びる 
 - 別の PR がどんどん先に merge されていく 
 - その結果コンフリクトする
 - さらにコンフリクトの解消に失敗してバグるかも 
 - 巨大にならざるをえないときは、途中でレビューしてもらう 
 - Git Flow で少し話をした、feature から feature を切るテク 
 - 最初の feature には WIP をタイトルに付けたり、draft PR として出したりすると ◦ 
 219 shumon.fujita

  148. PR を出す側の注意点
 - できるだけ細かい単位で PR を出すよう心がける 
 - 巨大 PR

    はレビューに時間がかかる 
 - レビューに時間がかかると merge までの時間も当然伸びる 
 - 別の PR がどんどん先に merge されていく 
 - その結果コンフリクトする
 - さらにコンフリクトの解消に失敗してバグるかも 
 - 巨大にならざるをえないときは、途中でレビューしてもらう 
 - Git Flow で少し話をした、feature から feature を切るテク 
 - 最初の feature には WIP をタイトルに付けたり、draft PR として出したりすると ◦ 
 - コミットログはできるだけ綺麗にしておこう 
 
 220 shumon.fujita

  149. PR を出す側の注意点
 - できるだけ細かい単位で PR を出すよう心がける 
 - 巨大 PR

    はレビューに時間がかかる 
 - レビューに時間がかかると merge までの時間も当然伸びる 
 - 別の PR がどんどん先に merge されていく 
 - その結果コンフリクトする
 - さらにコンフリクトの解消に失敗してバグるかも 
 - 巨大にならざるをえないときは、途中でレビューしてもらう 
 - Git Flow で少し話をした、feature から feature を切るテク 
 - 最初の feature には WIP をタイトルに付けたり、draft PR として出したりすると ◦ 
 - コミットログはできるだけ綺麗にしておこう 
 - こまめにコミットし、できれば最後に git rebase -i で体裁を整えよう
 221 shumon.fujita

  150. PR を出す側の注意点
 - できるだけ細かい単位で PR を出すよう心がける 
 - 巨大 PR

    はレビューに時間がかかる 
 - レビューに時間がかかると merge までの時間も当然伸びる 
 - 別の PR がどんどん先に merge されていく 
 - その結果コンフリクトする
 - さらにコンフリクトの解消に失敗してバグるかも 
 - 巨大にならざるをえないときは、途中でレビューしてもらう 
 - Git Flow で少し話をした、feature から feature を切るテク 
 - 最初の feature には WIP をタイトルに付けたり、draft PR として出したりすると ◦ 
 - コミットログはできるだけ綺麗にしておこう 
 - こまめにコミットし、できれば最後に git rebase -i で体裁を整えよう
 - 厳しめの OSS だと fast-forward merge できないだけでもダメって言われたりする 
 
 222 shumon.fujita

  151. PR を出す側の注意点
 - できるだけ細かい単位で PR を出すよう心がける 
 - 巨大 PR

    はレビューに時間がかかる 
 - レビューに時間がかかると merge までの時間も当然伸びる 
 - 別の PR がどんどん先に merge されていく 
 - その結果コンフリクトする
 - さらにコンフリクトの解消に失敗してバグるかも 
 - 巨大にならざるをえないときは、途中でレビューしてもらう 
 - Git Flow で少し話をした、feature から feature を切るテク 
 - 最初の feature には WIP をタイトルに付けたり、draft PR として出したりすると ◦ 
 - コミットログはできるだけ綺麗にしておこう 
 - こまめにコミットし、できれば最後に git rebase -i で体裁を整えよう
 - 厳しめの OSS だと fast-forward merge できないだけでもダメって言われたりする 
 - この辺は賛否あるので所属チームに合わせると良さそう 
 223 shumon.fujita

  152. PR を見る側の注意点
 - 機械的にチェックできる部分は CI に任せる 
 - テストはしっかり書こうね
 -

    コードフォーマッタを使うと、細かいスペースの差分とかが生まれなくて便利 
 227 shumon.fujita

  153. PR を見る側の注意点
 - 機械的にチェックできる部分は CI に任せる 
 - テストはしっかり書こうね
 -

    コードフォーマッタを使うと、細かいスペースの差分とかが生まれなくて便利 
 - 人間が見るべきポイントにしっかり集中する 
 228 shumon.fujita

  154. PR を見る側の注意点
 - 機械的にチェックできる部分は CI に任せる 
 - テストはしっかり書こうね
 -

    コードフォーマッタを使うと、細かいスペースの差分とかが生まれなくて便利 
 - 人間が見るべきポイントにしっかり集中する 
 - 仕様の穴、セキュリティ/法的にヤバそうなところ 
 
 229 shumon.fujita

  155. PR を見る側の注意点
 - 機械的にチェックできる部分は CI に任せる 
 - テストはしっかり書こうね
 -

    コードフォーマッタを使うと、細かいスペースの差分とかが生まれなくて便利 
 - 人間が見るべきポイントにしっかり集中する 
 - 仕様の穴、セキュリティ/法的にヤバそうなところ 
 - 負債になりそうなところ、設計的にまずいところ、計算量・レイテンシ的に厳しいところ 
 230 shumon.fujita

  156. PR を見る側の注意点
 - 機械的にチェックできる部分は CI に任せる 
 - テストはしっかり書こうね
 -

    コードフォーマッタを使うと、細かいスペースの差分とかが生まれなくて便利 
 - 人間が見るべきポイントにしっかり集中する 
 - 仕様の穴、セキュリティ/法的にヤバそうなところ 
 - 負債になりそうなところ、設計的にまずいところ、計算量・レイテンシ的に厳しいところ 
 - 意外と実装中に気づかなかった問題点が見つかることも多いので、自分のPRもレビューしておくと吉 
 231 shumon.fujita

  157. PR を見る側の注意点
 - 機械的にチェックできる部分は CI に任せる 
 - テストはしっかり書こうね
 -

    コードフォーマッタを使うと、細かいスペースの差分とかが生まれなくて便利 
 - 人間が見るべきポイントにしっかり集中する 
 - 仕様の穴、セキュリティ/法的にヤバそうなところ 
 - 負債になりそうなところ、設計的にまずいところ、計算量・レイテンシ的に厳しいところ 
 - 意外と実装中に気づかなかった問題点が見つかることも多いので、自分のPRもレビューしておくと吉 
 - なかなか人間の目ではバグは見つかりません!高品質なコードは高品質なテストから 
 232 shumon.fujita

  158. PR を見る側の注意点
 - 機械的にチェックできる部分は CI に任せる 
 - テストはしっかり書こうね
 -

    コードフォーマッタを使うと、細かいスペースの差分とかが生まれなくて便利 
 - 人間が見るべきポイントにしっかり集中する 
 - 仕様の穴、セキュリティ/法的にヤバそうなところ 
 - 負債になりそうなところ、設計的にまずいところ、計算量・レイテンシ的に厳しいところ 
 - 意外と実装中に気づかなかった問題点が見つかることも多いので、自分のPRもレビューしておくと吉 
 - なかなか人間の目ではバグは見つかりません!高品質なコードは高品質なテストから 
 - 実装者のことを思いやる
 233 shumon.fujita

  159. PR を見る側の注意点
 - 機械的にチェックできる部分は CI に任せる 
 - テストはしっかり書こうね
 -

    コードフォーマッタを使うと、細かいスペースの差分とかが生まれなくて便利 
 - 人間が見るべきポイントにしっかり集中する 
 - 仕様の穴、セキュリティ/法的にヤバそうなところ 
 - 負債になりそうなところ、設計的にまずいところ、計算量・レイテンシ的に厳しいところ 
 - 意外と実装中に気づかなかった問題点が見つかることも多いので、自分のPRもレビューしておくと吉 
 - なかなか人間の目ではバグは見つかりません!高品質なコードは高品質なテストから 
 - 実装者のことを思いやる
 - 「このコードは良くない」のような抽象的な言い方はやめて、どこがどういう理由で良くないのか書く 
 234 shumon.fujita

  160. PR を見る側の注意点
 - 機械的にチェックできる部分は CI に任せる 
 - テストはしっかり書こうね
 -

    コードフォーマッタを使うと、細かいスペースの差分とかが生まれなくて便利 
 - 人間が見るべきポイントにしっかり集中する 
 - 仕様の穴、セキュリティ/法的にヤバそうなところ 
 - 負債になりそうなところ、設計的にまずいところ、計算量・レイテンシ的に厳しいところ 
 - 意外と実装中に気づかなかった問題点が見つかることも多いので、自分のPRもレビューしておくと吉 
 - なかなか人間の目ではバグは見つかりません!高品質なコードは高品質なテストから 
 - 実装者のことを思いやる
 - 「このコードは良くない」のような抽象的な言い方はやめて、どこがどういう理由で良くないのか書く 
 - 合わせて、どういう方法なら良いのかも書けると議論もしやすい 
 
 235 shumon.fujita

  161. PR を見る側の注意点
 - 機械的にチェックできる部分は CI に任せる 
 - テストはしっかり書こうね
 -

    コードフォーマッタを使うと、細かいスペースの差分とかが生まれなくて便利 
 - 人間が見るべきポイントにしっかり集中する 
 - 仕様の穴、セキュリティ/法的にヤバそうなところ 
 - 負債になりそうなところ、設計的にまずいところ、計算量・レイテンシ的に厳しいところ 
 - 意外と実装中に気づかなかった問題点が見つかることも多いので、自分のPRもレビューしておくと吉 
 - なかなか人間の目ではバグは見つかりません!高品質なコードは高品質なテストから 
 - 実装者のことを思いやる
 - 「このコードは良くない」のような抽象的な言い方はやめて、どこがどういう理由で良くないのか書く 
 - 合わせて、どういう方法なら良いのかも書けると議論もしやすい 
 - 定量的な指標もあったりするのでそういうのも活用すると良いかも 
 236 shumon.fujita

  162. PR を見る側の注意点
 - 機械的にチェックできる部分は CI に任せる 
 - テストはしっかり書こうね
 -

    コードフォーマッタを使うと、細かいスペースの差分とかが生まれなくて便利 
 - 人間が見るべきポイントにしっかり集中する 
 - 仕様の穴、セキュリティ/法的にヤバそうなところ 
 - 負債になりそうなところ、設計的にまずいところ、計算量・レイテンシ的に厳しいところ 
 - 意外と実装中に気づかなかった問題点が見つかることも多いので、自分のPRもレビューしておくと吉 
 - なかなか人間の目ではバグは見つかりません!高品質なコードは高品質なテストから 
 - 実装者のことを思いやる
 - 「このコードは良くない」のような抽象的な言い方はやめて、どこがどういう理由で良くないのか書く 
 - 合わせて、どういう方法なら良いのかも書けると議論もしやすい 
 - 定量的な指標もあったりするのでそういうのも活用すると良いかも 
 - テキストでの指摘は、結構キツく感じてしまいがちなので、普段の1.5倍やさしい言葉使いをしよう 
 237 shumon.fujita

  163. PR を見る側の注意点
 - 機械的にチェックできる部分は CI に任せる 
 - テストはしっかり書こうね
 -

    コードフォーマッタを使うと、細かいスペースの差分とかが生まれなくて便利 
 - 人間が見るべきポイントにしっかり集中する 
 - 仕様の穴、セキュリティ/法的にヤバそうなところ 
 - 負債になりそうなところ、設計的にまずいところ、計算量・レイテンシ的に厳しいところ 
 - 意外と実装中に気づかなかった問題点が見つかることも多いので、自分のPRもレビューしておくと吉 
 - なかなか人間の目ではバグは見つかりません!高品質なコードは高品質なテストから 
 - 実装者のことを思いやる
 - 「このコードは良くない」のような抽象的な言い方はやめて、どこがどういう理由で良くないのか書く 
 - 合わせて、どういう方法なら良いのかも書けると議論もしやすい 
 - 定量的な指標もあったりするのでそういうのも活用すると良いかも 
 - テキストでの指摘は、結構キツく感じてしまいがちなので、普段の1.5倍やさしい言葉使いをしよう 
 - HRT(謙虚・尊敬・信頼)の原則 
 238 shumon.fujita

  164. Actions について
 GitHub が提供している CI/CD 環境。 
 他のサービスと連携させる必要がないので、簡単に使える + パブリックリポジトリでは無料で使える点がメリット。

    
 また、汎用的な部分は GitHub で公開されている Action を利用することができることもありがたい。 
 
 
 241 shumon.fujita

  165. Actions について
 GitHub が提供している CI/CD 環境。 
 他のサービスと連携させる必要がないので、簡単に使える + パブリックリポジトリでは無料で使える点がメリット。

    
 また、汎用的な部分は GitHub で公開されている Action を利用することができることもありがたい。 
 
 hook したいイベントとワークフローを書いた yaml を .github/workflows/ に配置すると、勝手に走ってくれる。 
 
 242 shumon.fujita

  166. Actions について
 GitHub が提供している CI/CD 環境。 
 他のサービスと連携させる必要がないので、簡単に使える + パブリックリポジトリでは無料で使える点がメリット。

    
 また、汎用的な部分は GitHub で公開されている Action を利用することができることもありがたい。 
 
 hook したいイベントとワークフローを書いた yaml を .github/workflows/ に配置すると、勝手に走ってくれる。 
 → 具体的な書き方は 公式ドキュメント を読んでください。
 
 243 shumon.fujita

  167. Actions について
 GitHub が提供している CI/CD 環境。 
 他のサービスと連携させる必要がないので、簡単に使える + パブリックリポジトリでは無料で使える点がメリット。

    
 また、汎用的な部分は GitHub で公開されている Action を利用することができることもありがたい。 
 
 hook したいイベントとワークフローを書いた yaml を .github/workflows/ に配置すると、勝手に走ってくれる。 
 → 具体的な書き方は 公式ドキュメント を読んでください。
 
 244 shumon.fujita

  168. Projects について
 カンバンスタイルのタスク管理ツール。 
 アジャイルとかスクラム開発でよく使う。 
 
 
 issue や

    PR を付箋のようにタブを移動 
 させて進捗状況を可視化できる。 
 
 
 247 shumon.fujita

  169. Projects について
 カンバンスタイルのタスク管理ツール。 
 アジャイルとかスクラム開発でよく使う。 
 
 
 issue や

    PR を付箋のようにタブを移動 
 させて進捗状況を可視化できる。 
 
 機能も少ないため、実際にはあまり使っている部署はないかも(?) 
 
 
 248 shumon.fujita

  170. Projects について
 カンバンスタイルのタスク管理ツール。 
 アジャイルとかスクラム開発でよく使う。 
 
 
 issue や

    PR を付箋のようにタブを移動 
 させて進捗状況を可視化できる。 
 
 機能も少ないため、実際にはあまり使っている部署はないかも(?) 
 ZenHubという有料拡張ツールつかうとかなり便利になる。 
 
 249 shumon.fujita

  171. Security について
 主に↓の 3 つの機能についてのあれこれをするタブ。 
 - Security Policy
 -

    Security Advisories
 - Dependabot
 
 Security Policy は脆弱性報告の手順を Markdown で書いておく。 
 
 
 
 254 shumon.fujita

  172. Security について
 主に↓の 3 つの機能についてのあれこれをするタブ。 
 - Security Policy
 -

    Security Advisories
 - Dependabot
 
 Security Policy は脆弱性報告の手順を Markdown で書いておく。 
 Security Advisories は非公開の issue のようなもので、脆弱性が対策されるまでは秘匿した状態で議論し、 
 対応パッチがリリースされると、その議論を公開できる。 
 
 
 255 shumon.fujita

  173. Security について
 主に↓の 3 つの機能についてのあれこれをするタブ。 
 - Security Policy
 -

    Security Advisories
 - Dependabot
 
 Security Policy は脆弱性報告の手順を Markdown で書いておく。 
 Security Advisories は非公開の issue のようなもので、脆弱性が対策されるまでは秘匿した状態で議論し、 
 対応パッチがリリースされると、その議論を公開できる。 
 Dependabot はコードから依存パッケージのバージョンを解析して、脆弱性があればアラートを飛ばしてくれる。 
 
 
 256 shumon.fujita

  174. Security について
 主に↓の 3 つの機能についてのあれこれをするタブ。 
 - Security Policy
 -

    Security Advisories
 - Dependabot
 
 Security Policy は脆弱性報告の手順を Markdown で書いておく。 
 Security Advisories は非公開の issue のようなもので、脆弱性が対策されるまでは秘匿した状態で議論し、 
 対応パッチがリリースされると、その議論を公開できる。 
 Dependabot はコードから依存パッケージのバージョンを解析して、脆弱性があればアラートを飛ばしてくれる。 
 
 → Dependabot 以外はパブリックリポジトリでしか使い道がないので、基本的にはOSSのための機能。 
 257 shumon.fujita

  175. Insights について
 リポジトリの活発度を色々な指標で確認できる場所。 
 
 時系列でコミット数や差分の量がグラフ化されていたり、リポジトリの色々な統計情報が見られる。 
 
 自分のリポジトリでこのタブを使うことはあんまりない。 


    
 新しいライブラリやツールの導入を検討しているとき、それが GitHub でホストされているならこのタブを見ると、 
 どれくらいメンテされているのかが一目瞭然なので、ぜひ使ってみてね。 
 261 shumon.fujita

  176. Settings について
 リポジトリの設定を変えるタブ(それはそう) 
 
 各種機能の on/off や、Secretsの登録、デフォルトブランチの変更、PRのマージに関するルールの設定など色々できる。 
 


    おそらく開発中に最もよく使うのは Branch protection rules。
 指定した正規表現にマッチした branch に対して、PR を経ない直接の push や force push を禁止したり...etc 
 
 
 265 shumon.fujita

  177. Settings について
 リポジトリの設定を変えるタブ(それはそう) 
 
 各種機能の on/off や、Secretsの登録、デフォルトブランチの変更、PRのマージに関するルールの設定など色々できる。 
 


    おそらく開発中に最もよく使うのは Branch protection rules。
 指定した正規表現にマッチした branch に対して、PR を経ない直接の push や force push を禁止したり...etc 
 master(main) と develop には、大体なんらかのルールが設定されていると思う。 
 
 
 266 shumon.fujita

  178. Settings について
 リポジトリの設定を変えるタブ(それはそう) 
 
 各種機能の on/off や、Secretsの登録、デフォルトブランチの変更、PRのマージに関するルールの設定など色々できる。 
 


    おそらく開発中に最もよく使うのは Branch protection rules。
 指定した正規表現にマッチした branch に対して、PR を経ない直接の push や force push を禁止したり...etc 
 master(main) と develop には、大体なんらかのルールが設定されていると思う。 
 
 private → public の変更、オーナー権限の委譲、リポジトリの削除などの 危険な操作もあるので注意 。
 267 shumon.fujita

  179. Git の内部構造
 Git をよく使っていても、実は全然 Git のことを理解できていない 
 
 - commit

    って親 commit との 差分を保存してるんでしょ
 - branch って分かれた枝のことでしょ
 - reset って commit をなかったことにするコマンドでしょ
 
 
 270 shumon.fujita

  180. Git の内部構造
 Git をよく使っていても、実は全然 Git のことを理解できていない 
 
 - commit

    って親 commit との 差分を保存してるんでしょ
 - branch って分かれた枝のことでしょ
 - reset って commit をなかったことにするコマンドでしょ
 
 ↑は全部間違い
 
 271 shumon.fujita

  181. Git の内部構造
 Git をよく使っていても、実は全然 Git のことを理解できていない 
 
 - commit

    って親 commit との 差分を保存してるんでしょ
 - branch って分かれた枝のことでしょ
 - reset って commit をなかったことにするコマンドでしょ
 
 ↑は全部間違い
 自分も学生時代は勘違いしたまま使ってた 
 
 272 shumon.fujita

  182. Git の内部構造
 Git をよく使っていても、実は全然 Git のことを理解できていない 
 
 - commit

    って親 commit との 差分を保存してるんでしょ
 - branch って分かれた枝のことでしょ
 - reset って commit をなかったことにするコマンドでしょ
 
 ↑は全部間違い
 自分も学生時代は勘違いしたまま使ってた 
 ここからの話を聞けば「reset や rebase 叩くときは毎回検索してコピペしてる 」みたいな状況を脱せるはず 
 273 shumon.fujita

  183. 278 Git を使っていると、大きく3つの段階を踏んで commit する 
 1. コードを編集する
 2. 編集したコードを

    add する 
 3. commit する
 2 と 3 のときに、Git 内部で一体何が起こっているのかを追っていく 
 
 コミットの仕組み
 shumon.fujita

  184. こんなリポジトリを用意して実験してみる。 
 
 $ tree . └── README.md 0 directories,

    1 file 
 ルートに README.md があるだけ。 
 279 コミットの仕組み
 shumon.fujita

  185. 編集したコードを add すると、内部的には何が起こっているのか 
 → 教科書的な回答は「コミットに含めたいファイルを index に登録している」 
 


    具体的に index はどこにあるかというと、.git/index に保存されている。 
 
 282 コミットの仕組み
 shumon.fujita

  186. 編集したコードを add すると、内部的には何が起こっているのか 
 → 教科書的な回答は「コミットに含めたいファイルを index に登録している」 
 


    具体的に index はどこにあるかというと、.git/index に保存されている。 
 とりあえず cat してみる。
 $ cat .git/index DIRC`m�� \D�`m�� \D����_A�</�S]:7��U��W���V�9� README.mdTREE1 0 Z��� �c�ؤ�c$-�Y�T1`^:qȋ�r��g�p;��T�� 
 283 コミットの仕組み
 shumon.fujita

  187. 編集したコードを add すると、内部的には何が起こっているのか 
 → 教科書的な回答は「コミットに含めたいファイルを index に登録している」 
 


    具体的に index はどこにあるかというと、.git/index に保存されている。 
 とりあえず cat してみる。バイナリファイルで文字化けしてるけど、それっぽい文字列が見える。 
 $ cat .git/index DIRC`m�� \D�`m�� \D����_A�</�S]:7��U��W���V�9� README.mdTREE1 0 Z��� �c�ؤ�c$-�Y�T1`^:qȋ�r��g�p;��T�� 
 284 コミットの仕組み
 shumon.fujita

  188. index の中身を確認するコマンドがあるので、それで確認してみる。 
 
 $ git ls-files --stage 100644 e2022389da0c18f0c8a0e2f9b27d58d197f41b32

    0 README.md 
 
 288 コミットの仕組み
 shumon.fujita
 ファイルの種類
 +
 パーミッション

  189. index の中身を確認するコマンドがあるので、それで確認してみる。 
 
 $ git ls-files --stage 100644 e2022389da0c18f0c8a0e2f9b27d58d197f41b32

    0 README.md 
 
 289 コミットの仕組み
 shumon.fujita
 ファイルの種類
 +
 パーミッション
 blob ハッシュ(後述) 

  190. index の中身を確認するコマンドがあるので、それで確認してみる。 
 
 $ git ls-files --stage 100644 e2022389da0c18f0c8a0e2f9b27d58d197f41b32

    0 README.md 
 
 290 コミットの仕組み
 shumon.fujita
 ファイルの種類
 +
 パーミッション
 blob ハッシュ(後述) 
 コンフリクトフラグ
 (0ならコンフリクトなし)

  191. index の中身を確認するコマンドがあるので、それで確認してみる。 
 
 $ git ls-files --stage 100644 e2022389da0c18f0c8a0e2f9b27d58d197f41b32

    0 README.md 
 
 291 コミットの仕組み
 shumon.fujita
 ファイルの種類
 +
 パーミッション
 blob ハッシュ(後述) 
 コンフリクトフラグ
 (0ならコンフリクトなし)
 ファイル名

  192. index の中身を確認するコマンドがあるので、それで確認してみる。 
 
 $ git ls-files --stage 100644 e2022389da0c18f0c8a0e2f9b27d58d197f41b32

    0 README.md 
 ファイル名と一緒に何やら色んな情報が出てくる。 
 
 292 コミットの仕組み
 shumon.fujita
 ファイルの種類
 +
 パーミッション
 blob ハッシュ(後述) 
 コンフリクトフラグ
 (0ならコンフリクトなし)
 ファイル名

  193. index の中身を確認するコマンドがあるので、それで確認してみる。 
 
 $ git ls-files --stage 100644 e2022389da0c18f0c8a0e2f9b27d58d197f41b32

    0 README.md 
 ファイル名と一緒に何やら色んな情報が出てくる。 
 
 ちなみに index は、ここに表示されていない情報も持っている。 
 293 コミットの仕組み
 shumon.fujita
 ファイルの種類
 +
 パーミッション
 blob ハッシュ(後述) 
 コンフリクトフラグ
 (0ならコンフリクトなし)
 ファイル名

  194. index の中身を確認するコマンドがあるので、それで確認してみる。 
 
 $ git ls-files --stage 100644 e2022389da0c18f0c8a0e2f9b27d58d197f41b32

    0 README.md 
 ファイル名と一緒に何やら色んな情報が出てくる。 
 
 ちなみに index は、ここに表示されていない情報も持っている。 
 気になる人は --debug を付けると index が持ってる全情報を確認できる(詳しくは index-format.txt 参照)
 294 コミットの仕組み
 shumon.fujita
 ファイルの種類
 +
 パーミッション
 blob ハッシュ(後述) 
 コンフリクトフラグ
 (0ならコンフリクトなし)
 ファイル名

  195. 297 blob ハッシュってなに?→ Git に管理されている オブジェクトの 1 種(の key) のこと。


    Git には様々なデータを、「オブジェクト」と呼ばれる概念で表現している。 
 
 コミットの仕組み
 shumon.fujita

  196. 298 blob ハッシュってなに?→ Git に管理されている オブジェクトの 1 種(の key) のこと。


    Git には様々なデータを、「オブジェクト」と呼ばれる概念で表現している。 
 オブジェクトには以下の 4 種類がある。 
 - commit オブジェクト
 - コミットの情報が入っているオブジェクト 
 - tree オブジェクト
 - ディレクトリの情報が入っているオブジェクト 
 - blob オブジェクト
 - ファイルの情報が入っているオブジェクト 
 - tag オブジェクト
 - annotated tag の情報が入っているオブジェクト 
 
 
 コミットの仕組み
 shumon.fujita

  197. 299 blob ハッシュってなに?→ Git に管理されている オブジェクトの 1 種(の key) のこと。


    Git には様々なデータを、「オブジェクト」と呼ばれる概念で表現している。 
 オブジェクトには以下の 4 種類がある。 
 - commit オブジェクト
 - コミットの情報が入っているオブジェクト 
 - tree オブジェクト
 - ディレクトリの情報が入っているオブジェクト 
 - blob オブジェクト
 - ファイルの情報が入っているオブジェクト 
 - tag オブジェクト
 - annotated tag の情報が入っているオブジェクト 
 
 
 コミットの仕組み
 shumon.fujita

  198. 300 blob ハッシュってなに?→ Git に管理されている オブジェクトの 1 種(の key) のこと。


    Git には様々なデータを、「オブジェクト」と呼ばれる概念で表現している。 
 オブジェクトには以下の 4 種類がある。 
 - commit オブジェクト
 - コミットの情報が入っているオブジェクト 
 - tree オブジェクト
 - ディレクトリの情報が入っているオブジェクト 
 - blob オブジェクト
 - ファイルの情報が入っているオブジェクト 
 - tag オブジェクト
 - annotated tag の情報が入っているオブジェクト 
 
 
 コミットの仕組み
 shumon.fujita

  199. 301 blob ハッシュってなに?→ Git に管理されている オブジェクトの 1 種(の key) のこと。


    Git には様々なデータを、「オブジェクト」と呼ばれる概念で表現している。 
 オブジェクトには以下の 4 種類がある。 
 - commit オブジェクト
 - コミットの情報が入っているオブジェクト 
 - tree オブジェクト
 - ディレクトリの情報が入っているオブジェクト 
 - blob オブジェクト
 - ファイルの情報が入っているオブジェクト(バックアップ) 
 - tag オブジェクト
 - annotated tag の情報が入っているオブジェクト 
 
 
 コミットの仕組み
 shumon.fujita

  200. 302 blob ハッシュってなに?→ Git に管理されている オブジェクトの 1 種(の key) のこと。


    Git には様々なデータを、「オブジェクト」と呼ばれる概念で表現している。 
 オブジェクトには以下の 4 種類がある。 
 - commit オブジェクト
 - コミットの情報が入っているオブジェクト 
 - tree オブジェクト
 - ディレクトリの情報が入っているオブジェクト 
 - blob オブジェクト
 - ファイルの情報が入っているオブジェクト(バックアップ) 
 - tag オブジェクト
 - annotated tag の情報が入っているオブジェクト 
 
 
 コミットの仕組み
 shumon.fujita

  201. 303 blob ハッシュってなに?→ Git に管理されている オブジェクトの 1 種(の key) のこと。


    Git には様々なデータを、「オブジェクト」と呼ばれる概念で表現している。 
 オブジェクトには以下の 4 種類がある。 
 - commit オブジェクト
 - コミットの情報が入っているオブジェクト 
 - tree オブジェクト
 - ディレクトリの情報が入っているオブジェクト 
 - blob オブジェクト
 - ファイルの情報が入っているオブジェクト(バックアップ) 
 - tag オブジェクト
 - annotated tag の情報が入っているオブジェクト 
 
 ただしGit で扱うデータが全てオブジェクトなわけではない。例えば branch はオブジェクトで管理していない。 
 コミットの仕組み
 shumon.fujita

  202. 305 オブジェクトの実体は .git/objects の中に zlib で圧縮して保存されている。 
 
 例えば、key が

    e2022389da0c18f0c8a0e2f9b27d58d197f41b32 のオブジェクトのパスは、 
 .git/objects/e2/022389da0c18f0c8a0e2f9b27d58d197f41b32 になる。
 
 
 コミットの仕組み
 shumon.fujita

  203. 306 オブジェクトの実体は .git/objects の中に zlib で圧縮して保存されている。 
 
 例えば、key が

    e2022389da0c18f0c8a0e2f9b27d58d197f41b32 のオブジェクトのパスは、 
 .git/objects/e2/022389da0c18f0c8a0e2f9b27d58d197f41b32 になる。
 
 このように、Git は一種の Key-Value Store としてオブジェクトを管理している。 
 
 コミットの仕組み
 shumon.fujita

  204. README.md の blob (e2022389da0c18f0c8a0e2f9b27d58d197f41b32) の中身を確認してみる。 
 $ cat README.md #

    21 卒 Git 研修用リポジトリ $ cat .git/objects/e2/022389da0c18f0c8a0e2f9b27d58d197f41b32 | zlib d blob 38# 21 卒 Git 研修用リポジトリ 308 コミットの仕組み

  205. README.md の blob (e2022389da0c18f0c8a0e2f9b27d58d197f41b32) の中身を確認してみる。 
 $ cat README.md #

    21 卒 Git 研修用リポジトリ $ cat .git/objects/e2/022389da0c18f0c8a0e2f9b27d58d197f41b32 | zlib d blob 38# 21 卒 Git 研修用リポジトリ ファイルの先頭に、オブジェクトの種類とファイルサイズを付けたものを、zlib で圧縮している事が分かる。 
 309 コミットの仕組み

  206. README.md の blob (e2022389da0c18f0c8a0e2f9b27d58d197f41b32) の中身を確認してみる。 
 $ cat README.md #

    21 卒 Git 研修用リポジトリ $ cat .git/objects/e2/022389da0c18f0c8a0e2f9b27d58d197f41b32 | zlib d blob 38# 21 卒 Git 研修用リポジトリ ファイルの先頭に、オブジェクトの種類とファイルサイズを付けたものを、zlib で圧縮している事が分かる。 
 blobオブジェクトはファイルの差分ではなくファイルの中身そのものを記録している事も分かる。 
 310 コミットの仕組み

  207. README.md の blob (e2022389da0c18f0c8a0e2f9b27d58d197f41b32) の中身を確認してみる。 
 $ cat README.md #

    21 卒 Git 研修用リポジトリ $ cat .git/objects/e2/022389da0c18f0c8a0e2f9b27d58d197f41b32 | zlib d blob 38# 21 卒 Git 研修用リポジトリ ファイルの先頭に、オブジェクトの種類とファイルサイズを付けたものを、zlib で圧縮している事が分かる。 
 blobオブジェクトはファイルの差分ではなくファイルの中身そのものを記録している事も分かる。 
 ちなみに、圧縮前の状態の SHA-1 が、この blob を指す key になっている。 
 $ cat .git/objects/e2/022389da0c18f0c8a0e2f9b27d58d197f41b32 | zlib d | shasum e2022389da0c18f0c8a0e2f9b27d58d197f41b32 - 311 コミットの仕組み

  208. README.md の blob (e2022389da0c18f0c8a0e2f9b27d58d197f41b32) の中身を確認してみる。 
 $ cat README.md #

    21 卒 Git 研修用リポジトリ $ cat .git/objects/e2/022389da0c18f0c8a0e2f9b27d58d197f41b32 | zlib d blob 38# 21 卒 Git 研修用リポジトリ ファイルの先頭に、オブジェクトの種類とファイルサイズを付けたものを、zlib で圧縮している事が分かる。 
 blobオブジェクトはファイルの差分ではなくファイルの中身そのものを記録している事も分かる。 
 ちなみに、圧縮前の状態の SHA-1 が、この blob を指す key になっている。 
 $ cat .git/objects/e2/022389da0c18f0c8a0e2f9b27d58d197f41b32 | zlib d | shasum e2022389da0c18f0c8a0e2f9b27d58d197f41b32 - 312 コミットの仕組み

  209. 各オブジェクトの中身を確認するには、自分で zlib で伸長してもいいけど、git cat-file を使えば簡単にできる。 
 $ git cat-file -p

    <オブジェクトハッシュ> -p オプションを付けると、自動でオブジェクトの種類を判別して読みやすく整形して表示してくれる。 
 315 コミットの仕組み
 shumon.fujita

  210. 316 各オブジェクトの中身を確認するには、自分で zlib で伸長してもいいけど、git cat-file を使えば簡単にできる。 
 $ git cat-file

    -p <オブジェクトハッシュ> -p オプションを付けると、自動でオブジェクトの種類を判別して読みやすく整形して表示してくれる。 
 
 $ git cat-file -p e2022389da0c18f0c8a0e2f9b27d58d197f41b32 # 21 卒 Git 研修用リポジトリ 
 コミットの仕組み
 shumon.fujita

  211. 317 本題に戻って、編集したコードを add すると何が起こるのか。 
 $ git ls-files --stage 100644

    e2022389da0c18f0c8a0e2f9b27d58d197f41b32 0 README.md 
 コミットの仕組み
 shumon.fujita

  212. 318 本題に戻って、編集したコードを add すると何が起こるのか。 
 $ git ls-files --stage 100644

    e2022389da0c18f0c8a0e2f9b27d58d197f41b32 0 README.md $ echo hoge > hoge.txt 
 コミットの仕組み
 shumon.fujita

  213. 319 本題に戻って、編集したコードを add すると何が起こるのか。 
 $ git ls-files --stage 100644

    e2022389da0c18f0c8a0e2f9b27d58d197f41b32 0 README.md $ echo hoge > hoge.txt $ git add hoge.txt 
 コミットの仕組み
 shumon.fujita

  214. 320 本題に戻って、編集したコードを add すると何が起こるのか。 
 $ git ls-files --stage 100644

    e2022389da0c18f0c8a0e2f9b27d58d197f41b32 0 README.md $ echo hoge > hoge.txt $ git add hoge.txt $ git ls-files --stage 
 コミットの仕組み
 shumon.fujita

  215. 321 本題に戻って、編集したコードを add すると何が起こるのか。 
 $ git ls-files --stage 100644

    e2022389da0c18f0c8a0e2f9b27d58d197f41b32 0 README.md $ echo hoge > hoge.txt $ git add hoge.txt $ git ls-files --stage 100644 e2022389da0c18f0c8a0e2f9b27d58d197f41b32 0 README.md 100644 2262de0c121f22df8e78f5a37d6e114fd322c0b0 0 hoge.txt 
 コミットの仕組み
 shumon.fujita

  216. 322 本題に戻って、編集したコードを add すると何が起こるのか。 
 $ git ls-files --stage 100644

    e2022389da0c18f0c8a0e2f9b27d58d197f41b32 0 README.md $ echo hoge > hoge.txt $ git add hoge.txt $ git ls-files --stage 100644 e2022389da0c18f0c8a0e2f9b27d58d197f41b32 0 README.md 100644 2262de0c121f22df8e78f5a37d6e114fd322c0b0 0 hoge.txt 
 コミットの仕組み
 shumon.fujita

  217. 323 本題に戻って、編集したコードを add すると何が起こるのか。 
 $ git ls-files --stage 100644

    e2022389da0c18f0c8a0e2f9b27d58d197f41b32 0 README.md $ echo hoge > hoge.txt $ git add hoge.txt $ git ls-files --stage 100644 e2022389da0c18f0c8a0e2f9b27d58d197f41b32 0 README.md 100644 2262de0c121f22df8e78f5a37d6e114fd322c0b0 0 hoge.txt index が更新されて、新しいエントリが追加されていることが分かる(このとき blob も一緒に生成される) 
 コミットの仕組み
 shumon.fujita

  218. add は基本的に index の更新 + blob オブジェクトの生成しかしていない。 
 $ mkdir

    fuga $ echo fuga > fuga/fuga.txt 
 324 コミットの仕組み
 shumon.fujita

  219. add は基本的に index の更新 + blob オブジェクトの生成しかしていない。 
 $ mkdir

    fuga $ echo fuga > fuga/fuga.txt $ git add fuga/fuga.txt 
 325 コミットの仕組み
 shumon.fujita

  220. add は基本的に index の更新 + blob オブジェクトの生成しかしていない。 
 $ mkdir

    fuga $ echo fuga > fuga/fuga.txt $ git add fuga/fuga.txt $ git ls-files --stage 
 326 コミットの仕組み
 shumon.fujita

  221. add は基本的に index の更新 + blob オブジェクトの生成しかしていない。 
 $ mkdir

    fuga $ echo fuga > fuga/fuga.txt $ git add fuga/fuga.txt $ git ls-files --stage 100644 e2022389da0c18f0c8a0e2f9b27d58d197f41b32 0 README.md 100644 9128c3eb56a3547e2cca631042366bf0f37abe67 0 fuga/fuga.txt 100644 2262de0c121f22df8e78f5a37d6e114fd322c0b0 0 hoge.txt 
 327 コミットの仕組み
 shumon.fujita

  222. add は基本的に index の更新 + blob オブジェクトの生成しかしていない。 
 $ mkdir

    fuga $ echo fuga > fuga/fuga.txt $ git add fuga/fuga.txt $ git ls-files --stage 100644 e2022389da0c18f0c8a0e2f9b27d58d197f41b32 0 README.md 100644 9128c3eb56a3547e2cca631042366bf0f37abe67 0 fuga/fuga.txt 100644 2262de0c121f22df8e78f5a37d6e114fd322c0b0 0 hoge.txt 
 328 コミットの仕組み
 shumon.fujita

  223. add は基本的に index の更新 + blob オブジェクトの生成しかしていない。 
 $ mkdir

    fuga $ echo fuga > fuga/fuga.txt $ git add fuga/fuga.txt $ git ls-files --stage 100644 e2022389da0c18f0c8a0e2f9b27d58d197f41b32 0 README.md 100644 9128c3eb56a3547e2cca631042366bf0f37abe67 0 fuga/fuga.txt 100644 2262de0c121f22df8e78f5a37d6e114fd322c0b0 0 hoge.txt ディレクトリが追加されても tree オブジェクトは作らず、blob オブジェクトしか作らない。 
 329 コミットの仕組み
 shumon.fujita

  224. 331 blob オブジェクトは add 時に、tree オブジェクトは commit 時に生成する。 
 


    commit すると内部的に実行している処理は大まかには次の通り。 
 1. index から tree オブジェクトを生成 
 2. commit オブジェクトを生成 
 3. HEAD を新しい commit ハッシュに書き換え 
 
 
 コミットの仕組み
 shumon.fujita

  225. 332 blob オブジェクトは add 時に、tree オブジェクトは commit 時に生成する。 
 


    commit すると内部的に実行している処理は大まかには次の通り。 
 1. index から tree オブジェクトを生成 
 2. commit オブジェクトを生成 
 3. HEAD を新しい commit ハッシュに書き換え 
 
 それぞれ細かく見ていく。
 コミットの仕組み
 shumon.fujita

  226. 334 commit オブジェクトを作る前に、index から tree オブジェクトを生成する。 
 tree オブジェクトの構造はこんな感じ。 


    $ cat .git/objects/18/4135bd0b06f80372a29a35c32ba2e8a5609dc6 | zlib d | hexdump -C 00000000 74 72 65 65 20 33 37 00 31 30 30 36 34 34 20 52 |tree 37.100644 R| 00000010 45 41 44 4d 45 2e 6d 64 00 e2 02 23 89 da 0c 18 |EADME.md...#....| 00000020 f0 c8 a0 e2 f9 b2 7d 58 d1 97 f4 1b 32 |......}X....2| 
 コミットの仕組み
 shumon.fujita

  227. 335 commit オブジェクトを作る前に、index から tree オブジェクトを生成する。 
 tree オブジェクトの構造はこんな感じ。 


    $ cat .git/objects/18/4135bd0b06f80372a29a35c32ba2e8a5609dc6 | zlib d | hexdump -C 00000000 74 72 65 65 20 33 37 00 31 30 30 36 34 34 20 52 |tree 37.100644 R| 00000010 45 41 44 4d 45 2e 6d 64 00 e2 02 23 89 da 0c 18 |EADME.md...#....| 00000020 f0 c8 a0 e2 f9 b2 7d 58 d1 97 f4 1b 32 |......}X....2| 
 コミットの仕組み
 shumon.fujita

  228. 336 commit オブジェクトを作る前に、index から tree オブジェクトを生成する。 
 tree オブジェクトの構造はこんな感じ。 


    $ cat .git/objects/18/4135bd0b06f80372a29a35c32ba2e8a5609dc6 | zlib d | hexdump -C 00000000 74 72 65 65 20 33 37 00 31 30 30 36 34 34 20 52 |tree 37.100644 R| 00000010 45 41 44 4d 45 2e 6d 64 00 e2 02 23 89 da 0c 18 |EADME.md...#....| 00000020 f0 c8 a0 e2 f9 b2 7d 58 d1 97 f4 1b 32 |......}X....2| 
 コミットの仕組み
 shumon.fujita

  229. 337 commit オブジェクトを作る前に、index から tree オブジェクトを生成する。 
 tree オブジェクトの構造はこんな感じ。 


    $ cat .git/objects/18/4135bd0b06f80372a29a35c32ba2e8a5609dc6 | zlib d | hexdump -C 00000000 74 72 65 65 20 33 37 00 31 30 30 36 34 34 20 52 |tree 37.100644 R| 00000010 45 41 44 4d 45 2e 6d 64 00 e2 02 23 89 da 0c 18 |EADME.md...#....| 00000020 f0 c8 a0 e2 f9 b2 7d 58 d1 97 f4 1b 32 |......}X....2| 
 コミットの仕組み
 shumon.fujita

  230. 338 commit オブジェクトを作る前に、index から tree オブジェクトを生成する。 
 tree オブジェクトの構造はこんな感じ。 


    $ cat .git/objects/18/4135bd0b06f80372a29a35c32ba2e8a5609dc6 | zlib d | hexdump -C 00000000 74 72 65 65 20 33 37 00 31 30 30 36 34 34 20 52 |tree 37.100644 R| 00000010 45 41 44 4d 45 2e 6d 64 00 e2 02 23 89 da 0c 18 |EADME.md...#....| 00000020 f0 c8 a0 e2 f9 b2 7d 58 d1 97 f4 1b 32 |......}X....2| 
 コミットの仕組み
 shumon.fujita

  231. 339 commit オブジェクトを作る前に、index から tree オブジェクトを生成する。 
 tree オブジェクトの構造はこんな感じ。 


    $ cat .git/objects/18/4135bd0b06f80372a29a35c32ba2e8a5609dc6 | zlib d | hexdump -C 00000000 74 72 65 65 20 33 37 00 31 30 30 36 34 34 20 52 |tree 37.100644 R| 00000010 45 41 44 4d 45 2e 6d 64 00 e2 02 23 89 da 0c 18 |EADME.md...#....| 00000020 f0 c8 a0 e2 f9 b2 7d 58 d1 97 f4 1b 32 |......}X....2| ファイルの種類とパーミッションのフラグとファイル名、blob ハッシュが 0x00 区切りで書き込まれている。 
 
 コミットの仕組み
 shumon.fujita

  232. 340 commit オブジェクトを作る前に、index から tree オブジェクトを生成する。 
 tree オブジェクトの構造はこんな感じ。 


    $ cat .git/objects/18/4135bd0b06f80372a29a35c32ba2e8a5609dc6 | zlib d | hexdump -C 00000000 74 72 65 65 20 33 37 00 31 30 30 36 34 34 20 52 |tree 37.100644 R| 00000010 45 41 44 4d 45 2e 6d 64 00 e2 02 23 89 da 0c 18 |EADME.md...#....| 00000020 f0 c8 a0 e2 f9 b2 7d 58 d1 97 f4 1b 32 |......}X....2| ファイルの種類とパーミッションのフラグとファイル名、blob ハッシュが 0x00 区切りで書き込まれている。 
 → 全部 index が持っていた情報 
 
 コミットの仕組み
 shumon.fujita

  233. 341 commit オブジェクトを作る前に、index から tree オブジェクトを生成する。 
 tree オブジェクトの構造はこんな感じ。 


    $ cat .git/objects/18/4135bd0b06f80372a29a35c32ba2e8a5609dc6 | zlib d | hexdump -C 00000000 74 72 65 65 20 33 37 00 31 30 30 36 34 34 20 52 |tree 37.100644 R| 00000010 45 41 44 4d 45 2e 6d 64 00 e2 02 23 89 da 0c 18 |EADME.md...#....| 00000020 f0 c8 a0 e2 f9 b2 7d 58 d1 97 f4 1b 32 |......}X....2| ファイルの種類とパーミッションのフラグとファイル名、blob ハッシュが 0x00 区切りで書き込まれている。 
 → 全部 index が持っていた情報 
 
 コミットの仕組み

  234. 343 ちなみに tree オブジェクトも cat-file で確認できる。 
 
 
 $

    git cat-file -p 184135 100644 blob e2022389da0c18f0c8a0e2f9b27d58d197f41b32 README.md 
 
 コミットの仕組み
 shumon.fujita

  235. 344 ちなみに tree オブジェクトも cat-file で確認できる。 
 16進数でダンプするよりも、もっと人間にやさしく表示してくれる。 
 


    $ git cat-file -p 184135 100644 blob e2022389da0c18f0c8a0e2f9b27d58d197f41b32 README.md 
 
 コミットの仕組み
 shumon.fujita

  236. 345 ちなみに tree オブジェクトも cat-file で確認できる。 
 16進数でダンプするよりも、もっと人間にやさしく表示してくれる。 
 


    $ git cat-file -p 184135 100644 blob e2022389da0c18f0c8a0e2f9b27d58d197f41b32 README.md コミットの仕組み
 shumon.fujita

  237. 347 commit すると差分だけでなく、 リポジトリのルートディレクトリを含む全ディレクトリ分の tree を自動で作る 。
 この時、変更があった部分だけ新しい blob 及び

    tree オブジェクト 
 に書き換えられ、それ以外はコピーされる。 
 
 コミットの仕組み
 https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

  238. 348 commit すると差分だけでなく、 リポジトリのルートディレクトリを含む全ディレクトリ分の tree を自動で作る 。
 この時、変更があった部分だけ新しい blob 及び

    tree オブジェクト 
 に書き換えられ、それ以外はコピーされる。 
 tree オブジェクトを作ったら、次は後述する 
 commit オブジェクトを作る。 
 
 コミットの仕組み
 https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

  239. 349 commit すると差分だけでなく、 リポジトリのルートディレクトリを含む全ディレクトリ分の tree を自動で作る 。
 この時、変更があった部分だけ新しい blob 及び

    tree オブジェクト 
 に書き換えられ、それ以外はコピーされる。 
 tree オブジェクトを作ったら、次は後述する 
 commit オブジェクトを作る。 
 commit オブジェクトは、リポジトリのルートにあたる 
 tree オブジェクトを参照していて、commit 時のリポジトリの 
 状態を再現できるようになっている。 
 
 
 コミットの仕組み
 https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

  240. 350 commit すると差分だけでなく、 リポジトリのルートディレクトリを含む全ディレクトリ分の tree を自動で作る 。
 この時、変更があった部分だけ新しい blob 及び

    tree オブジェクト 
 に書き換えられ、それ以外はコピーされる。 
 tree オブジェクトを作ったら、次は後述する 
 commit オブジェクトを作る。 
 commit オブジェクトは、リポジトリのルートにあたる 
 tree オブジェクトを参照していて、commit 時のリポジトリの 
 状態を再現できるようになっている。 
 => コミットはある時点のスナップショット 
 
 
 
 コミットの仕組み
 https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

  241. 351 commit すると差分だけでなく、 リポジトリのルートディレクトリを含む全ディレクトリ分の tree を自動で作る 。
 この時、変更があった部分だけ新しい blob 及び

    tree オブジェクト 
 に書き換えられ、それ以外はコピーされる。 
 tree オブジェクトを作ったら、次は後述する 
 commit オブジェクトを作る。 
 commit オブジェクトは、リポジトリのルートにあたる 
 tree オブジェクトを参照していて、commit 時のリポジトリの 
 状態を再現できるようになっている。 
 => コミットはある時点のスナップショット 
 checkoutなどで別のコミットに移った時にすぐにその状態を 
 復元できるのはこれが理由。 
 
 
 コミットの仕組み
 https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

  242. 352 commit オブジェクトの構造はこんな感じ。 
 
 $ cat .git/objects/56/4d5425c6eff4fab2be1cec9562003b6b64eea0 | zlib

    d commit 232tree 184135bd0b06f80372a29a35c32ba2e8a5609dc6 parent dd08f09944c8c97a718548030886514d8ef4b887 author shumon84 <[email protected]> 1617805187 +0900 committer shumon84 <[email protected]> 1617805187 +0900 README.md を追加
 コミットの仕組み
 shumon.fujita

  243. 353 commit オブジェクトの構造はこんな感じ。 
 他のオブジェクトと同様に、これの SHA-1 ハッシュが commit ハッシュになる。 


    $ cat .git/objects/56/4d5425c6eff4fab2be1cec9562003b6b64eea0 | zlib d commit 232tree 184135bd0b06f80372a29a35c32ba2e8a5609dc6 parent dd08f09944c8c97a718548030886514d8ef4b887 author shumon84 <[email protected]> 1617805187 +0900 committer shumon84 <[email protected]> 1617805187 +0900 README.md を追加
 コミットの仕組み
 shumon.fujita

  244. 354 commit オブジェクトの構造はこんな感じ。 
 他のオブジェクトと同様に、これの SHA-1 ハッシュが commit ハッシュになる。 


    $ cat .git/objects/56/4d5425c6eff4fab2be1cec9562003b6b64eea0 | zlib d commit 232tree 184135bd0b06f80372a29a35c32ba2e8a5609dc6 parent dd08f09944c8c97a718548030886514d8ef4b887 author shumon84 <[email protected]> 1617805187 +0900 committer shumon84 <[email protected]> 1617805187 +0900 README.md を追加
 コミットの仕組み
 shumon.fujita

  245. 355 commit オブジェクトの構造はこんな感じ。 
 他のオブジェクトと同様に、これの SHA-1 ハッシュが commit ハッシュになる。 


    $ cat .git/objects/56/4d5425c6eff4fab2be1cec9562003b6b64eea0 | zlib d commit 232tree 184135bd0b06f80372a29a35c32ba2e8a5609dc6 parent dd08f09944c8c97a718548030886514d8ef4b887 author shumon84 <[email protected]> 1617805187 +0900 committer shumon84 <[email protected]> 1617805187 +0900 README.md を追加
 コミットの仕組み
 shumon.fujita

  246. 356 commit オブジェクトの構造はこんな感じ。 
 他のオブジェクトと同様に、これの SHA-1 ハッシュが commit ハッシュになる。 


    $ cat .git/objects/56/4d5425c6eff4fab2be1cec9562003b6b64eea0 | zlib d commit 232tree 184135bd0b06f80372a29a35c32ba2e8a5609dc6 parent dd08f09944c8c97a718548030886514d8ef4b887 author shumon84 <[email protected]> 1617805187 +0900 committer shumon84 <[email protected]> 1617805187 +0900 README.md を追加
 コミットの仕組み
 shumon.fujita

  247. 357 commit オブジェクトの構造はこんな感じ。 
 他のオブジェクトと同様に、これの SHA-1 ハッシュが commit ハッシュになる。 


    $ cat .git/objects/56/4d5425c6eff4fab2be1cec9562003b6b64eea0 | zlib d commit 232tree 184135bd0b06f80372a29a35c32ba2e8a5609dc6 parent dd08f09944c8c97a718548030886514d8ef4b887 author shumon84 <[email protected]> 1617805187 +0900 committer shumon84 <[email protected]> 1617805187 +0900 README.md を追加
 コミットの仕組み
 shumon.fujita

  248. 358 commit オブジェクトの構造はこんな感じ。 
 他のオブジェクトと同様に、これの SHA-1 ハッシュが commit ハッシュになる。 


    $ cat .git/objects/56/4d5425c6eff4fab2be1cec9562003b6b64eea0 | zlib d commit 232tree 184135bd0b06f80372a29a35c32ba2e8a5609dc6 parent dd08f09944c8c97a718548030886514d8ef4b887 author shumon84 <[email protected]> 1617805187 +0900 committer shumon84 <[email protected]> 1617805187 +0900 README.md を追加
 コミットの仕組み
 shumon.fujita

  249. 359 commit オブジェクトの構造はこんな感じ。 
 他のオブジェクトと同様に、これの SHA-1 ハッシュが commit ハッシュになる。 


    $ cat .git/objects/56/4d5425c6eff4fab2be1cec9562003b6b64eea0 | zlib d commit 232tree 184135bd0b06f80372a29a35c32ba2e8a5609dc6 parent dd08f09944c8c97a718548030886514d8ef4b887 author shumon84 <[email protected]> 1617805187 +0900 committer shumon84 <[email protected]> 1617805187 +0900 README.md を追加
 コミットの仕組み
 shumon.fujita

  250. 360 commit オブジェクトに含まれている情報は↓の通り。 
 - リポジトリのルートディレクトリの tree ハッシュ 
 -

    親 commit ハッシュ
 - committer と author のタイムスタンプ・名前・メアド 
 - コミットメッセージ
 
 
 コミットの仕組み
 shumon.fujita

  251. 361 commit オブジェクトに含まれている情報は↓の通り。 
 - リポジトリのルートディレクトリの tree ハッシュ 
 -

    親 commit ハッシュ
 - committer と author のタイムスタンプ・名前・メアド 
 - コミットメッセージ
 このうち、どれか 1 つでも変わると、(SHA-1 が衝突しない限り)別の commit ハッシュ になる。 
 
 
 コミットの仕組み
 shumon.fujita

  252. 362 commit オブジェクトに含まれている情報は↓の通り。 
 - リポジトリのルートディレクトリの tree ハッシュ 
 -

    親 commit ハッシュ
 - committer と author のタイムスタンプ・名前・メアド 
 - コミットメッセージ
 このうち、どれか 1 つでも変わると、(SHA-1 が衝突しない限り)別の commit ハッシュ になる。 
 
 ちなみに、commit ハッシュがどれくらい衝突しないのかというと、 
 「1000 人で 1 日 10 回、40 京年間 commit し続けても、衝突する可能性は 50 %」 
 と言われている。
 
 コミットの仕組み
 shumon.fujita

  253. 363 commit オブジェクトに含まれている情報は↓の通り。 
 - リポジトリのルートディレクトリの tree ハッシュ 
 -

    親 commit ハッシュ
 - committer と author のタイムスタンプ・名前・メアド 
 - コミットメッセージ
 このうち、どれか 1 つでも変わると、(SHA-1 が衝突しない限り)別の commit ハッシュ になる。 
 
 ちなみに、commit ハッシュがどれくらい衝突しないのかというと、 
 「1000 人で 1 日 10 回、40 京年間 commit し続けても、衝突する可能性は 50 %」 
 と言われている。
 
 コミットの仕組み
 shumon.fujita
 親 commit のハッシュを
 持っていることが超重要

  254. 365 親 commit ハッシュを commit オブジェクトの一部に含めることで、改ざんされていないことが保証できる。 
 
 
 


    
 
 
 
 コミットの仕組み
 コミット1
 コミット2
 コミット3
 コミット4
 shumon.fujita

  255. 366 親 commit ハッシュを commit オブジェクトの一部に含めることで、改ざんされていないことが保証できる。 
 
 
 


    
 
 
 
 コミットの仕組み
 コミット1
 コミット2
 コミット3
 コミット4
 このコミットを
 改ざんしたい!
 shumon.fujita

  256. 367 親 commit ハッシュを commit オブジェクトの一部に含めることで、改ざんされていないことが保証できる。 
 
 
 


    
 
 
 
 コミットの仕組み
 コミット1
 コミット2
 コミット3
 コミット4
 このコミットを
 改ざんしたい!
 親コミットのハッシュが変わるので
 parent を書き換える必要がある
 shumon.fujita

  257. 368 親 commit ハッシュを commit オブジェクトの一部に含めることで、改ざんされていないことが保証できる。 
 
 
 


    
 
 
 
 コミットの仕組み
 コミット1
 コミット2
 コミット3
 コミット4
 このコミットを
 改ざんしたい!
 親コミットのハッシュが変わるので
 parent を書き換える必要がある
 親コミットのハッシュが変わるので
 以下略
 shumon.fujita

  258. 369 親 commit ハッシュを commit オブジェクトの一部に含めることで、改ざんされていないことが保証できる。 
 
 
 


    
 
 
 
 コミットの仕組み
 コミット1
 コミット2
 コミット3
 コミット4
 このコミットを
 改ざんしたい!
 親コミットのハッシュが変わるので
 parent を書き換える必要がある
 親コミットのハッシュが変わるので
 以下略
 結局元のコミット4とは
 別物になってしまう
 → 改ざん不可能
 shumon.fujita

  259. 370 親 commit ハッシュを commit オブジェクトの一部に含めることで、改ざんされていないことが保証できる。 
 
 
 


    
 
 過去の commit を改ざんするには、それ以降全ての commit を改ざんする必要があり、最新の commit も別物に。 
 
 
 コミットの仕組み
 コミット1
 コミット2
 コミット3
 コミット4
 このコミットを
 改ざんしたい!
 親コミットのハッシュが変わるので
 parent を書き換える必要がある
 親コミットのハッシュが変わるので
 以下略
 結局元のコミット4とは
 別物になってしまう
 → 改ざん不可能
 shumon.fujita

  260. 371 親 commit ハッシュを commit オブジェクトの一部に含めることで、改ざんされていないことが保証できる。 
 
 
 


    
 
 過去の commit を改ざんするには、それ以降全ての commit を改ざんする必要があり、最新の commit も別物に。 
 → Git はブロックチェーン!! 
 コミットの仕組み
 コミット1
 コミット2
 コミット3
 コミット4
 このコミットを
 改ざんしたい!
 親コミットのハッシュが変わるので
 parent を書き換える必要がある
 親コミットのハッシュが変わるので
 以下略
 結局元のコミット4とは
 別物になってしまう
 → 改ざん不可能
 shumon.fujita

  261. 372 blob オブジェクトは add 時に、tree オブジェクトは commit 時に生成する。 
 


    commit すると内部的に実行している処理は大まかには次の通り。 (本当はもうちょっと色々やってるけど割愛)
 1. index から tree オブジェクトを生成 
 2. commit オブジェクトを生成 
 3. HEAD を新しい commit ハッシュに書き換え 
 
 それぞれ細かく見ていく。
 コミットの仕組み
 shumon.fujita

  262. 375 commit オブジェクトを作ったら、Git は最後に HEAD を書き換える。 
 → HEAD とは?


    
 HEAD の話をする前に、refs の話をする必要がある。(HEAD は refs の一種) 
 
 コミットの仕組み
 shumon.fujita

  263. 376 commit オブジェクトを作ったら、Git は最後に HEAD を書き換える。 
 → HEAD とは?


    
 HEAD の話をする前に、refs の話をする必要がある。(HEAD は refs の一種) 
 refs は特定の commit を指すポインタのようなもの。commit ハッシュのエイリアスとも言える。 
 
 コミットの仕組み
 shumon.fujita

  264. 377 commit オブジェクトを作ったら、Git は最後に HEAD を書き換える。 
 → HEAD とは?


    
 HEAD の話をする前に、refs の話をする必要がある。(HEAD は refs の一種) 
 refs は特定の commit を指すポインタのようなもの。commit ハッシュのエイリアスとも言える。 
 具体的には↓などが refs にあたる。 
 - tag
 - branch
 - HEAD
 コミットの仕組み
 shumon.fujita

  265. 379 まずは refs の中でも、最も単純な light weight tag を見ていく。 
 light

    weight tag は本当にただ特定の commit を指しているだけ。 
 refs について
 shumon.fujita

  266. 380 まずは refs の中でも、最も単純な light weight tag を見ていく。 
 light

    weight tag は本当にただ特定の commit を指しているだけ。 
 
 $ git tag light-weight # オプションなしでタグを作ると light weight tag になる refs について
 shumon.fujita

  267. 381 まずは refs の中でも、最も単純な light weight tag を見ていく。 
 light

    weight tag は本当にただ特定の commit を指しているだけ。 
 
 $ git tag light-weight # オプションなしでタグを作ると light weight tag になる $ git log -n 1 --oneline 7c4c08d (HEAD -> master, tag: light-weight) Merge branch 'develop' refs について
 shumon.fujita

  268. 382 まずは refs の中でも、最も単純な light weight tag を見ていく。 
 light

    weight tag は本当にただ特定の commit を指しているだけ。 
 タグを作ると .git/refs/tags/ 以下に保存される。 
 $ git tag light-weight # オプションなしでタグを作ると light weight tag になる $ git log -n 1 --oneline 7c4c08d (HEAD -> master, tag: light-weight) Merge branch 'develop' refs について
 shumon.fujita

  269. 383 まずは refs の中でも、最も単純な light weight tag を見ていく。 
 light

    weight tag は本当にただ特定の commit を指しているだけ。 
 タグを作ると .git/refs/tags/ 以下に保存される。 
 $ git tag light-weight # オプションなしでタグを作ると light weight tag になる $ git log -n 1 --oneline 7c4c08d (HEAD -> master, tag: light-weight) Merge branch 'develop' $ cat .git/refs/tags/light-weight 7c4c08d68be5a53406af4582a961a460b0db83cd refs について
 shumon.fujita

  270. 385 次に annotated tag の挙動を見ていく。 
 annotated tag とはコメントが付けられるタグのこと。 


    -a オプションで作ることができる。 
 refs について
 shumon.fujita

  271. 386 次に annotated tag の挙動を見ていく。 
 annotated tag とはコメントが付けられるタグのこと。 


    -a オプションで作ることができる。 $ git tag -a annotated -m "メッセージ" $ git log -n 1 --oneline 7c4c08d (HEAD -> master, tag: annotated) Merge branch 'develop' 
 refs について
 shumon.fujita

  272. 387 次に annotated tag の挙動を見ていく。 
 annotated tag とはコメントが付けられるタグのこと。 


    -a オプションで作ることができる。 $ git tag -a annotated -m "メッセージ" $ git log -n 1 --oneline 7c4c08d (HEAD -> master, tag: annotated) Merge branch 'develop' $ cat .git/refs/tags/annotated e0114d0446b25c2c653fa5dd28c678602033c48b 
 refs について
 shumon.fujita

  273. 388 次に annotated tag の挙動を見ていく。 
 annotated tag とはコメントが付けられるタグのこと。 


    -a オプションで作ることができる。 $ git tag -a annotated -m "メッセージ" $ git log -n 1 --oneline 7c4c08d (HEAD -> master, tag: annotated) Merge branch 'develop' $ cat .git/refs/tags/annotated e0114d0446b25c2c653fa5dd28c678602033c48b light weight tag と違って、直接 commit ハッシュが書かれているわけではない。 
 
 refs について
 shumon.fujita

  274. 389 次に annotated tag の挙動を見ていく。 
 annotated tag とはコメントが付けられるタグのこと。 


    -a オプションで作ることができる。 $ git tag -a annotated -m "メッセージ" $ git log -n 1 --oneline 7c4c08d (HEAD -> master, tag: annotated) Merge branch 'develop' $ cat .git/refs/tags/annotated e0114d0446b25c2c653fa5dd28c678602033c48b light weight tag と違って、直接 commit ハッシュが書かれているわけではない。 
 → じゃあ何なの?
 refs について
 shumon.fujita

  275. 390 blob ハッシュってなに?→ Git に管理されている オブジェクトの 1 種(の key)のこと。 


    Git には様々なデータを、「オブジェクト」と呼ばれる概念で表現している。 
 オブジェクトには以下の 4 種類がある。 
 - commit オブジェクト
 - コミットの情報が入っているオブジェクト 
 - tree オブジェクト
 - ディレクトリの情報が入っているオブジェクト 
 - blob オブジェクト
 - ファイルの情報が入っているオブジェクト 
 - tag オブジェクト
 - annotated tag の情報が入っているオブジェクト 
 
 ただしGit で扱うデータが全てオブジェクトなわけではない。例えば branch はオブジェクトで管理していない。 
 コミットの仕組み
 shumon.fujita

  276. 392 オブジェクトなので、例によって cat-file で覗いてみる。 
 もちろん実体は .git/objects/ 以下に zlib で圧縮して保存されている。

    
 $ git cat-file -p e0114d0446b25c2c653fa5dd28c678602033c48b object 7c4c08d68be5a53406af4582a961a460b0db83cd type commit tag annotated tagger shumon84 <[email protected]> 1618330965 +0900 メッセージ 
 refs について
 shumon.fujita

  277. 393 オブジェクトなので、例によって cat-file で覗いてみる。 
 もちろん実体は .git/objects/ 以下に zlib で圧縮して保存されている。

    
 $ git cat-file -p e0114d0446b25c2c653fa5dd28c678602033c48b object 7c4c08d68be5a53406af4582a961a460b0db83cd type commit tag annotated tagger shumon84 <[email protected]> 1618330965 +0900 メッセージ 
 refs について
 shumon.fujita
 object の欄に、tag が指している
 commit のハッシュが書かれている

  278. 394 オブジェクトなので、例によって cat-file で覗いてみる。 
 もちろん実体は .git/objects/ 以下に zlib で圧縮して保存されている。

    
 $ git cat-file -p e0114d0446b25c2c653fa5dd28c678602033c48b object 7c4c08d68be5a53406af4582a961a460b0db83cd type commit tag annotated tagger shumon84 <[email protected]> 1618330965 +0900 メッセージ commit オブジェクトにちょっと似てる。 
 refs について
 shumon.fujita
 object の欄に、tag が指している
 commit のハッシュが書かれている

  279. 397 次に branch の解説。
 branch は基本的に light-weight tag とほぼ変わらない。 


    $ cat .git/refs/heads/master 7c4c08d68be5a53406af4582a961a460b0db83cd
 
 refs について
 shumon.fujita

  280. 398 次に branch の解説。
 branch は基本的に light-weight tag とほぼ変わらない。 


    $ cat .git/refs/heads/master 7c4c08d68be5a53406af4582a961a460b0db83cd
 保存場所が .git/refs/heads/ 以下になっているだけで、書かれている内容は同じ。 
 
 refs について
 shumon.fujita

  281. 399 次に branch の解説。
 branch は基本的に light-weight tag とほぼ変わらない。 


    $ cat .git/refs/heads/master 7c4c08d68be5a53406af4582a961a460b0db83cd
 保存場所が .git/refs/heads/ 以下になっているだけで、書かれている内容は同じ。 
 指している commit ハッシュが直接書かれているだけ。 
 
 refs について
 shumon.fujita

  282. 400 次に branch の解説。
 branch は基本的に light-weight tag とほぼ変わらない。 


    $ cat .git/refs/heads/master 7c4c08d68be5a53406af4582a961a460b0db83cd
 保存場所が .git/refs/heads/ 以下になっているだけで、書かれている内容は同じ。 
 指している commit ハッシュが直接書かれているだけ。 
 → tag との違いは、tag は基本的に書き換えないのに対して、branch はどんどん書き換わっていくところ 
 
 refs について
 shumon.fujita

  283. 401 次に branch の解説。
 branch は基本的に light-weight tag とほぼ変わらない。 


    $ cat .git/refs/heads/master 7c4c08d68be5a53406af4582a961a460b0db83cd
 保存場所が .git/refs/heads/ 以下になっているだけで、書かれている内容は同じ。 
 指している commit ハッシュが直接書かれているだけ。 
 → tag との違いは、tag は基本的に書き換えないのに対して、branch はどんどん書き換わっていくところ 
 ちなみに、branch 名がそのままファイルパスになるため、「feature/hoge」という branch を作ると、 
 feature/ というディレクトリが作られてしまうため、それ以降「feature」という branch は作れなくなる。 
 refs について
 shumon.fujita

  284. 404 話を戻して、HEAD について。HEAD は現在の commit を指す refs。 
 checkout したときは

    HEAD が書き換わっている。 
 
 refs について
 shumon.fujita

  285. 405 話を戻して、HEAD について。HEAD は現在の commit を指す refs。 
 checkout したときは

    HEAD が書き換わっている。 
 .git/HEAD に保存されている。 
 refs について
 shumon.fujita

  286. 406 話を戻して、HEAD について。HEAD は現在の commit を指す refs。 
 checkout したときは

    HEAD が書き換わっている。 
 .git/HEAD に保存されている。 
 $ cat .git/HEAD ref: refs/heads/master 
 refs について
 shumon.fujita

  287. 407 話を戻して、HEAD について。HEAD は現在の commit を指す refs。 
 checkout したときは

    HEAD が書き換わっている。 
 .git/HEAD に保存されている。 
 $ cat .git/HEAD ref: refs/heads/master branch 名で checkout すると、commit ハッシュではなく、branch の場所が書き込まれる。 
 refs について
 shumon.fujita

  288. 408 話を戻して、HEAD について。HEAD は現在の commit を指す refs。 
 checkout したときは

    HEAD が書き換わっている。 
 .git/HEAD に保存されている。 
 $ cat .git/HEAD ref: refs/heads/master $ cat .git/refs/heads/master 7c4c08d68be5a53406af4582a961a460b0db83cd branch 名で checkout すると、commit ハッシュではなく、branch の場所が書き込まれる。 
 
 refs について
 shumon.fujita

  289. 409 話を戻して、HEAD について。HEAD は現在の commit を指す refs。 
 checkout したときは

    HEAD が書き換わっている。 
 .git/HEAD に保存されている。 
 $ cat .git/HEAD ref: refs/heads/master $ cat .git/refs/heads/master 7c4c08d68be5a53406af4582a961a460b0db83cd branch 名で checkout すると、commit ハッシュではなく、branch の場所が書き込まれる。 
 参照を辿って、現在の commit は推移的に解決される。 
 refs について
 shumon.fujita

  290. 412 ようやく commit の内部処理の話に戻ります。 
 commit オブジェクトを作ったら、Git は最後に HEAD を書き換える。

    
 
 HEAD が直接 commit ハッシュを参照している場合 
 
 
 HEAD が branch を参照している場合 
 
 コミットの仕組み
 shumon.fujita

  291. 413 ようやく commit の内部処理の話に戻ります。 
 commit オブジェクトを作ったら、Git は最後に HEAD を書き換える。

    
 
 HEAD が直接 commit ハッシュを参照している場合 
 → HEAD の commit ハッシュを書き換える 
 
 HEAD が branch を参照している場合 
 
 コミットの仕組み
 shumon.fujita

  292. 414 ようやく commit の内部処理の話に戻ります。 
 commit オブジェクトを作ったら、Git は最後に HEAD を書き換える。

    
 
 HEAD が直接 commit ハッシュを参照している場合 
 → HEAD の commit ハッシュを書き換える 
 
 HEAD が branch を参照している場合 
 → HEAD が参照している branch の commit ハッシュを書き換える 
 コミットの仕組み
 shumon.fujita

  293. 417 Git では、1回コミットするまでに次のような処理をしている。 
 
 1. コードを編集する
 2. 編集したコードを add

    する 
 - index の更新
 - blob オブジェクトの生成
 
 
 コミットの仕組み まとめ
 shumon.fujita

  294. 418 Git では、1回コミットするまでに次のような処理をしている。 
 
 1. コードを編集する
 2. 編集したコードを add

    する 
 - index の更新
 - blob オブジェクトの生成
 3. commit する
 - tree オブジェクトの生成
 - commit オブジェクトの生成 
 - HEAD の書き換え
 
 
 コミットの仕組み まとめ
 shumon.fujita

  295. 419 Git では、1回コミットするまでに次のような処理をしている。 
 
 1. コードを編集する
 2. 編集したコードを add

    する 
 - index の更新
 - blob オブジェクトの生成
 3. commit する
 - tree オブジェクトの生成
 - commit オブジェクトの生成 
 - HEAD の書き換え
 
 もうちょっと色々やってるけど、大まかには「コミットする」というとこんな感じの処理のことを指す。 
 コミットの仕組み まとめ
 shumon.fujita

  296. 424 すでに講義中に何度も登場している、みんなお馴染み checkout。 
 checkout に比べると、複雑で上級者向けのコマンドと思われている reset。 
 実は、この 2

    つのコマンドは結構似たようなことをしている。 
 
 この 2 つは、基本的に↓の 3 つを書き換えるコマンド。 
 - ワークツリー(作業ディレクトリ) 
 - index
 - HEAD
 
 checkout, reset の仕組み
 shumon.fujita

  297. 425 すでに講義中に何度も登場している、みんなお馴染み checkout。 
 checkout に比べると、複雑で上級者向けのコマンドと思われている reset。 
 実は、この 2

    つのコマンドは結構似たようなことをしている。 
 
 この 2 つは、基本的に↓の 3 つを書き換えるコマンド。 
 - ワークツリー(作業ディレクトリ) 
 - index
 - HEAD
 それぞれ見ていく。
 checkout, reset の仕組み
 shumon.fujita

  298. 427 まず checkout は、指定した commit にワークツリーも index も HEAD も全部向けるコマンド。

    
 
 1. 指定した commit が参照している tree をワークツリーに展開する。 
 
 
 checkout の仕組み
 shumon.fujita

  299. 428 まず checkout は、指定した commit にワークツリーも index も HEAD も全部向けるコマンド。

    
 
 1. 指定した commit が参照している tree をワークツリーに展開する。 
 2. index をワークツリーと同期する(= tree と同じ状態にする)。 
 
 
 checkout の仕組み
 shumon.fujita

  300. 429 まず checkout は、指定した commit にワークツリーも index も HEAD も全部向けるコマンド。

    
 
 1. 指定した commit が参照している tree をワークツリーに展開する。 
 2. index をワークツリーと同期する(= tree と同じ状態にする)。 
 3. HEAD を指定した commit に変更する。 
 
 
 checkout の仕組み
 shumon.fujita

  301. 430 まず checkout は、指定した commit にワークツリーも index も HEAD も全部向けるコマンド。

    
 
 1. 指定した commit が参照している tree をワークツリーに展開する。 
 2. index をワークツリーと同期する(= tree と同じ状態にする)。 
 3. HEAD を指定した commit に変更する。 
 
 refs を指定していた場合、HEAD にはその参照が書き込まれる。 
 checkout の仕組み
 shumon.fujita

  302. 432 reset は、オプションによって挙動が変わる。 
 おおまかには soft, mixed, hard の 3

    種類のオプションがある。 
 
 
 
 
 
 reset の仕組み
 shumon.fujita

  303. 433 reset は、オプションによって挙動が変わる。 
 おおまかには soft, mixed, hard の 3

    種類のオプションがある。 
 指定した commit ハッシュに向けて、それぞれの内容を書き換える。 
 
 
 
 
 
 reset の仕組み
 shumon.fujita

  304. 434 reset は、オプションによって挙動が変わる。 
 おおまかには soft, mixed, hard の 3

    種類のオプションがある。 
 指定した commit ハッシュに向けて、それぞれの内容を書き換える。 
 
 
 
 
 
 reset の仕組み
 shumon.fujita
 
 HEAD
 index
 ワークツリー
 git reset --soft <commit ハッシュ> 書き換える
 
 
 git reset --mixed <commit ハッシュ> 書き換える
 書き換える
 
 git reset --hard <commit ハッシュ> 書き換える
 書き換える
 書き換える

  305. 435 reset は、オプションによって挙動が変わる。 
 おおまかには soft, mixed, hard の 3

    種類のオプションがある。 
 指定した commit ハッシュに向けて、それぞれの内容を書き換える。 
 
 
 
 
 --hard は全部書き換えるし、checkout と違いはあるの? 
 
 reset の仕組み
 shumon.fujita
 
 HEAD
 index
 ワークツリー
 git reset --soft <commit ハッシュ> 書き換える
 
 
 git reset --mixed <commit ハッシュ> 書き換える
 書き換える
 
 git reset --hard <commit ハッシュ> 書き換える
 書き換える
 書き換える

  306. 436 reset は、オプションによって挙動が変わる。 
 おおまかには soft, mixed, hard の 3

    種類のオプションがある。 
 指定した commit ハッシュに向けて、それぞれの内容を書き換える。 
 
 
 
 
 --hard は全部書き換えるし、checkout と違いはあるの? 
 reset と checkout の最も大きな違いは、HEAD が branch を参照していた場合の挙動。 
 
 reset の仕組み
 shumon.fujita
 
 HEAD
 index
 ワークツリー
 git reset --soft <commit ハッシュ> 書き換える
 
 
 git reset --mixed <commit ハッシュ> 書き換える
 書き換える
 
 git reset --hard <commit ハッシュ> 書き換える
 書き換える
 書き換える

  307. 437 checkout は HEAD が branch を参照していても、書き換えるのは HEAD のみ。 


    
 
 
 
 
 
 
 
 
 reset の仕組み
 shumon.fujita
 first commit
 master.txt を追加
 README.md に
 「master」と追記
 develop.txt を追加
 master
 README.md に
 「develop」と追記
 develop
 HEAD

  308. 438 checkout は HEAD が branch を参照していても、書き換えるのは HEAD のみ。 


    
 
 
 
 
 
 
 
 
 reset の仕組み
 shumon.fujita
 first commit
 master.txt を追加
 README.md に
 「master」と追記
 develop.txt を追加
 master
 README.md に
 「develop」と追記
 develop
 HEAD

  309. 439 checkout は HEAD が branch を参照していても、書き換えるのは HEAD のみ。 


    
 
 
 
 reset は HEAD が branch を参照していた場合、branch の参照先も書き換える。 
 
 
 
 
 
 reset の仕組み
 shumon.fujita
 first commit
 master.txt を追加
 README.md に
 「master」と追記
 develop.txt を追加
 master
 README.md に
 「develop」と追記
 develop
 HEAD
 first commit
 master.txt を追加
 README.md に
 「master」と追記
 develop.txt を追加
 master
 README.md に
 「develop」と追記
 develop
 HEAD

  310. 440 checkout は HEAD が branch を参照していても、書き換えるのは HEAD のみ。 


    
 
 
 
 reset は HEAD が branch を参照していた場合、branch の参照先も書き換える。 
 
 
 
 
 
 reset の仕組み
 shumon.fujita
 first commit
 master.txt を追加
 README.md に
 「master」と追記
 develop.txt を追加
 master
 README.md に
 「develop」と追記
 develop
 HEAD
 first commit
 master.txt を追加
 README.md に
 「master」と追記
 develop.txt を追加
 README.md に
 「develop」と追記
 develop
 master
 HEAD

  311. 443 branch の参照先を変えられる機能を応用すると、reset は色々な使い方ができる。 
 
 ① コミットを無かったことにする 
 1

    つ前の commit ハッシュに branch を向けることで、最新のコミットをなかったことにできる。 
 
 
 reset の仕組み
 shumon.fujita

  312. 444 branch の参照先を変えられる機能を応用すると、reset は色々な使い方ができる。 
 
 ① コミットを無かったことにする 
 1

    つ前の commit ハッシュに branch を向けることで、最新のコミットをなかったことにできる。 
 ② add の取り消し
 
 
 reset の仕組み
 shumon.fujita

  313. 445 branch の参照先を変えられる機能を応用すると、reset は色々な使い方ができる。 
 
 ① コミットを無かったことにする 
 1

    つ前の commit ハッシュに branch を向けることで、最新のコミットをなかったことにできる。 
 ② add の取り消し
 git reset --mixed HEAD とすると、index を HEAD の状況に戻せるので、add を取り消すことができる。 
 
 
 reset の仕組み
 shumon.fujita

  314. 446 branch の参照先を変えられる機能を応用すると、reset は色々な使い方ができる。 
 
 ① コミットを無かったことにする 
 1

    つ前の commit ハッシュに branch を向けることで、最新のコミットをなかったことにできる。 
 ② add の取り消し
 git reset --mixed HEAD とすると、index を HEAD の状況に戻せるので、add を取り消すことができる。 
 git 2.23 で追加された、restore というサブコマンドを使っても同じことができる。 ※experimental
 
 
 reset の仕組み
 shumon.fujita

  315. 447 branch の参照先を変えられる機能を応用すると、reset は色々な使い方ができる。 
 
 ① コミットを無かったことにする 
 1

    つ前の commit ハッシュに branch を向けることで、最新のコミットをなかったことにできる。 
 ② add の取り消し
 git reset --mixed HEAD とすると、index を HEAD の状況に戻せるので、add を取り消すことができる。 
 git 2.23 で追加された、restore というサブコマンドを使っても同じことができる。 ※experimental
 
 使い方は無限大。
 reset の仕組み
 shumon.fujita

  316. 450 割愛していた commit 時に「もうちょっと色々やってる」って話を詳しく。 
 - 各種 Hooks の起動
 -

    .git/hooks/ 以下にスクリプトを置いておくと、対応するイベントが発火したときに実行してくれる。 
 - どんなイベントを hook できるのかは 公式ドキュメント参照
 - reflog の更新
 - .git/logs/HEAD に HEAD の向き先の移動履歴を書き込む。 
 - HEAD が branch を参照していた場合、.git/log/refs/<branch 名> にも移動履歴を書き込む。 
 - ちなみにこれらの移動履歴は git reflog で確認できる。 
 - COMMIT_EDITMSG の編集 
 - コミットメッセージを設定せずに commit すると自動でエディタが起動するが、そのエディタが開いているファイルが COMMIT_EDITMSG
 - ここに書き込まれている内容が、コミットメッセージとして commit オブジェクトに取り込まれる。 
 休憩中の余談 ①
 shumon.fujita

  317. 451 reset を使っても、本当に commit がなかったことにできるわけではない。 
 reset はあくまでも、HEAD・index・ワークツリーを書き換えるコマンドのため、当然 commit オブジェクトを

    
 削除したりはできない。
 
 そうすると、どこからも参照されていない commit が出来上がることがある。 
 → そういうオブジェクトは一定期間経つと、 git gc というコマンドが走って消される。 
 → ちなみにどこからも参照されていないオブジェクトは git fsck で探せるよ
 休憩中の余談 ②
 shumon.fujita

  318. 453 休憩中の余談 ④
 このあとのgit challengeがうってつけです! 
 gitの設定値が異なったのが原因かも?
 => “git config

    —system core.longpaths true” で変更可能
 他にもwindowsだとサポートされてるパス長に制限があるそう
 要議論 要議論