安全なMergeを行う開発フロー

369件のシェア(そこそこ話題の記事)

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

渡辺です。

スノーボードでのスピン(回転)では、フロントサイド(前回り)は視界に向けて回るので比較的に簡単です。 ところが、バックサイド(背中周り)は非常に難しいと感じます。 これは見えない方向への回転なので見えないためであり、恐怖心が原因です。

解らないのは怖いことです。 解ってしまえば意外と簡単だったりします。 「幽霊の正体見たり枯れ尾花」とは良く言ったものですね。 Git(バージョン管理)のMergeも同様です。 Mergeの正体を理解し、恐怖心をなくしましょう。

最後の最後は気合いで手動Merge

はじめにお断りしますが、Mergeを理解したとしても、手動でMergeする作業がなくなるわけではありません。 そして、手動でMergeするときは、最終的に気合いでMergeする以外の方法はありません(笑) しかし、Mergeを理解しConflict(競合)が発生しにくい運用を行うことで、手動Mergeの頻度は圧倒的に低くなります

BranchとMerge

Branchは、コミットラインを複数に分岐させ、本流に影響を与えずにバージョン管理を行うための機能です。

Branchを使わない場合、コミット履歴は1本の線となります。 開発者が1人しかいないのであれば、Branchを使わなくとも不自由はありませんが、開発者が複数いる場合には様々な問題を発生させます。 例えば、他の開発者に影響を与えてしまうため、ある程度まとまった単位でなければ変更をコミットできません。 同じソースファイルを編集していた場合、Conflict(競合)が発生し、Merge作業が発生します。

no-branch

Branchを作成すると、専用のコミットラインが複数作られます。 それぞれの開発者は専用のコミットラインにコミットをすることができますので、お互いのコミットの影響を受けることがありません

with-branch

しかし、Branchの更新は、最終的に本流に反映させなければなりません。 ここでMergeが発生します。

Branchを使わない場合は、コミット毎にConflictの可能性が発生しますが、Branchを運用することで本流へのMerge頻度を減らすことになり、MergeやConflictの頻度は低くなります

安全なMerge

では、安全なMerge、すなわちConflictが発生しないようにMergeするにはどうしたらば良いでしょうか? ケーススタディとしてみていきましょう。

Branch作成後、他のBranchがMergeする前にMergeする

最も安全なMergeは、Branchを作成した後、最初にMergeすることです。 Branchを作成した時点から本流に変更は加えられていない状態でMergeすれば、Confilctが起きる事は絶対にありません。

1st-Merge

更新対象のファイルが異なる

自分が作業したBranchで更新の対象となったファイルが、他のBranchで更新されていない場合も安全にMergeできます。

なぜならば、リポジトリ全体ではMergeというプロセスになりますが、個々のファイル単位で見た場合は競合がないからです。 他のBranchで更新されていないファイルであれば上書きされるだけで済むため、Conflictは起こらず、ツール(Git)に任せてしまえば綺麗にMergeできます。

split-files

Conflictが発生する条件

MergeにてConflictが発生する条件は、「Mergeする時、Branchで更新したファイルが別のBranchなどで更新されていて、本流が変更されている」ことになります。 言い換えれば次のような運用をしているとConflictが発生しやすくなります。

巨大なソースファイルが存在する

適切にクラスなどが分割されていないと巨大なソースファイルとなります。 ユーティリティクラスとして、UltraUtilsというクラスがあり、すべて個々に記述していたならば、あっという間に肥大化していくでしょう。 同時に更新を行っていることも増える筈です。 そうではなくて、StringUtils, ListUtils, FormatUtilsというように目的に合わせて適切にクラスが分割されていれば、同じクラスを同時に変更する確率は減ります。 また、手動Mergeする場合でも小さなクラスのMergeの方が巨大なクラスのMergeより簡単です。

Branchの作業期間が長い

Branchの粒度が1日〜数日で終わらないほど大きいと、それだけMergeされる範囲が大きくなります。 大きくなると言うことはConflictする可能性が高いということです。 仕様などが不明確なまま実装を進め、Mergeできないまま放置せざるを得ないなどは避けましょう。

チケットで作業を切っている場合は、1つのチケットの粒度を工夫します。 チケットが数時間から長くても1−2日で終わるように作り、大きなチケットは子チケットを作ってこまめにBranchを作ってMergeするようにしましょう。

まとめ

次のように開発を回せば、Mergeは怖くありません。

  • Branchを運用する
  • Branchはなるべく早く本流にMergeする
  • 適切にソースファイルを分割する
  • 共有ファイルを更新する場合は、リアルで声をかけるなどコミュニケーションを取る

適切な開発フローで行えばConflictはほとんど発生しないため、Mergeは全く怖くないですね。