186
こわくない Presented by Kota Saito @ksaito

こわくない Git

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: こわくない Git

こわくない

Presented by Kota Saito @ksaito

Page 2: こわくない Git

こんな人が対象者一応ブランチ作ってコミットしてるけど

実は、マージとかよくわかってない……

エラーが出た時に対処できない……

rebase しちゃダメって何でなの?

Page 3: こわくない Git

Git よくわかんない!

怖い!!

Page 4: こわくない Git

\怖くないよ/

Page 5: こわくない Git

#1 コミットとブランチ

#2 二種類のマージ

#3 リベースの功罪

Page 6: こわくない Git

#1コミットとブランチ

Page 7: こわくない Git

そもそも、コミットってなんだっけ……?

Page 8: こわくない Git

コミットに入ってる情報

リビジョン (SHA-1 ハッシュ)

Author (コミットを作成した人)例: 23cdd334e6e251336ca7dd34e0f6e3ea08b5d0db

Committer (コミットを適用した人)例: オープンソースプロジェクトにパッチを送った人

例: 受け取ったパッチを取り込んだ人

ファイルのスナップショット (tree)コミットで変更されたファイルを含むツリー(説明は省略)

1つ前のコミットのリビジョン例: 4717e3cf182610e9e82940ac45abb0d422a76d77

Page 9: こわくない Git

コミットに入ってる情報

リビジョン (SHA-1 ハッシュ)

Author (コミットを作成した人)例: 23cdd334e6e251336ca7dd34e0f6e3ea08b5d0db

Committer (コミットを適用した人)例: オープンソースプロジェクトにパッチを送った人

例: 受け取ったパッチを取り込んだ人

ファイルのスナップショット (tree)コミットで変更されたファイルを含むツリー(説明は省略)

1つ前のコミットのリビジョン例: 4717e3cf182610e9e82940ac45abb0d422a76d77

これ重要!!

Page 10: こわくない Git

コミット があればA

Page 11: こわくない Git

コミット があればA

Bその前の をたどれる

Page 12: こわくない Git

A

B

C

Page 13: こわくない Git
Page 14: こわくない Git

最新のコミット

最古のコミット

たどれる!!

Page 15: こわくない Git

この概念=

コミットグラフ

\テストに出るぞ/

Page 16: こわくない Git

で、ブランチってなんだっけ……?

Page 17: こわくない Git

例えば にコミットが4回されたあとのこんなコミットグラフ

old

newmaster

Page 18: こわくない Git

old

new master= イマココ!!

Page 19: こわくない Git

さらに にもう1回コミットがされると…

old

new

master

Page 20: こわくない Git

old

new! master= イマココ!!

Page 21: こわくない Git

つまり

=

ブランチは最新コミットの別名!!

Page 22: こわくない Git

ブランチ名の代わりにリビジョンを指定したり

git checkout -b foo 4717e3cf1826

git checkout -b foo master =

Page 23: こわくない Git

リビジョンの代わりにブランチ名を指定したり

git show master

git show 4717e3cf1826=

Page 24: こわくない Git

できる!!

Page 25: こわくない Git

あれ? 枝分かれするブランチの話は?

てか、masterって

ブランチだったのか

Page 26: こわくない Git

git branch topic master

Page 27: こわくない Git

から を作る

git branch mastertopic

topicmaster

Page 28: こわくない Git

例えば にコミットが3回されたあとのこんなコミットグラフ

old

new

master

Page 29: こわくない Git

old

new master= イマココ!!

Page 30: こわくない Git

old

new master=

git branch mastertopic

してみると……

Page 31: こわくない Git

old

new master= topic=

!?

Page 32: こわくない Git

つまり

ブランチを作る=コミットのさらなる別名を作る

==

Page 33: こわくない Git

枝分かれしてなくね?スルーですか?

Page 34: こわくない Git

old

new master= topic=

この状態から にコミットしてみると……

topic

Page 35: こわくない Git

old

new!

master=

topic= 伸びた!!

Page 36: こわくない Git

old

new!

master

=

topic=

にコミットしてみると…

master

Page 37: こわくない Git

old

new! =

topic=

master

枝分かれ!!

Page 38: こわくない Git

Point

初めてコミットした時点で

枝分かれになります。

Page 39: こわくない Git

コミットとブランチ・コミットには「1つ前のコミット」が 含まれるので、最古までたどっていける → コミットグラフ

・ブランチは、そのブランチでの 最新のコミットの別名に過ぎない

・枝分かれは、それぞれのブランチで コミットされて初めて発生する

Page 40: こわくない Git

二種類のマージ

#2

Page 41: こわくない Git

Question

gitのマージには

2種類ある事

知ってましたか?

Page 42: こわくない Git

Fast-Forward and

Non Fast-Forward

Page 43: こわくない Git

Fast-Forward = 早送り

Page 44: こわくない Git

?

Page 45: こわくない Git

master=

topic=

例えばこんなコミットグラフ

Page 46: こわくない Git

topic ブランチに3回コミットした

master=

topic=

1

2

3

Page 47: こわくない Git

master=

topic=

マージ!!1

2

3

git merge topic

Page 48: こわくない Git

master=

topic=

マージ!!1

2

3

グラフはどうなる?

git merge topic

Page 49: こわくない Git

master=topic=

1

2

3

!?

Page 50: こわくない Git

master=

topic=

1

2

3

←これが

Page 51: こわくない Git

master=topic=

1

2

3

ここに↑移動しただけ

Page 52: こわくない Git

Why?

Page 53: こわくない Git

mastertopic = 1 2 3+ + +

master

Page 54: こわくない Git

mastertopic = 1 2 3+ + +

master 1 2 3+ + + =

マージ!!

?

Page 55: こわくない Git

mastertopic = 1 2 3+ + +

master 1 2 3+ + + = topic

Page 56: こわくない Git

mastertopic = 1 2 3+ + +

master = topicマージ後の

Page 57: こわくない Git

中の人「どうせ同じ内容になるならいちいちマージしなくてよくね?」

Page 58: こわくない Git

master=topic=

1

2

3

master=

中の人「マージ後に topic と同じ内容になるならtopic のところまで進めちゃおうぜww」

進める

Page 59: こわくない Git

これが Fast-Forward

Page 60: こわくない Git

マージのかわりに早送り。Fast-Forward

Page 61: こわくない Git

\ドヤァ…/

Page 62: こわくない Git

Non Fast-Forward

Page 63: こわくない Git

master=

topic=

さっきのコミットグラフから    にコミットすると…master

Page 64: こわくない Git

master=

topic=

枝分かれ!!

Page 65: こわくない Git

master ≠ topicマージ後の

Page 66: こわくない Git

中の人「早送りできない><」

Page 67: こわくない Git

中の人「ちゃんとマージするかー」

Page 68: こわくない Git

master=

topic=

git merge topic

マージ!!1

2

3

Page 69: こわくない Git

〜中の人計算中〜

「えーと master の内容と topic のコミットを比較して…」

「衝突してたら教えてあげなきゃ…」

Page 70: こわくない Git

master 1 2 3+ + +

中の人「全部まぜちゃえー」

Page 71: こわくない Git

Mmaster =1 2 3+ + +

中の人「マージ結果ができたよ!」

Page 72: こわくない Git

master=

topic=

1

2

3

M

中の人「そぉい!!」

Page 73: こわくない Git

master=

topic=

1

2

3

M <スポッ

Page 74: こわくない Git

master=

topic=

1

2

3

M ←マージの結果 作られたコミット

Page 75: こわくない Git

master=

topic=

1

2

3

M ←マージの結果 作られたコミット

マージコミット

\テストに出るぞ/

Page 76: こわくない Git

Non Fast-Forward

Page 77: こわくない Git

早送りじゃないマージ。Non Fast-Forward

Page 78: こわくない Git

\ドヤヤヤァ…/

Page 79: こわくない Git

ちなみに

Page 80: こわくない Git

git merge topic早送りできればする、無理なら普通のマージ

Non Fast-ForwardFast-Forward

常に普通のマージNon Fast-Forward

常に早送りする(できなければエラーとする)Fast-Forward

git merge --no-ff topic

git merge --ff-only topic

Page 81: こわくない Git

ところが

Page 82: こわくない Git

議論がある

Page 83: こわくない Git

常に git merge --no-ff すべきだ!

訳: 早送りマージすんな!

Page 84: こわくない Git

\えっ/

Page 85: こわくない Git

Why?

Page 86: こわくない Git

master=topic=

1

2

3

早送りした後の状態から     を消すと…topic

Page 87: こわくない Git

master=

1

2

3

ん?

Page 88: こわくない Git

master=

あれ?1

2

3

Page 89: こわくない Git

master=

直接コミットしたのと変わらない!!

Page 90: こわくない Git

master=

\    の霊圧が消えた…!?/topic

Page 91: こわくない Git

Fast-Forward の弊害①

「ブランチをマージした」という事実が歴史(コミットグラフ)に残らない

Page 92: こわくない Git

master=

おっと、間違ってマージしちゃった (>ω・)

Page 93: こわくない Git

master=

えーと、マージを元に戻すにはっと…

Page 94: こわくない Git

git revert <commit><commit> (リビジョン) のコミットを取り消すためのコミットを作る

git reset --hard <commit><commit> (リビジョン) 時点の状態まで完全に巻き戻す

Page 95: こわくない Git

master=

おkおkコミットを指定すればいいのか

Page 96: こわくない Git

master=

で、どれが topic のコミットだっけ……

Page 97: こわくない Git

Fast-Forward の弊害②

「ブランチのマージ」を取り消しづらい

Page 98: こわくない Git

Point

マージの種類を意識して

マージしましょう!

Page 99: こわくない Git

二種類のマージ・Fast-Forward = 早送り

 ・コミットグラフ的に結果が同じなら  同じコミットまで進めてしまうこと

 ・「マージした」という記録が残らない

 ・マージを取り消しづらい

・Non Fast-Forward = 普通のマージ

 ・Git ががんばって計算するマージ

Page 100: こわくない Git

リベースの功罪

#3

Page 101: こわくない Git

git 初心者が陥りがちな罠

第1位(個人的に)

Page 102: こわくない Git

git rebaseリベーーーーーース

Page 103: こわくない Git

ブランチを master に追従するときに

使ってます!! マージはなんか怖いし…

rebase すると、コミットログがキレイになって見やすいよね!!

merge よりも rebase の方がマージコミットもなくて楽でしょ?

Page 104: こわくない Git

Question

そもそも rebase が

なにをするのか

理解していますか?

Page 105: こわくない Git

master=

topic=

1

2

1

2

この状態から     で

git rebase master すると…

topic

Page 106: こわくない Git

topic

1

2

1

2

まず、コミットの変更内容をそれぞれパッチにする

Page 107: こわくない Git

master=

topic=

1

2

1

2 topic=

移動

次に topic を master と同じコミットに移動させる(元々の topic ブランチでの 変更は含まなくなる)

Page 108: こわくない Git

master=

1

2 topic=

21(  と  は省略)

ここまで来たら、作っておいたパッチを1つずつ順に適用してコミットしていく

Page 109: こわくない Git

master=

1

2 topic=

1差分を適用してコミット

Page 110: こわくない Git

master=

1

2 topic=

1A ← から作られたコミット

Page 111: こわくない Git

master=

1

2

topic=A

Page 112: こわくない Git

master=

1

2

A

2

topic=

Page 113: こわくない Git

master=

1

2

A topic=

B 2← から作られたコミット

Page 114: こわくない Git

master=

1

2

topic=

A

B

Page 115: こわくない Git

2

1 A

B≠

重要

rebase で作られたコミットは元のコミットと同じ内容だけど別のコミットになります!!

Page 116: こわくない Git

rebase で作られたコミットは元のコミットと同じ内容だけど別のコミットになります!!

2

1 A

B≠

重要

本当?

Page 117: こわくない Git

コミットに入ってる情報

リビジョン (SHA-1 ハッシュ)

Author (コミットを作成した人)例: 23cdd334e6e251336ca7dd34e0f6e3ea08b5d0db

Committer (コミットを適用した人)例: オープンソースプロジェクトにパッチを送った人

例: 受け取ったパッチを取り込んだ人

ファイルのスナップショット (tree)コミットで変更されたファイルを含むツリー(説明は省略)

1つ前のコミットのリビジョン例: 4717e3cf182610e9e82940ac45abb0d422a76d77

Page 118: こわくない Git

コミットに入ってる情報

リビジョン (SHA-1 ハッシュ)

Author (コミットを作成した人)例: 23cdd334e6e251336ca7dd34e0f6e3ea08b5d0db

Committer (コミットを適用した人)例: オープンソースプロジェクトにパッチを送った人

例: 受け取ったパッチを取り込んだ人

ファイルのスナップショット (tree)コミットで変更されたファイルを含むツリー(説明は省略)

1つ前のコミットのリビジョン例: 4717e3cf182610e9e82940ac45abb0d422a76d77

Page 119: こわくない Git

1

2

2

A

B

1つ前のコミットが違う!!

Page 120: こわくない Git

1

2

2

A

B

1つ前のコミットが変わるとリビジョンも変わります(だから別物になる)

Page 121: こわくない Git

Point

rebaseで作られるコミットは

元のコミットとは別物

Page 122: こわくない Git

別物でも、同じ変更がされるから問題ない気が

Page 123: こわくない Git

git push origin topic

Page 124: こわくない Git

git push origin topic

topic を origin (サーバー) に同期

Page 125: こわくない Git

topic=

1

2

local origin

push

Page 126: こわくない Git

topic=

1

2

local origin

topic=

1

2

Page 127: こわくない Git

topic=

1

2

local origin

topic=

1

2

3

commit

Page 128: こわくない Git

topic=

1

2

local origin

topic=

1

2

3

push

Page 129: こわくない Git

origin「お、pushがきたぞ?どれどれ、内容を見てみよう」

Page 130: こわくない Git

3

origin「新しいコミットは1つだけか」

「さて、こいつの前のコミットは…」

Page 131: こわくない Git

3

origin「お、2番なら知ってるぞ!」

2

Page 132: こわくない Git

topic=

1

2

local origin

topic=

1

2

3

Page 133: こわくない Git

topic=

1

2

local origintopic=

1

2

3 3

よし、2番の後ろに追加

Page 134: こわくない Git

topic=

1

2

local origintopic=

1

2

3 3

Page 135: こわくない Git

push after rebase

Page 136: こわくない Git

topic=

1

2

local origin

topic=

1

2

0 0

Page 137: こわくない Git

topic=

A

B

local origin

topic=

1

2

rebase

0 0

Page 138: こわくない Git

topic=

A

B

local origin

topic=

1

2

push

00

Page 139: こわくない Git

origin「お、pushがきたぞ?どれどれ、内容を見てみよう」

Page 140: こわくない Git

origin「新しいコミットは2つか」

「さて、こいつの前のコミットは…」

A

B

Page 141: こわくない Git

origin「あれ? 0番か…」

A

B

0

Page 142: こわくない Git

origin「もう0番には次のコミットがあるし、1とAはリビジョンも違う!!」

A

B

0

1

2

0

Page 143: こわくない Git

topic=

A

B

local origin

topic=

1

2

00

ダメダメ!!受け付けないよ!!

Page 144: こわくない Git

Point

push されているブランチを

rebase すると

push できなくなる

Page 145: こわくない Git

Point

よって、共有のブランチでは

rebase してはいけない !!

Page 146: こわくない Git

push -f ダメ! 絶対!!

push -f で強制的に上書き push できますが他の人が pull する時にマージする必要があったりコミットログがおかしな事になるのでやめましょう

Page 147: こわくない Git

ブランチを master に追従するときに

使ってます!! マージはなんか怖いし…

Page 148: こわくない Git

\怖くないよ/

Page 149: こわくない Git
Page 150: こわくない Git

M git merge master

Page 151: こわくない Git

M

Page 152: こわくない Git

M

M git merge master

Page 153: こわくない Git

M

M

Page 154: こわくない Git

M

M

M git merge topic

Page 155: こわくない Git

M

M

M

  と  で衝突する修正をしない限り、マージ時には一切コンフリクトしません!

Page 156: こわくない Git

Point

git のマージは

相当かしこい

Page 157: こわくない Git

rebase すると、コミットログがキレイになって見やすいよね!!

Page 158: こわくない Git

M

M

M

この一連の流れをもし rebase でやっていると

Page 159: こわくない Git

確かに一直線でキレイ

Page 160: こわくない Git

お気づきだろうか…

Page 161: こわくない Git

ヒソヒソ…(なあ、もしかして 俺たち忘れられてないか?)

M M M

Page 162: こわくない Git

マージの記録は残らない

Page 163: こわくない Git

えっ

M M M

Page 164: こわくない Git

Point

rebase でコミットグラフは

一直線にキレイになるが

その陰で失われる情報がある

Page 165: こわくない Git

Point

そもそも git で

入り組んだグラフになっても

そんなに気にすることはない

Page 166: こわくない Git

merge よりも rebase の方がマージコミットもなくて楽でしょ?

Page 167: こわくない Git

←a.txtの1行目を修正a.txtの1行目を修正→

ここから git rebase master すると…

←a.txtの1行目を修正

Page 168: こわくない Git

a.txtの1行目を修正→

コミットがそれぞれパッチになって…

2

1

Page 169: こわくない Git

a.txtの1行目を修正→

a.txtの1行目を修正するパッチ1つ目↓

1つ目のパッチを適用

1

Page 170: こわくない Git

a.txtの1行目を修正→

a.txtの1行目を修正するパッチ1つ目↓

1

コンフリクト!

Page 171: こわくない Git

a.txtの1行目を修正→

コンフリクトを解消

←a.txtの1行目を修正

Page 172: こわくない Git

a.txtの1行目を修正→

2つ目のパッチを適用

←a.txtの1行目を修正

2

a.txtの1行目を修正するパッチ2つ目↓

Page 173: こわくない Git

a.txtの1行目を修正→

←a.txtの1行目を修正

2

a.txtの1行目を修正するパッチ2つ目↓

コンフリクト!

Page 174: こわくない Git

a.txtの1行目を修正→

コンフリクトを解消

←a.txtの1行目を修正

←a.txtの1行目を修正

Page 175: こわくない Git

Point

rebase だと

コミットそれぞれについて

コンフリクトの解消が必要

Page 176: こわくない Git

←a.txtの1行目を修正a.txtの1行目を修正→

ちなみに git merge master だと…

←a.txtの1行目を修正

Page 177: こわくない Git

←a.txtの1行目を修正a.txtの1行目を修正→

←a.txtの1行目を修正

M

コンフリクトを解消

Page 178: こわくない Git

Point

merge だと

コミットがいくつあろうと

コンフリクト解消は1回だけ

Page 179: こわくない Git

Point

したがって

rebase よりもむしろ

merge の方が楽です

Page 180: こわくない Git

リベースの功罪Good

・コミットグラフがキレイになる → マージ後のログがキレイになるので   master にマージする直前にやるのは   OK とする事がある → GitHub などのオープンソースプロジェクトに   プルリクエストを送る場合は   rebase してから送るのがマナーとされている

Page 181: こわくない Git

リベースの功罪Bad

・push されたブランチをリベースすると push できなくなる

・「マージした」という事実は失われる

・マージに比べるとコンフリクト解消が面倒

Page 182: こわくない Git

すこしは git の

理解の手助けに

なれたでしょうか?

Page 183: こわくない Git

\怖くないよ/

Page 184: こわくない Git

\ズッ友だょ……!!/

Page 185: こわくない Git

Have a Nice Git!

Page 186: こわくない Git

ReferencesPro Git bookhttp://git-scm.com/book/ja/

git merge or rebase, ff or no-ff - Togetterhttp://togetter.com/li/407277

A successful Git branching modelhttp://nvie.com/posts/a-successful-git-branching-model/