git: 大規模なマージ

Takami Torao #git
  • このエントリーをはてなブックマークに追加

想定: あなたのチームはあるリポジトリ Alice 1.x をフォークしていくつかの機能を修正した Bob 1.x を開発している。いままで Alice 側の修正は alice/master ブランチ上の v1.x.y リリースタグを bob/develop にマージすることで取り込んでいた。

さて、Alice 2.0 リリースに追従してあなたのチームも Bob 2.0 を準備する必要がでてきた。Alice 2.0 は、Alice 1.x から派生しているとはいえ分岐してからの開発期間が長く大規模な改修が行われている。一部のモジュールは 1.x から大きくかけ離れたソースになっている。Alice 2.0 を Bob 2.0 へどの様にマージするのが良いだろうか?

  1. プラン1: 素直に rebase する
  2. プラン2: Alice 1.0 と Bob 1.0 の差分のみをマージする
  3. プラン3: Bob 1.x に追加した commit をすべて cherry-pick でマージする

プラン1: 素直に rebase する

  • Pros. 正攻法。修正差分が少ないのであればこれで良い。
  • Cons. Alice の修正と Bob の修正を含めた膨大なマージ作業が必要。

プラン2: Alice 1.0 と Bob 1.0 の差分のみをマージする

  • Pros. ファイル数は多くなるがマージは 1 回で済む最短時間の方法。
  • Cons. 過去の Bob 1.0 で行った commit が 2.0 からすべて消える。

プラン3: Bob 1.x に追加した commit をすべて cherry-pick でマージする

  • Pros. Bob 1.x での変更履歴を残しつつ最小限のマージ作業。
  • Cons. 過去の Bob 1.0 の修正すべてを一つずつで行った commit が 2.0 からすべて消える。

作業ブランチで

git --no-pager log | grep -b3 -E "Author: (開発者の名前1|開発者の名前2|...)" | grep "\-commit " | cut -d" " -f2 | tac

これで表示される commit を cherry-pick で tac は入力を逆順で出力するコマンド。macOS では brew install coreutils でインストールできる。

出力されたハッシュ値のリストをファイルに保存し、alice/v2.0 から分岐した bob/v2.0 をチェックアウトしてリスト先頭のコミットから cherry-pick を適用してゆく。

git cherry-pick $HASH

単に Alice 1.x の最新修正を Bob 1.x にマージしているだけの commit はスキップして良い。

F