Gitマージコンフリクトの理解と解決

Diff出力でGitマージコンフリクトマーカーを読み解き解決する方法を学びます。三方向Diff、コンフリクト解決戦略、Diffツールを使用した安全なコンフリクト解決方法を理解します。

Real-World Scenarios

詳細な説明

マージコンフリクトのDiff

マージコンフリクトは、Gitが2つのブランチからの変更を自動的に調整できない場合に発生します。コンフリクトマーカーを理解し、Diffツールを効果的に使用することは、安全なコンフリクト解決に不可欠です。

コンフリクトマーカーの構造

<<<<<<< HEAD
const API_URL = "https://api.staging.example.com";
=======
const API_URL = "https://api.production.example.com";
>>>>>>> feature/deploy-config
  • <<<<<<< HEAD — 現在のブランチのバージョンの開始
  • ======= — 2つのバージョン間のセパレータ
  • >>>>>>> feature/... — 受信ブランチ名を示す終了

三方向Diff

三方向Diffは3つのバージョンを表示します:

  1. Base — 共通の祖先(どちらのブランチも変更する前)
  2. Ours — 現在のブランチ(HEAD)
  3. Theirs — 受信ブランチ
BASE:   const API_URL = "https://api.example.com";
OURS:   const API_URL = "https://api.staging.example.com";
THEIRS: const API_URL = "https://api.production.example.com";

Baseバージョンを見ることで、各変更の意図を理解できます。

コンフリクト解決戦略

戦略 使用場面
Oursを採用 自分のブランチの変更が正しい
Theirsを採用 受信ブランチの変更が正しい
両方を採用 両方の変更が必要(異なるセクション)
手動マージ 両方のバージョンのロジックを組み合わせる必要がある

一般的なコンフリクトパターン

同じ行を両方が変更:

<<<<<<< HEAD
  timeout: 30,
=======
  timeout: 60,
>>>>>>> feature/performance

解決:どのタイムアウト値が正しいかを判断するか、もう一方の開発者と相談。

隣接する行の変更:

<<<<<<< HEAD
  host: "localhost",
  port: 3000,
=======
  host: "0.0.0.0",
  port: 8080,
>>>>>>> feature/docker

解決:一方のブランチのhostともう一方のportが必要かもしれません。

一方が削除、もう一方が変更:

<<<<<<< HEAD
function legacyHandler() {
  // 更新された実装
}
=======
>>>>>>> feature/cleanup

解決:関数を保持(更新あり)するか削除するかを判断。

ベストプラクティス

  1. 頻繁にpull — 小さなDiffはコンフリクトが少ない
  2. 三方向マージツールを使用 — VS Code、IntelliJ、またはgit mergetool
  3. 解決後にテストを実行 — 何も壊れていないことを確認
  4. 最終Diffをレビュー — コミット前にgit diff --staged
  5. コミュニケーション — 相手の変更が不明な場合はもう一方の開発者と話す

ユースケース

すべての開発者がマージコンフリクトに遭遇します。コンフリクトDiffの理解は、チームコラボレーション中のコード整合性の維持に不可欠です。関連するコードに複数の開発者が作業する変化の速いプロジェクト、リリースブランチのマージ時、更新されたメインブランチへの長期存続するフィーチャーブランチのリベース時に特に重要です。

試してみる — Diff Viewer

フルツールを開く