こわくない Git

  • 353,166 views
Uploaded on

「マージがなんとなく怖い」「リベースするなって怒られて怖い」「エラーが出て怖い」 …

「マージがなんとなく怖い」「リベースするなって怒られて怖い」「エラーが出て怖い」
Git 入門者にありがちな「Git 怖い」を解消するため、Git のお仕事(コミット、ブランチ、マージ、リベース)について解説します。

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
353,166
On Slideshare
0
From Embeds
0
Number of Embeds
133

Actions

Shares
Downloads
1,965
Comments
14
Likes
1,215

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. こわくないPresented by Kota Saito @ksaito
  • 2. こんな人が対象者一応ブラン チ作ってコミットしてるけど実は、マー ジとかよくわかってない…… エラーが出た時に対処できない…… rebase しちゃダ メって何でな の?
  • 3. Git よくわかんない! 怖い!!
  • 4. \怖くないよ/
  • 5. #1 コミットとブランチ#2 二種類のマージ#3 リベースの功罪
  • 6. コミットとブランチ
  • 7. そもそも、コミットってなんだっけ……?
  • 8. コミットに入ってる情報 リビジョン (SHA-1 ハッシュ) 例: 23cdd334e6e251336ca7dd34e0f6e3ea08b5d0db Author (コミットを作成した人) 例: オープンソースプロジェクトにパッチを送った人 Committer (コミットを適用した人) 例: 受け取ったパッチを取り込んだ人 ファイルのスナップショット (tree) コミットで変更されたファイルを含むツリー(説明は省略) 1つ前のコミットのリビジョン 例: 4717e3cf182610e9e82940ac45abb0d422a76d77
  • 9. コミットに入ってる情報 リビジョン (SHA-1 ハッシュ) 例: 23cdd334e6e251336ca7dd34e0f6e3ea08b5d0db Author (コミットを作成した人) 例: オープンソースプロジェクトにパッチを送った人 Committer (コミットを適用した人) これ重要!! 例: 受け取ったパッチを取り込んだ人 ファイルのスナップショット (tree) コミットで変更されたファイルを含むツリー(説明は省略) 1つ前のコミットのリビジョン 例: 4717e3cf182610e9e82940ac45abb0d422a76d77
  • 10. コミット A があれば
  • 11. コミット A があればその前の B をたどれる
  • 12. ABC
  • 13. 最新のコミット たどれる!!最古のコミット
  • 14. この概念=コミットグラフ \テストに出るぞ/
  • 15. で、ブランチってなんだっけ……?
  • 16. new 例えば master に コミットが4回されたあとの こんなコミットグラフold
  • 17. new = master イマココ!!old
  • 18. new さらに master にもう1回 コミットがされると…old
  • 19. new! = master イマココ!!old
  • 20. つまり =ブランチは最新コミットの別名!!
  • 21. ブランチ名の代わりにリビジョンを指定したりgit checkout -b foo master =git checkout -b foo 4717e3cf1826
  • 22. リビジョンの代わりにブランチ名を指定したり git show 4717e3cf1826 = git show master
  • 23. できる!!
  • 24. あれ? 枝分かれするブランチの話は?てか、masterってブランチだったのか
  • 25. git branch topic master
  • 26. git branch topic mastermaster から topic を作る
  • 27. 例えば master にnew コミットが3回されたあとの こんなコミットグラフold
  • 28. new = master イマココ!!old
  • 29. git branch topic master してみると……new = masterold
  • 30. !?new = master = topicold
  • 31. つまり = = ブランチを作る=コミットのさらなる別名を作る
  • 32. 枝分かれしてなくね?スルーですか?
  • 33. この状態から topic に コミットしてみると……new = master = topicold
  • 34. new! = topic 伸びた!! = masterold
  • 35. master にコミットしてみると…new! = topic = masterold
  • 36. new! = master = topic 枝分かれ!!old
  • 37. Point初めてコミットした時点で枝分かれになります。
  • 38. コミットとブランチ・コミットには「1つ前のコミット」が 含まれるので、最古までたどっていける → コミットグラフ・ブランチは、そのブランチでの 最新のコミットの別名に過ぎない・枝分かれは、それぞれのブランチで コミットされて初めて発生する
  • 39. 二種類のマージ
  • 40. Questiongitのマージには 2種類ある事知ってましたか?
  • 41. Fast-Forward andNon Fast-Forward
  • 42. Fast-Forward = 早送り
  • 43. ?
  • 44. 例えばこんなコミットグラフ = topic= master
  • 45. topic ブランチに3回コミットした 3 = topic 2 1= master
  • 46. git merge topic 3 = topic2 1 マージ!!= master
  • 47. git merge topic 3 = topic2 1 マージ!! グラフはどうなる?= master
  • 48. 3 = topic = master21 !?
  • 49. 3 = topic2 1= master ←これが
  • 50. 3 = topic = master2 ここに↑1 移動しただけ
  • 51. Why?
  • 52. topic = master + 1 + 2 + 3master
  • 53. topic = master + 1 + 2 + 3 マージ!!master + 1 + 2 + 3 = ?
  • 54. topic = master + 1 + 2 + 3master + 1 + 2 + 3 = topic
  • 55. topic = master + 1 + 2 + 3マージ後の master = topic
  • 56. 中の人「どうせ同じ内容になるならいちいちマージしなくてよくね?」
  • 57. 中の人「マージ後に topic と同じ内容になるなら topic のところまで進めちゃおうぜww」 3 = topic = master 2 1 進める = master
  • 58. これが Fast-Forward
  • 59. Fast-Forwardマージのかわりに早送り。
  • 60. \ドヤァ…/
  • 61. Non Fast-Forward
  • 62. さっきのコミットグラフから    にコミットすると…master = topic= master
  • 63. = master = topic 枝分かれ!!
  • 64. マージ後の master ≠ topic
  • 65. 中の人「早送りできない><」
  • 66. 中の人「ちゃんとマージするかー」
  • 67. git merge topic= master 3 = topic 2 1 マージ!!
  • 68. 〜中の人計算中〜「えーと master の内容と topic のコミットを比較して…」 「衝突してたら教えてあげなきゃ…」
  • 69. master + 1 + 2 + 3中の人「全部まぜちゃえー」
  • 70. master + 1 + 2 + 3 = M中の人「マージ結果ができたよ!」
  • 71. = master 3 = topic 2 M 1 中の人「そぉい!!」
  • 72. M = master <スポッ 3 = topic 2 1
  • 73. M = master ←マージの結果  作られたコミット 3 = topic 2 1
  • 74. M = master ←マージの結果  作られたコミット マージコミット 3 = topic 2 1 \テストに出るぞ/
  • 75. Non Fast-Forward
  • 76. Non Fast-Forward早送りじゃないマージ。
  • 77. \ドヤヤヤァ…/
  • 78. ちなみに
  • 79. git merge topicFast-Forward Non Fast-Forward早送りできればする、無理なら普通のマージgit merge --no-ff topic Non Fast-Forward常に普通のマージgit merge --ff-only topic Fast-Forward常に早送りする(できなければエラーとする)
  • 80. ところが
  • 81. 議論がある
  • 82. 常に git merge --no-ff すべきだ! 訳: 早送りマージすんな!
  • 83. \えっ/
  • 84. Why?
  • 85. 3 = topic = master21 早送りした後の状態から      を消すと… topic
  • 86. 3 = master21 ん?
  • 87. 3 = master21 あれ?
  • 88. = master 直接コミットしたのと 変わらない!!
  • 89. \    の霊圧が消えた…!?/ topic = master
  • 90. Fast-Forward の弊害①「ブランチをマージした」という事実が 歴史(コミットグラフ)に残らない
  • 91. = master おっと、間違って マージしちゃった (>ω・)
  • 92. = master えーと、マージを 元に戻すにはっと…
  • 93. git revert <commit><commit> (リビジョン) のコミットを取り消すためのコミットを作るgit reset --hard <commit><commit> (リビジョン) 時点の状態まで完全に巻き戻す
  • 94. = master おkおk コミットを指定すればいいのか
  • 95. = master で、どれが topic の コミットだっけ……
  • 96. Fast-Forward の弊害② 「ブランチのマージ」を 取り消しづらい
  • 97. Pointマージの種類を意識してマージしましょう!
  • 98. 二種類のマージ・Fast-Forward = 早送り ・コミットグラフ的に結果が同じなら  同じコミットまで進めてしまうこと ・「マージした」という記録が残らない ・マージを取り消しづらい・Non Fast-Forward = 普通のマージ ・Git ががんばって計算するマージ
  • 99. リベースの功罪
  • 100. git 初心者が陥りがちな罠 第1位 (個人的に)
  • 101. リベーーーーーースgit rebase
  • 102. ブランチ を master に追従するときに使ってま す!! マージはなんか怖いし… rebase すると、コミットログが キレイになって見やすいよね!! merge よりも rebase の方が マージコミット もなくて楽でし ょ?
  • 103. Questionそもそも rebase が なにをするのか理解していますか?
  • 104. 2 = master1 2 = topic 1 topic この状態から     で git rebase master すると…
  • 105. topic 2 2 1 1まず、コミットの変更内容をそれぞれパッチにする
  • 106. 2 = master = topic1 移動 2 = topic 1 次に topic を master と 同じコミットに移動させる (元々の topic ブランチでの  変更は含まなくなる)
  • 107. ここまで来たら、作っておいた パッチを1つずつ順に適用して コミットしていく2 = master = topic1 1 2 (  と  は省略)
  • 108. 差分を適用してコミット 12 = master = topic1
  • 109. A ← 1 から作られたコミット2 = master = topic1
  • 110. A = topic2 = master1
  • 111. 2 A = topic2 = master1
  • 112. B ← 2 から作られたコミット A = topic2 = master1
  • 113. B = topic A2 = master1
  • 114. 重要 2 B 1 ≠ Arebase で作られたコミットは元のコミットと同じ内容だけど別のコミットになります!!
  • 115. 重要 2 B 1 ≠ A 本当?rebase で作られたコミットは元のコミットと同じ内容だけど別のコミットになります!!
  • 116. コミットに入ってる情報 リビジョン (SHA-1 ハッシュ) 例: 23cdd334e6e251336ca7dd34e0f6e3ea08b5d0db Author (コミットを作成した人) 例: オープンソースプロジェクトにパッチを送った人 Committer (コミットを適用した人) 例: 受け取ったパッチを取り込んだ人 ファイルのスナップショット (tree) コミットで変更されたファイルを含むツリー(説明は省略) 1つ前のコミットのリビジョン 例: 4717e3cf182610e9e82940ac45abb0d422a76d77
  • 117. コミットに入ってる情報 リビジョン (SHA-1 ハッシュ) 例: 23cdd334e6e251336ca7dd34e0f6e3ea08b5d0db Author (コミットを作成した人) 例: オープンソースプロジェクトにパッチを送った人 Committer (コミットを適用した人) 例: 受け取ったパッチを取り込んだ人 ファイルのスナップショット (tree) コミットで変更されたファイルを含むツリー(説明は省略) 1つ前のコミットのリビジョン 例: 4717e3cf182610e9e82940ac45abb0d422a76d77
  • 118. 2 B 1 A 21つ前のコミットが違う!!
  • 119. 2 B 1 A 21つ前のコミットが変わると リビジョンも変わります (だから別物になる)
  • 120. Pointrebaseで作られるコミットは 元のコミットとは別物
  • 121. 別物でも、同じ変更がされるから問題ない気が
  • 122. git push origin topic
  • 123. git push origin topic topic を origin (サーバー) に同期
  • 124. local origin2 = topic push1
  • 125. local origin2 = topic 2 = topic1 1
  • 126. local origin3 = topic2 commit 2 = topic1 1
  • 127. local origin3 = topic push2 2 = topic1 1
  • 128. origin「お、pushがきたぞ?どれどれ、内容を見てみよう」
  • 129. origin「新しいコミットは1つだけか」 3「さて、こいつの前のコミットは…」
  • 130. 3 2origin「お、2番なら知ってるぞ!」
  • 131. local origin3 = topic2 2 = topic1 1
  • 132. local origin3 = topic 3 = topic2 2 よし、2番の 後ろに追加1 1
  • 133. local origin3 = topic 3 = topic2 21 1
  • 134. push after rebase
  • 135. local origin2 = topic 2 = topic1 10 0
  • 136. local originB = topic 2 = topicA rebase 10 0
  • 137. local originB = topic 2 = topic pushA 10 0
  • 138. origin「お、pushがきたぞ?どれどれ、内容を見てみよう」
  • 139. origin「新しいコミットは2つか」 B A「さて、こいつの前のコミットは…」
  • 140. B A 0origin「あれ? 0番か…」
  • 141. B 2 A 1 0 0origin「もう0番には次のコミットがあるし、1とAはリビジョンも違う!!」
  • 142. local origin ダメダメ!! 受け付けないよ!!B = topic 2 = topicA 10 0
  • 143. Pointpush されているブランチを rebase すると push できなくなる
  • 144. Pointよって、共有のブランチではrebase してはいけない !!
  • 145. push -f ダメ! 絶対!! push -f で強制的に上書き push できますが他の人が pull する時にマージする必要があったりコミットログがおかしな事になるのでやめましょう
  • 146. ブ ランチを master に追従するときに使ってます !! マージはなんか怖いし…
  • 147. \怖くないよ/
  • 148. M git merge master
  • 149. M
  • 150. M git merge masterM
  • 151. MM
  • 152. M git merge topic M M
  • 153. M M   と  で衝突する修正を M しない限り、マージ時には 一切コンフリクトしません!
  • 154. Pointgit のマージは相当かしこい
  • 155. rebase すると、コミットログがキレイになって見やすいよね!!
  • 156. M M この一連の流れを M もし rebase でやっていると
  • 157. 確かに一直線でキレイ
  • 158. お気づきだろうか…
  • 159. ヒソヒソ…(なあ、もしかして 俺たち忘れられてないか?) M M M
  • 160. マージの記録は残らない
  • 161. えっM M M
  • 162. Pointrebase でコミットグラフは 一直線にキレイになるがその陰で失われる情報がある
  • 163. Point そもそも git で入り組んだグラフになってもそんなに気にすることはない
  • 164. merge よりも rebase の方がマージコミット もなくて楽でし ょ?
  • 165. ここから git rebase master すると… ←a.txtの1行目を修正a.txtの1行目を修正→ ←a.txtの1行目を修正
  • 166. コミットがそれぞれパッチになって… 2a.txtの1行目を修正→ 1
  • 167. 1つ目のパッチを適用 a.txtの1行目を修正するパッチ1つ目↓ 1a.txtの1行目を修正→
  • 168. コンフリクト! a.txtの1行目を修正するパッチ1つ目↓ 1a.txtの1行目を修正→
  • 169. コンフリクトを解消 ←a.txtの1行目を修正a.txtの1行目を修正→
  • 170. 2つ目のパッチを適用 a.txtの1行目を修正するパッチ2つ目↓ 2 ←a.txtの1行目を修正a.txtの1行目を修正→
  • 171. コンフリクト! a.txtの1行目を修正するパッチ2つ目↓ 2 ←a.txtの1行目を修正a.txtの1行目を修正→
  • 172. コンフリクトを解消 ←a.txtの1行目を修正 ←a.txtの1行目を修正a.txtの1行目を修正→
  • 173. Point rebase だとコミットそれぞれについてコンフリクトの解消が必要
  • 174. ちなみに git merge master だと… ←a.txtの1行目を修正a.txtの1行目を修正→ ←a.txtの1行目を修正
  • 175. コンフリクトを解消 M ←a.txtの1行目を修正a.txtの1行目を修正→ ←a.txtの1行目を修正
  • 176. Point merge だとコミットがいくつあろうとコンフリクト解消は1回だけ
  • 177. Point したがってrebase よりもむしろmerge の方が楽です
  • 178. リベースの功罪 Good・コミットグラフがキレイになる → マージ後のログがキレイになるので   master にマージする直前にやるのは   OK とする事がある → GitHub などのオープンソースプロジェクトに   プルリクエストを送る場合は   rebase してから送るのがマナーとされている
  • 179. リベースの功罪 Bad・push されたブランチをリベースすると push できなくなる・「マージした」という事実は失われる・マージに比べるとコンフリクト解消が面倒
  • 180. すこしは git の 理解の手助けになれたでしょうか?
  • 181. \怖くないよ/
  • 182. \ズッ友だょ……!!/
  • 183. Have a Nice Git!
  • 184. ReferencesPro Git bookhttp://git-scm.com/book/ja/git merge or rebase, ff or no-ff - Togetterhttp://togetter.com/li/407277A successful Git branching modelhttp://nvie.com/posts/a-successful-git-branching-model/