A Hacker’s Guide to Git の続き。Merging から。
Merging
- とりあえず feature と hotfix な branch で話がすすむ模様
- 先に hotfix を master に merge します
- これは fast-forward されるケイス
- master は hotfix の直接の upstream なので、とのこと
- こうしたケイスでは master のポインタがそのまま hotfix に移動する模様
- 次に feature を master に merge します
- 当たり前ですが fast-forward にはならない
- master は feature の直接の upstream ではありません
- こうした場合、Git は merge commit を作ります (ログを見てみましょう)
- merge commit は二つの parent commit を持ちます
- git show –format=raw で確認できます
- 次のセクションでは master に merge する前に feature を rabase することにより non-fast-forward なマージを防ぐ方法を学ぶ
Rebasing
- rebase は Git の最も誤解されている feature の一つ
- ほとんどの人にとって
git rebase
は回避されるべきコマンド - many anti-rebase article てw
- それが何かを理解している限りは rebase は scary でも dangerous でもない
- でも rebase の前に cherry-picking の context で rebasing を説明するのがはるかに容易なのでちょっとした余談を (ry
Cherry-Picking
あれ、この節って cherry-pick を使って rebase を説明してるのかな。つうかこんな仕掛けだったのか。
むむ、これは凄いな。以下な状態から
C D
o - o <- foo
/
o - o - o - o <- master
A B E F
まずテンポラリな branch を作ります。
$ git checkout master
$ git checkout -b foo-tmp
以下な状態になります。
C D
o - o <- foo
/
o - o - o - o <- master, foo-tmp
A B E F
で、master branch に C および D を cherry-pick します。
$ git cherry-pick C D
すると以下に状態が変わります。
C D
o - o <- foo
/
o - o - o - o - o - o <- master, foo-tmp
A B E F C' D'
ここで branch を foo に切り替えて foo の先頭を foo-tmp の先頭にして
$ git checkout foo
$ git reset --hard foo-tmp
このコマンドで以下な状態になるはず
o - o - o - o - o - o <- master, foo-tmp, foo
A B E F C' D'
で、foo-tmp を削除するとこうなるのか。
o - o - o - o - o - o <- master, foo
A B E F C' D'
これは正に rebase だな。
Rebasing (Continued)
以下の一連のソレが
$ git checkout master
$ git checkout -b foo-tmp
$ git cherry-pick C D
$ git checkout foo
$ git reset --hard foo-tmp
$ git branch -D foo-tmp
以下で記述できるとのこと。
$ git rebase master foo
これ、rebase が先なのか cherry-pick が先なのかはいつか確認してみたいです。あと、本文には記載が無いけど remote に存在する branch を rebase してはいけません。
でも、今や pull request 作るのに rebase は必要不可欠なはずなのでこんな仕組みで、ってのは目から鱗でした。
続きはまた別途で。