Gitのコンフリクト(conflict)を解消する手順についてまとめました【Git】

Linux

クライアントソフトでGitを使っていますが、コマンドでも操作できるようになりたいので一連の操作をメモしておきます。

マージする時、どうしても発生してしまうコンフリクト(競合)。
今回、コンフリクトの解消方法をまとめました。

マージするファイルの確認

まず、ブランチの状態ですが現在このようになっています。

$ git branch
* develop
  main

ポインタはdevelopブランチを指していることが確認できます。
編集するファイルはこちらです。

sample.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>テストページ</title>
</head>
<body>
    <section>
        <h1>タイトル</h1>
        <p>テキストテキストテキストテキストテキストテキスト</p>
        <button>ボタン</button>
    </section>
</body>
</html>

今回、<button>タグを変更してコンフリクトを発生させたいと思います。

ブランチをマージしてコンフリクトが発生するまでの手順

コンフリクトが発生するまでの流れは次のようになります。

  • developブランチに切り替える
  • feature/change-btnブランチを作成
  • sample.htmlを変更してコミットする(feature/change-btnブランチで変更)
  • developブランチに切り替える
  • sample.htmlを変更してコミットする(developブランチで変更)
  • ブランチの差分を確認
  • developブランチにfeature/change-btnブランチをマージする
  • コンフリクトが発生!

図にするとこんな感じです。

図の③でコンフリクトが発生

developブランチに切り替える

先ほど、既にdevelopブランチに切り替わってるのを確認しました。
次にfeature/change-btnブランチを作成します。
ブランチを新しく作成&切り替えるには、コマンドgit checkout -b <ブランチ名>を使います。

$ git checkout -b feature/change-btn
Switched to a new branch 'feature/change-btn'
$ git branch
  develop
* feature/change-btn
  main

この状態で、sample.htmlを次のように変更します。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>テストページ</title>
</head>
<body>
    <section>
        <h1>タイトル</h1>
        <p>テキストテキストテキストテキストテキストテキスト</p>
        <button class="feature-btn">ボタン</button> //クラス名追加
    </section>
</body>
</html>

<button>タグにクラス名「feature-btn」を追加しました。
この変更をコミットします。コミットの流れはざっくりですがこんなカンジです。

$ git status
On branch feature/change-btn
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   sample.html

no changes added to commit (use "git add" and/or "git commit -a")
$ git add sample.html
$ git commit -m "change btn feature"
[feature/change-btn 6bde8f5] change btn feature
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git status
On branch feature/change-btn
nothing to commit, working tree clean

developブランチに切り替えてマージする

今度は、developブランチに切り替えて、sample.htmlを変更してコミットします。
クラス名は先ほどと異なる「develop-btn」を設定しました。

sample.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>テストページ</title>
</head>
<body>
    <section>
        <h1>タイトル</h1>
        <p>テキストテキストテキストテキストテキストテキスト</p>
        <button class="develop-btn">ボタン</button> //クラス名追加
    </section>
</body>
</html>

先ほどと同じように変更をコミットします。

$ git status
On branch develop
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   sample.html

no changes added to commit (use "git add" and/or "git commit -a")
$ git add sample.html
$ git commit -m "change btn develop"
[develop beca128] change btn develop
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git status
On branch develop
nothing to commit, working tree clean

現在のGitの状態を整理

ここでちょっとGitの状態を整理します。

現在、developブランチ、feature/change-btnに同じ行の変更内容が異なるsample.htmlが存在することになります。

Gitのログでも確認します。コマンドはgit log –oneline –all –graphです。

コミットメッセージ「delete blank」から枝が2つに分かれています。

1つは現在ポインタが指しているdevelopブランチの「change btn develop」、もう一つはひとつ前にコミットしたfeature/change-btnブランチです。
これからこの2つのブランチをマージします。

ブランチの差分を確認

マージする前に差分を確認します。差分を確認するには、コマンドgit diff <ベースのブランチ> <比較したいブランチ>を使用します。

sample.htmlの<button>タグにクラス名develop-btnが追加されているのが確認できました。
問題なさそうなのでマージします!

マージしてコンフリクトを発生させる

マージするには次のコマンドを使います。

$ git merge <取り込みたいブランチ>

取り込むブランチはfeature/change-btnブランを指定します。
マージしたらこのような文章が出てきました。

英語だけ抜き出しました。ついでにGoogleで翻訳しました。

Auto-merging sample.html
CONFLICT (content): Merge conflict in sample.html
Automatic merge failed; fix conflicts and then commit the result.

(日本語訳)
sample.htmlの自動マージ
CONFLICT(コンテンツ):sample.htmlの競合をマージします。
自動マージに失敗しました。競合を修正してから、結果をコミットします。

平たく言うと、マージに失敗したからどっちの変更を反映するか修正してね。ってことのようです。

コンフリクトを解消する

同じ行で異なる記述があると、マージに失敗してコンフリクトが発生します。
Gitはどちらを反映してマージすれば良いか分からない為です。

まずステータスを確認してみます。これから何をやれば良いか英語で記載されています。Googleで翻訳します。

On branch develop
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: sample.html

no changes added to commit (use “git add” and/or “git commit -a”)

(日本語訳)

ブランチ開発で
マージされていないパスがあります。
(競合を修正し、「gitcommit」を実行します)
(「gitmerge –abort」を使用してマージを中止します)

マージされていないパス:
(「gitadd <file> …」を使用して解決をマークします)
両方とも変更:sample.html

コミットに変更が追加されていません(「gitadd」および/または「gitcommit-a」を使用)


競合している箇所を修正して、コミットしてね。って書いてあります。
sample.htmlを見てみると、ファイルに変な記号?が追加されています。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>テストページ</title>
</head>
<body>
    <section>
        <h1>タイトル</h1>
        <p>テキストテキストテキストテキストテキストテキスト</p>
<<<<<<< HEAD
        <button class="develop-btn">ボタン</button> //クラス名追加
=======
        <button class="feature-btn">ボタン</button>
>>>>>>> feature/change-btn
    </section>
</body>
</html>

この記号の意味は次の通りです。

<<<<<<< HEAD
# developブランチの変更内容(現在のブランチ)

=======
# feature/change-btnブランチの変更内容(取り込まれるブランチ)

>>>>>>> feature/change-btn

今回、feature/change-btnブランチの内容を反映したいので、次のように修正しました。

sample.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>テストページ</title>
</head>
<body>
    <section>
        <h1>タイトル</h1>
        <p>テキストテキストテキストテキストテキストテキスト</p>
        <button class="feature-btn">ボタン</button>
    </section>
</body>
</html>

あとはいつもと同じようにコミットします。
コミットメッセージは「resolve merge conflict」にしました。

$ git add .
$ git commit -m "resolve merge conflict"
[develop 5dec3a1] resolve merge conflict
$ git status
On branch develop
nothing to commit, working tree clean

問題なくコミットできました!

最後にログを確認する

最後にログを確認してみます。ログを確認するコマンドはgit log –oneline –all –graphです。

コミット「delete blank」から2つに分かれたブランチが、最終的に「resolve merge conflict」に統合(マージ)されているのが確認できました!