こわくない Git
- 8. コミットに入ってる情報
リビジョン (SHA-1 ハッシュ)
例: 23cdd334e6e251336ca7dd34e0f6e3ea08b5d0db
Author (コミットを作成した人)
例: オープンソースプロジェクトにパッチを送った人
Committer (コミットを適用した人)
例: 受け取ったパッチを取り込んだ人
ファイルのスナップショット (tree)
コミットで変更されたファイルを含むツリー(説明は省略)
1つ前のコミットのリビジョン
例: 4717e3cf182610e9e82940ac45abb0d422a76d77
- 9. コミットに入ってる情報
リビジョン (SHA-1 ハッシュ)
例: 23cdd334e6e251336ca7dd34e0f6e3ea08b5d0db
Author (コミットを作成した人)
例: オープンソースプロジェクトにパッチを送った人
Committer (コミットを適用した人)
これ重要!!
例: 受け取ったパッチを取り込んだ人
ファイルのスナップショット (tree)
コミットで変更されたファイルを含むツリー(説明は省略)
1つ前のコミットのリビジョン
例: 4717e3cf182610e9e82940ac45abb0d422a76d77
- 11. コミット A があれば
その前の B をたどれる
- 17. new
例えば master に
コミットが4回されたあとの
こんなコミットグラフ
old
- 18. new = master イマココ!!
old
- 19. new
さらに master にもう1回
コミットがされると…
old
- 20. new! = master イマココ!!
old
- 21. つまり
=
ブランチは最新コミットの別名!!
- 29. new = master イマココ!!
old
- 30. git branch topic master
してみると……
new = master
old
- 31. !?
new = master = topic
old
- 32. つまり
= =
ブランチを作る=
コミットのさらなる別名を作る
- 34. この状態から topic に
コミットしてみると……
new = master = topic
old
- 35. new! = topic 伸びた!!
= master
old
- 36. master にコミットしてみると…
new! = topic
= master
old
- 37. new! = master
= topic
枝分かれ!!
old
- 49. 3 = topic = master
2
1
!?
- 50. 3 = topic
2
1
= master
←これが
- 51. 3 = topic = master
2 ここに↑
1 移動しただけ
- 53. topic = master + 1 + 2 + 3
master
- 54. topic = master + 1 + 2 + 3
マージ!!
master + 1 + 2 + 3 = ?
- 55. topic = master + 1 + 2 + 3
master + 1 + 2 + 3 = topic
- 56. topic = master + 1 + 2 + 3
マージ後の master = topic
- 64. = master
= topic
枝分かれ!!
- 70. master + 1 + 2 + 3
中の人「全部まぜちゃえー」
- 71. master + 1 + 2 + 3 = M
中の人「マージ結果ができたよ!」
- 72. = master
3 = topic
2
M
1
中の人「そぉい!!」
- 73. M = master <スポッ
3 = topic
2
1
- 74. M = master ←マージの結果
作られたコミット
3 = topic
2
1
- 75. M = master ←マージの結果
作られたコミット
マージコミット
3 = topic
2
1
\テストに出るぞ/
- 80. git merge topic
Fast-Forward Non Fast-Forward
早送りできればする、無理なら普通のマージ
git merge --no-ff topic
Non Fast-Forward
常に普通のマージ
git merge --ff-only topic
Fast-Forward
常に早送りする(できなければエラーとする)
- 86. 3 = topic = master
2
1
早送りした後の状態から
を消すと…
topic
- 89. = master
直接コミットしたのと
変わらない!!
- 92. = master
おっと、間違って
マージしちゃった (>ω・)
- 93. = master
えーと、マージを
元に戻すにはっと…
- 95. = master
おkおk
コミットを指定すればいいのか
- 96. = master
で、どれが topic の
コミットだっけ……
- 103. ブランチ を master に追従するときに
使ってま す!! マージはなんか怖いし…
rebase すると、コミットログが
キレイになって見やすいよね!!
merge よりも
rebase の方が
マージコミット
もなくて楽でし
ょ?
- 105. 2 = master
1
2 = topic
1
topic
この状態から で
git rebase master すると…
- 106. topic
2 2
1 1
まず、コミットの変更内容を
それぞれパッチにする
- 107. 2 = master = topic
1 移動
2 = topic
1 次に topic を master と
同じコミットに移動させる
(元々の topic ブランチでの
変更は含まなくなる)
- 108. ここまで来たら、作っておいた
パッチを1つずつ順に適用して
コミットしていく
2 = master = topic
1
1 2
( と は省略)
- 110. A ← 1 から作られたコミット
2 = master = topic
1
- 111. A = topic
2 = master
1
- 112. 2
A = topic
2 = master
1
- 113. B ← 2 から作られたコミット
A = topic
2 = master
1
- 114. B = topic
A
2 = master
1
- 115. 重要
2 B
1
≠ A
rebase で作られたコミットは
元のコミットと同じ内容だけど
別のコミットになります!!
- 116. 重要
2 B
1
≠ A
本当?
rebase で作られたコミットは
元のコミットと同じ内容だけど
別のコミットになります!!
- 117. コミットに入ってる情報
リビジョン (SHA-1 ハッシュ)
例: 23cdd334e6e251336ca7dd34e0f6e3ea08b5d0db
Author (コミットを作成した人)
例: オープンソースプロジェクトにパッチを送った人
Committer (コミットを適用した人)
例: 受け取ったパッチを取り込んだ人
ファイルのスナップショット (tree)
コミットで変更されたファイルを含むツリー(説明は省略)
1つ前のコミットのリビジョン
例: 4717e3cf182610e9e82940ac45abb0d422a76d77
- 118. コミットに入ってる情報
リビジョン (SHA-1 ハッシュ)
例: 23cdd334e6e251336ca7dd34e0f6e3ea08b5d0db
Author (コミットを作成した人)
例: オープンソースプロジェクトにパッチを送った人
Committer (コミットを適用した人)
例: 受け取ったパッチを取り込んだ人
ファイルのスナップショット (tree)
コミットで変更されたファイルを含むツリー(説明は省略)
1つ前のコミットのリビジョン
例: 4717e3cf182610e9e82940ac45abb0d422a76d77
- 119. 2 B
1 A
2
1つ前のコミットが違う!!
- 120. 2 B
1 A
2
1つ前のコミットが変わると
リビジョンも変わります
(だから別物になる)
- 125. local origin
2 = topic
push
1
- 126. local origin
2 = topic 2 = topic
1 1
- 127. local origin
3 = topic
2 commit 2 = topic
1 1
- 128. local origin
3 = topic
push
2 2 = topic
1 1
- 131. 3
2
origin「お、2番なら知ってるぞ!」
- 132. local origin
3 = topic
2 2 = topic
1 1
- 133. local origin
3 = topic 3 = topic
2 2 よし、2番の
後ろに追加
1 1
- 134. local origin
3 = topic 3 = topic
2 2
1 1
- 136. local origin
2 = topic 2 = topic
1 1
0 0
- 137. local origin
B = topic 2 = topic
A rebase 1
0 0
- 138. local origin
B = topic 2 = topic
push
A 1
0 0
- 141. B
A
0
origin「あれ? 0番か…」
- 142. B 2
A 1
0 0
origin「もう0番には次のコミットが
あるし、1とAはリビジョンも違う!!」
- 143. local origin
ダメダメ!!
受け付けないよ!!
B = topic 2 = topic
A 1
0 0
- 146. push -f ダメ! 絶対!!
push -f で強制的に上書き push できますが
他の人が pull する時にマージする必要があったり
コミットログがおかしな事になるのでやめましょう
- 152. M git merge master
M
- 154. M git merge topic
M
M
- 155. M
M
と で衝突する修正を
M しない限り、マージ時には
一切コンフリクトしません!
- 158. M
M
この一連の流れを
M もし rebase でやっていると
- 169. 1つ目のパッチを適用
a.txtの1行目を修正するパッチ1つ目↓
1
a.txtの1行目を修正→
- 170. コンフリクト!
a.txtの1行目を修正するパッチ1つ目↓
1
a.txtの1行目を修正→
- 172. 2つ目のパッチを適用
a.txtの1行目を修正するパッチ2つ目↓
2
←a.txtの1行目を修正
a.txtの1行目を修正→
- 173. コンフリクト!
a.txtの1行目を修正するパッチ2つ目↓
2
←a.txtの1行目を修正
a.txtの1行目を修正→
- 174. コンフリクトを解消
←a.txtの1行目を修正
←a.txtの1行目を修正
a.txtの1行目を修正→
- 175. Point
rebase だと
コミットそれぞれについて
コンフリクトの解消が必要
- 176. ちなみに git merge master だと…
←a.txtの1行目を修正
a.txtの1行目を修正→
←a.txtの1行目を修正
- 177. コンフリクトを解消
M
←a.txtの1行目を修正
a.txtの1行目を修正→
←a.txtの1行目を修正
- 178. Point
merge だと
コミットがいくつあろうと
コンフリクト解消は1回だけ
- 179. Point
したがって
rebase よりもむしろ
merge の方が楽です
- 180. リベースの功罪
Good
・コミットグラフがキレイになる
→ マージ後のログがキレイになるので
master にマージする直前にやるのは
OK とする事がある
→ GitHub などのオープンソースプロジェクトに
プルリクエストを送る場合は
rebase してから送るのがマナーとされている
- 181. リベースの功罪
Bad
・push されたブランチをリベースすると
push できなくなる
・「マージした」という事実は失われる
・マージに比べるとコンフリクト解消が面倒