Gitマージコンフリクト(競合)の解決方法をわかりやすく解説
Gitは通常、ブランチ間の差分を自動的に検出してマージしてくれます。これは、開発者がそれぞれ異なる行やファイルに変更を加えていることが多いためです。しかし、Gitが自動的にマージできないケースも存在します。このような状況は「マージコンフリクト(競合)」と呼ばれます。
この記事では、マージとは何か、マージコンフリクトとは何か、そしてGitのマージコンフリクトを実際に解決する方法について詳しく解説します。それでは始めましょう!
マージコンフリクトとは?
マージコンフリクトとは、開発者の助けなしにはGitが2つのブランチをマージできない状態のことです。
マージは、Gitのようなバージョン管理システムにおける基盤となる重要な機能です。マージにより、開発者はリポジトリ内で複数の独立した開発ラインを維持できます。つまり、プロジェクトのメインコピーを変更することなく、別のブランチでバグ修正などの作業を進めることが可能になります。
マージコンフリクトが発生するのは、主に以下の2つのシナリオです。
- 2つのブランチで同じ行のコードが変更された場合
- 片方のブランチで削除されたファイルが、もう片方のブランチで変更されていた場合
マージコンフリクトが発生すると、Gitはエラーを表示します。これは、ブランチの自動マージに失敗したことを伝えるものです。
「削除されたファイル」のコンフリクトを解決する方法
Gitのブランチは互いに独立しています。そのため、開発者があるブランチ上でファイルを削除しても、その変更は他のブランチには影響しません。
しかし、片方のブランチであるファイルに変更を加え、もう片方のブランチでそのファイルが削除されていると、マージコンフリクトが発生する可能性があります。これは、Gitがそのファイルを「削除すべき」のか「変更すべき」のか判断できないためです。
例として、devとmasterという2つのブランチがあるとします。devブランチではREADME.mdファイルを削除し、masterブランチでは新しいテキストを追加しました。
これらのブランチはgit mergeコマンドでマージできます。
git merge dev
これにより、「dev」ブランチが現在のブランチ(master)にマージされます。しかし、実行結果にはマージコンフリクトが表示されました。
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.
このコンフリクトを解決するには、まず判断を下す必要があります。「ファイルを保持する」のか、それとも「削除する」のか。ファイルを保持したい場合は、git addコマンドを使ってリポジトリに再度追加します。
git add README.md
逆に、削除したい場合はgit rmコマンドを使ってリポジトリから削除します。
git rm README.md
rmコマンドはローカルリポジトリからファイルを削除します。実行する前に、本当にそのファイルを削除してよいか必ず確認してください。
コンフリクトしたファイルの扱いを決めたら、変更をコミットしてブランチをマージできます。
git add README.md
git commit -m "feat: Add README.md to repository"
git merge dev
git addコマンドは変更をステージングし、git commitコマンドは新しいコミットを作成します。そしてgit mergeコマンドがdevブランチとmasterブランチをマージします。マージコンフリクトが解決されたため、ブランチを正常にマージできるようになりました。
「ファイル変更」のコンフリクトを解決する方法
開発者が異なる2つのブランチで同じファイルに変更を加えることもあります。2つのブランチをマージする際、どちらの変更を保持すべきかをGitが判別することはできません。
この場合、マージコンフリクトが発生します。masterとdevという2つのブランチを持つリポジトリがあり、両方のブランチでREADME.mdファイルに変更を加えたとしましょう。これにより、マージコンフリクトが発生しました。
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.
まず最初に行うべきは、マージコンフリクトの根本原因を特定することです。これはgit statusコマンドで確認できます。
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: README.md
このメッセージから、README.mdファイルが両方のブランチで変更されたことがわかります。次に、マージコンフリクトを解決していきましょう。テキストエディタでREADME.mdファイルを開いてみます。
This is a README.md file.
This is in a repository called merge-conflicts.
<<<<<<< HEAD
This file is on the main branch.
=======
This file is on the dev branch.
>>>>>>> dev
Gitは、マージコンフリクトが存在することを知らせるためにファイルへコンフリクトマーカーを追加しています。Gitは小なり・大なり・等号の記号を使ってマージコンフリクトを表現します。
小なり記号(<)は現在のブランチへの変更を表し、大なり記号(>)は現在のブランチにマージしようとしたブランチ側の変更を示します。等号(=)は2つの差分を区切る役割を果たします。
この場合、以下のようになっています。
- 「This file is on the main branch.」はmasterブランチ(HEAD)側の内容
- 「This file is on the dev branch.」はdevブランチ側の内容
このマージコンフリクトを解決するには、不要なテキストとコンフリクトマーカーを削除するだけです。例えば、最終的に「This file is on a branch.」という内容にしたい場合は、次のように修正します。
This is a README.md file.
This is in a repository called merge-conflicts.
This file is on a branch.
修正が完了したら、最終的なマージを行う準備が整いました。変更をステージングし、リポジトリにコミットして、devブランチとmasterブランチをマージしましょう。
git add .
git commit -m "feat: Resolve merge conflict."
git merge dev
これでマージコンフリクトが解決され、コードは正常にマージされます。
まとめ
マージコンフリクトは、2つのブランチで同じ行のテキストに変更を加えた場合や、片方のブランチでファイルを変更し、もう片方のブランチでそのファイルを削除した場合に発生します。
この記事では、両方のケースにおけるマージコンフリクトの解決方法を具体的なコマンド例とともに解説しました。これであなたも、Gitのエキスパートのようにマージコンフリクトに自信を持って取り組めるようになったはずです。
-
Gitエラー「You need to resolve your current index first」の原因と解決方法
Gitで発生する「You need to resolve your current index first(まず現在のインデックスを解決する必要があります)」というエラーは、マージコンフリクト(競合)が存在していることを意味します。この競合を解決しない限り、別のブランチへチェックアウトすることはできません。また、このエラーメッセージは、マージが失敗したか、ファイルに競合が残っていることを示しています。そもそも、これらの「ファイル」「マージ」「競合」とは何なのでしょうか?Gitを使い始めたばかりの方には馴染みのない用語かもしれません。Gitとはバージョン管理プラットフォームの一種で、複数人の開発
-
Gitマージエラー「現在のインデックスを先に解決する必要があります」の直し方
Gitには「ブランチ」という概念が組み込まれています。通常はmasterブランチを起点として、そこから複数のブランチが枝分かれする構成になります。ブランチ間を切り替える際や、ブランチ内のファイルに競合(コンフリクト)が発生した場合、「Git error: you need to resolve your current index first」(まず現在のインデックスを解決する必要があります)というエラーメッセージが表示されることがあります。このエラーが解決されるまで、Git内でブランチを切り替えることはできません。 本記事では、このGitマージエラーの原因と具体的な解決方法をわかりやすく解説