Gitにおけるコンフリクト解消手法を以下の2パターンについて、手順、比較したときの利点・欠点をまとめます。
- マージコミットでコンフリクトを解消する(一般的・標準的な手順)
- マージとコンフリクト解消のコミットを分離する
通常は1の手順を利用します。
2の手順はコンフリクト解消が複雑なときに利用することがあります。
1. マージコミットでコンフリクトを解消する(一般的・標準的な手順)
この手法はGitが推奨する一般的な流れであり、コンフリクト解消作業を単一のマージコミット内に含めます。
手順
-
マージの実行とコンフリクトの発生:
$ git checkout main $ git merge feature/branch # CONFLICT (content): Merge conflict in <ファイル名> -
コンフリクトの手動解消:
- 競合が発生したファイルを開き、
<<<<<<<、=======、>>>>>>>などのコンフリクトマーカーを削除しながら、適切なコードを手動で選択・統合します。
- 競合が発生したファイルを開き、
-
解消後のステージング:
$ git add <解消したファイル名> -
マージコミットの作成:
- すべてのコンフリクトを解消し、ステージングした後、コミットを実行します。Gitが自動生成したコミットメッセージ(Merge branch '...')をそのまま使用するか、必要に応じて編集します。
$ git commit # マージコミットが完了し、コンフリクト解消の内容もこのコミットに含まれる
メリット
それぞれ2の手法と比較してのメリット・デメリットです。
| 項目 | 詳細 |
|---|---|
| シンプルさ | 標準的な手順であり、特別なコマンドオプションが不要なため、最もシンプルで直感的です。 |
| 履歴の簡潔さ | コンフリクトの解消を含むマージ作業全体が単一のコミットとして表現されるため、履歴が簡潔に保たれます。 |
デメリット
| 項目 | 詳細 |
|---|---|
| 解消内容の追跡の困難さ | コンフリクト解消のための手動での変更がマージコミットの差分に埋もれるため、後から 「純粋なマージの結果」と「手動解消の変更」を切り分けて確認するのが困難 です。 |
| バグ調査の難しさ | マージコミットでバグが導入された場合、その原因が元のブランチの変更によるものか、手動でのコンフリクト解消によるものかを切り分ける作業が複雑になりやすいです。 |
2. マージとコンフリクト解消のコミットを分離する
この手法は、コンフリクトの解消作業を独立したコミットとして残すことで、履歴の可視性を高めます。
手順
-
マージを一時停止し、自動マージの結果をコミット:
- マージを実行し、コミットを一時的に停止させます。
$ git checkout main # `--no-ff` : 必ずマージコミットを作成するオプション # `--no-commit`: マージ結果を自動的にコミットせずに停止するオプション $ git merge feature/branch [--no-ff] [--no-commit]-
git addで自動マージの結果(コンフリクトマーカーが残った状態を含む)をステージングし、マージコミットを作成します。
$ git add <コンフリクトが含まれているファイル> / git add . $ git commit -
コンフリクトの手動解消:
- 競合ファイルを開き、手動でコンフリクトを解消します。
-
コンフリクト解消コミットの作成:
- 解消したファイルをステージングし、コンフリクト解消専用のコミットを作成します。
$ git add <解消したファイル名> $ git commit -m "Fix A機能についてのコンフリクト解消"- これでマージ作業が完了し、履歴上は2つのコミットが作成されます。
メリット
| 項目 | 詳細 |
|---|---|
| 解消内容の明確化 | コンフリクト解消のための手動の変更が独立したコミットとして明確に記録されます。 |
| バグ調査の容易さ | マージコミットの後にできたコンフリクト解消コミットにバグの原因がある場合、そのコミットをピンポイントで特定しやすいです。 |
| レビューの効率化 | プルリクエストのレビューにおいて、純粋なマージの差分と手動解消の差分を切り分けて確認できるため、レビューが効率的になります。 |
デメリット
| 項目 | 詳細 |
|---|---|
| コミット履歴の冗長化 | 1つのマージ作業に対して最低2つのコミット(マージコミット、解消コミット)が作成されるため、履歴の行数が増え、冗長になる傾向があります。 |
| 誤った操作のリスク |
git commitの前に競合マーカーのついたファイルをgit addする必要があるなど、操作ミスをすると履歴が乱れるリスクがあります。 |
まとめ
バージョン間などのでかいコンフリクトを解消するときは、1回のマージで複数の機能コンフリクトすることがあります。このとき機能ごとにコンフリクト解消することがとても重要になります。
リポジトリのコンフリクト解消の複雑さやチームの開発スタイルに合わせて、1,2を使い分けることでスムーズな開発を心がけます。
参考