Close

Git のマージ戦略のオプションとサンプル

作業とテストが完了し、開発のメインラインにマージする準備ができたら、チームで検討すべきことがあります。それは、チームにおけるマージ戦略をどうするかということです。この記事では、さまざまなマージ戦略を探りながら、アトラシアンではどのような戦略を採っているかを紹介します。この記事を読み終わるころには、チームに最適な戦略を見つけることができているでしょう。


Git でのマージの進め方


マージとは、2 つのブランチを結合することです。Git では 2 つ以上のコミットポインターを取って、ポインター間で共通するベースコミットを見つけようとします。Git にはベースコミットを見つけるためのさまざまな手法があり、これらの手法は「マージ戦略」と呼ばれます。共通するベースコミットが見つかったら、指定したマージコミットの変更を結合する新しい「マージコミット」が作成されます。技術的な観点から見ると、マージコミットは単に 2 つの親コミットを持つ通常のマージということになります。

merge gif

明示的に指定しない限り、git merge は自動でマージ戦略を選択します。git merge コマンドと git pull コマンドには -s (strategy の「s」) オプションを渡せます。-s オプションでは使用するマージ戦略の名前を追加できます。明示的に指定しなかった場合は、Git は指定したブランチに最適なマージ戦略を自動的に選択します。使用可能なマージ戦略の一覧は以下のとおりです。

コンソール・ウィンドウ
関連資料

高度な Git ログ

Bitbucket ロゴ
ソリューションを見る

Bitbucket Cloud での Git の使用方法についてのチュートリアルです。

Recursive

git merge -s recursive branch1 branch2

このマージ戦略では 2 つの HEAD に対応します。Recursive はデフォルトのマージ戦略で、1 つのブランチのプルまたはマージを実行します。また、名前変更に関するマージの検出と操作ができますが、現時点では検出したコピーを活用する方法はありません。こちらが 1 つのブランチのプルまたはマージを実行する際のデフォルトのマージ戦略になります。

解決

git merge -s resolve branch1 branch2

この戦略では三方向マージアルゴリズムを使った、2 つの HEAD の解決のみを実行できます。十字マージの曖昧さを慎重に検出する戦略で、一般的には安全かつ高速だとみなされています。

Octopus

git merge -s octopus branch1 branch2 branch3 branchN

3 つ以上の HEAD に対応する際のデフォルトのマージ戦略です。複数のブランチが渡されると、自動的に Octopus がマージ戦略として選択されます。手動による解決が必要なマージの競合がある場合、マージは却下されます。基本的には類似するフィーチャーブランチ HEAD を結合するときに使用します。

Ours

git merge -s ours branch1 branch2 branchN

Ours 戦略は、複数の任意の数のブランチに対応しています。この戦略のマージ結果は現在のブランチの HEAD のものになります。「Ours」という単語は、他のすべてのブランチにおけるすべての変更を実質的に無視することを意味しています。類似するフィーチャー ブランチの履歴を結合する際に使用します。

Subtree

git merge -s subtree branchA branchB

Subtree は Recursive 戦略の拡張版です。A と B をマージしようとしていて、B が A の子サブツリーである場合、まず B が更新されて A のツリー構造が反映されます。この更新は A と B で共有されている共通の祖先ツリーにも行われます。

Git マージ戦略のタイプ


明示的なマージ

明示的なマージはデフォルトのマージタイプです。この場合の「明示的」とは、新しいマージコミットが作成されることを意味します。これによってコミット履歴が変更され、マージが実行された箇所が明示的に示されます。マージコミットのコンテンツも明示的で、どのコミットがマージコミットの親かが表示されます。マージコミットではほぼ間違いなくプロジェクト履歴に「ノイズ」が追加されるため、明示的なマージを使わないチームもあります。

リベースマージまたは早送りマージでトリガーされる暗黙のマージ

コミットをまとめてマージする (通常は明示的なマージで使用しない)

Git マージの Recursive 戦略で使えるオプション


さきほど紹介した「Recursive」戦略には他にも独自の操作オプションのサブセットがあります。

ours

このオプションを Ours マージ戦略と混同しないようにしてください。このオプションでは「Ours」の結果を利用することで競合を自動的かつスムーズに解決します。競合がない場合、「Theirs」側の変更は自動的に組み込まれます。

theirs

「Ours」戦略とは反対に、「Theirs」オプションでは競合の解決時に外部のマージ対象ツリーを対象にします。

patience

このオプションではじっくりと時間をかけて、条件に一致する重要ではない行のマージエラーを回避します。マージ対象のブランチの分岐が激しいときにこのオプションを使います。

diff-algorithim
ignore-*

    ignore-space-change
    ignore-all-space
    ignore-space-at-eol
    ignore-cr-at-eol

これらは空白文字を対象とするオプションです。渡されたオプションのサブセットに一致するすべての行が無視されます。

renormalize

このオプションではすべての git ツリーでチェックアウトとチェックインが実行されるとともに、三方向マージを解決します。このオプションは、異なるチェックイン/チェックアウト状態のマージ対象ブランチで使用します。

no-normalize

このコマンドを実行すると標準化オプションが無効になり、merge.renormalize の構成変数が上書きされます。

no-renames

このオプションを指定すると、名前を変更したファイルをマージ中に無視します。

find-renames=n

これはデフォルトの動作です。Recursive マージではファイルの名前変更が尊重されます。n パラメーターを使って名前変更の類似性のしきい値を渡せます。デフォルトの n 値は 100% です。

subtree

このオプションは Subtree 戦略から流用したものです。マージ戦略を 2 つのツリーで実行し、同じ祖先に一致させる方法を修正する場合、このオプションではツリーのパスメタデータを操作して祖先に一致させます。

アトラシアンの Git マージポリシー


アトラシアンでは明示的なマージの使用が強く推奨されています。理由はいたってシンプルです。明示的なマージは、マージ対象のフィーチャーのトレーサビリティとコンテンツが非常にわかりやすくなっています。レビュー用にフィーチャーブランチを共有する前にローカル履歴のクリーンアップリベースを行うことを強く推奨しますが、これによってポリシーが変更されるようなことは一切なく、単純にポリシーが強化されます。


この記事を共有する

おすすめコンテンツ

次のリソースをブックマークして、DevOps チームのタイプに関する詳細や、アトラシアンの DevOps についての継続的な更新をご覧ください。

一面のツールを使ってコラボレーションしている人たち

Bitbucket ブログ

DevOps のイラスト

DevOps ラーニング パス

Demo Den アトラシアン・エキスパートによる機能デモ

Bitbucket Cloud が、Atlassian Open DevOps とどのように連携するか

DevOps ニュースレター購読

Thank you for signing up