/var/log/messages

Oct 22, 2014 - 2 minute read - Comments - Git

A Hackers Guide to Git (2)

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 は必要不可欠なはずなのでこんな仕組みで、ってのは目から鱗でした。

続きはまた別途で。