45395 - シコウサクゴ -

検証環境と本番環境で構造分岐:機械的cherry-pick不可になったときの3案判断

2026-04-26
インフラ
インフラ運用
Git
ブランチ戦略
設計思考
Last updated:2026-05-07
7 Minutes
1311 Words

検証環境(pre)と本番環境(main)の間で構造リファクタが先に進んでしまい、git cherry-pick約200行の衝突 が発生しました。半日かけて手動解決するか、検証環境を諦めて本番直行するか、判断を迫られました。

最終的に選んだのは 「検証環境への反映を諦め、構造的負債は別施策に逃がす」 という選択。本記事は、このトレードオフの判断軸を整理した記録です。

状況:3ブランチ運用で構造分岐が発生

データ処理プロジェクトでは以下の3ブランチを運用していました。

1
develop → 開発・検証
2
pre → 本番投入前のリハーサル環境
3
main → 本番

ある時期、develop で大規模リファクタ(PR#117以降) を進めました。これは pre/main にはまだ反映されていない構造変更でした。

その状態で、リファクタに依存する新機能(PR#138)を pre に cherry-pick しようとしました。

1
develop: PR#117 リファクタ → PR#138 新機能(リファクタ依存)
2
pre: PR#117 未反映
3
→ pre に PR#138 だけ cherry-pick
4
→ 約200行の衝突発生

衝突200行の中身

衝突箇所は2箇所、約200行。

  • main_pipeline_X.py のクラス構造(PR#117でメソッド再配置済み)
  • 共通モジュールのインターフェース(PR#117で引数追加)

つまり「PR#138 単体では正しく動作する」が「pre のリファクタ前コードには適用できない構造」になっていました。

3案の比較

判断のために3案を並べました。

案A: 強行(手動衝突解決)

  • 半日〜1日かけて衝突を手動解決
  • メリット: pre での Dry-Run 検証が可能
  • デメリット: 衝突解決時のヒューマンエラーリスク、半日の時間コスト

案B: pre 反映スキップ

  • pre をすっ飛ばして main に直接 cherry-pick
  • メリット: 時間コスト最小
  • デメリット: pre Dry-Run の検証効果を失う

案C: 段階分割(縮約版PR起票)

  • PR#138 を pre 互換の縮約版に書き換えた別PRを起票
  • メリット: pre 反映可能、リスク最小
  • デメリット: PR起票・レビュー工数2倍、後で本番版とdiff管理が必要

判断軸:何を最大化すべきか

3案を比較する際、何を最大化したいか を明示しました。

軸1: 時間コスト

  • 案A: 半日〜1日
  • 案B: 30分
  • 案C: 1日(PR2本起票)

軸2: 検証品質

  • 案A: pre Dry-Run可能(高)
  • 案B: pre 検証なし(低)
  • 案C: pre Dry-Run可能(高)

軸3: ヒューマンエラーリスク

  • 案A: 高(手動衝突解決)
  • 案B: 低(コピーのみ)
  • 案C: 中(縮約PR起票)

軸4: 構造的負債の蓄積

  • 案A: なし(develop と pre が同期する)
  • 案B: 中(pre と develop の乖離が拡大)
  • 案C: 高(縮約版という分岐コードが増える)

結論:案B + 構造的負債の別施策化

最終判断は 案B(pre スキップ)+ 構造的負債は別施策化 でした。

なぜ案Bか

  • ヒューマンエラーリスクが最も低い
  • 時間コストが最も低い
  • pre 検証の喪失は、本番投入時の 段階的rollout(X%→100%) で代替できる

構造的負債への対処

「pre と develop の構造分岐」は単独施策として認識し、「TD-CLEANUP」という独立施策 で計画的に解消することにしました。

1
今回の決断: PR#138 は pre スキップで main 直行
2
別施策化: develop の構造リファクタを pre に反映する施策
3
      (規模が大きいので独立PRとして起票)

これにより、

  • 今回の施策(新機能投入)はサクッと終わる
  • 構造分岐は「目に見える施策」として認識される
  • 後でまとめて解消するスケジュールが立てられる

学び:「同期する」より「同期しないことを認める」

これまで「3環境は常に同期させるべき」と思っていました。しかし、

  • リファクタ施策と新機能施策のタイミングは噛み合わない
  • 完全同期にこだわると、毎回半日の衝突解決が発生する
  • 「ある期間、構造的に乖離している」を許容する方が安全

ただし、乖離を許容するには2つの条件が必要です。

条件1: 段階rolloutが効く設計

pre Dry-Run の代わりに、本番でも段階rolloutで検証できる仕組みが必要です。

  • フィーチャーフラグで X%→100%
  • ユーザーセグメント絞り込みで一部公開
  • carbon copy で本番影響なしに動作確認

条件2: 構造的負債の可視化

「pre と develop が乖離している」を施策として認識し、TODO リストに載せる。隠していると忘れます。

まとめ

  • 検証環境と本番環境の構造分岐は、避けられない場合がある
  • 強行(手動解決)/ スキップ / 縮約PRの3案を比較
  • 時間コスト・検証品質・リスク・構造的負債で評価
  • 「同期しないことを認める」+「段階rollout」+「構造的負債の可視化」の3点セットが鍵

完全同期を目指して半日溶かすより、乖離を許容して段階rolloutで検証する 方が、開発のスループットは上がります。

Article title:検証環境と本番環境で構造分岐:機械的cherry-pick不可になったときの3案判断
Article author:45395
Release time:2026-04-26

記事へのご質問・ご感想をお聞かせください

フィードバックを送る