git の merge と rebase の相異

git をいきなり始めても、git merge と git rebase の相異が解りづらい。

大部だけれど、 Git Book http://git-scm.com/book/ja/v1 を読むべきだというのは、ただしい。 Git に限らず、フリーソフトウェアだからといってもドキュメントを整備しないでいい訳がなく、 むしろ整備すべきだと言える。ドキュメントが無いと、多数の人に対して逐一教えて差し上げなければならない、教えなければ利用してもらえないで廃れるというサヴァイヴァルだ。

プロプライエタリの業界では、ドキュメントが無ければ創らせたり、サポートセンタに電凸ネットワーク(笑)すべきである。有料(not 有償。有料=カネ支払を強制すること)であるからむしろ、売上でサポセンを雇ってさらに儲けるというモデルが完成している。サポセンを造った方が儲かり、保守企業を創業させて儲けさせるという業界である。

さてともかくも、Git に関しては多くの人が、 GitHub を見かけて始めてみた、といういきさつだ。 だから、git を熟知せずに ビリーズではないがブートキャンプ(軍隊かっ!)から始める。 それで、 git merge と git rebase の重大な相異も、そもそも git merge の2種類のストラテジも解らないで、git のメッセジ見て「ああそうですか」「言葉の意味は判らないが何だか凄い自信だ」ということになる。

それでとにかく、 merge と rebase の相異だ。 http://git-scm.com/book/ja/v1/Git-%E3%81%AE%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E6%A9%9F%E8%83%BD-%E3%83%AA%E3%83%99%E3%83%BC%E3%82%B9 に書いてある。読むべきだ。

知らないで git pull するのも、git merge をするのも、一人だからリア充の非公開repoで実験するので無ければ危険だと考える。

merge は、複数の、コミット(変更記録)の履歴を、併合する。 rebase は、片方のコミット履歴を、他方の履歴に付け足す。 一言で言うとこうなる。


merge には、 fast-forward と recursive の2種類の遣り方(ストラテジ)がある。

単にコミットを付け足せば構わない(conflict;矛盾、が生じない)ときに行われるのは、fast-forward;単に先へ進む、手法だ。

conflict が生ずるから「佳きに計らえ」ということになったときは、その「佳き計らい」というのは、変更ということなのだから、merge 時に変更を生じ、新たなコミットを記録せねばならない。 矛盾が生じるのは、双方が共通の起原を保ちながらも、別途の進化をしたからで、だから、遡って双方の矛盾を解消せねば、併合することはできないのだ。 だからこれを recursive と呼ぶ。

fast-forward はコミットを生じぬ merge で、 recursive はコミットする merge になる。


次に、 rebase だ。

これは、履歴を変更して、片方の末端に他方のコミットを付け足すものだ。 合併では無く、片方が旧い、他方が新しい、と決めつけて繋げる。

そうすると、履歴の書き換えをせねばならなくなる。 本当は共通の起原から変更されたのに、恰も片方の末端から他方が進化したことにするから、履歴("Git Book"では「歴史」と訳されている)が変わる

履歴が変わるのだから、 git rebase は、リスクの大きい作業だ。 付け足されるコミットの名前 (hash)も変わり、別の名前のコミットにされてしまう。

履歴が変わるので、 git push [origin master] 等するときには、--force しないといけなくなる場合が多い。 整合性が崩壊するからだ。

独りリア充の秘密リポジトリ、俺様だけが創造主の天国では、問題ない。 破壊的創造をするのは、創造主の独裁能力だ。

だが、公開リポジトリや、ましてやコミッタが独りでないリポジトリでは、危険だ。 付け足すコミットが、親を(付け足される側の末端に)変更され、名前も書き換えられてしまう。

GitHub では、公開リポジトリであることが原則だ(なぜならば、GitHub はフリーソフトウェアパラダイスだから)。 そして、そのリポがマイナで誰もフォークしていないクロンすらもしていないならば構わないのだけれど、誰かがクロンして編集していたときには、origin[/upstream] がリベースして、特に master ブランチが書き換わったなんてときには、マトリックス避けかジョジョ立ちのように仰け反ることになる。

逆に自分がクロンやフォークをした側であるときには、upstream と動向をよく見て、変更を同期させる方法を検討すべきだ。 齟齬が生じない最も安全なのは、 merge の fast-forward で解決する場合。 だから、安易に git pull (= git fetch && git merge) をするのには、一定のリスクがある(recursive されて、コミットしてねんと git に云われることがある)。

公開日時:

wjn's repos' info.

  Japenese , English