Help us understand the problem. What is going on with this article?

Gitでコンフリクトを発生させて、解消してみた。

More than 1 year has passed since last update.

環境

・Git version 2.20.1.windows.1

お題

今回はGitで発生しうるコンフリクト(競合)がどんなものか体験する。
まずは作業前にコンフリクトについてお勉強。

目次

1.競合って?
2.Gitにおけるコンフリクト(競合)とは?
3.ファイルの新規作成
4.リポジトリの初期化
5.TEST.txtを作成してcommitする。
6.トピックブランチAとBを作成する
7.トピックブランチAのTEST.txtを修正してコミットする。
8.トピックブランチBのTEST.txtを修正してコミットする。
9.コンフリクトを発生させて、解消する。

1.競合って?

そもそも競合ってなんだ。
と思ったわけではないが一応検索した。
結果、「互いにせりあうこと。」らしい。('ω')

2.Gitにおけるコンフリクト(競合)とは?

Gitにおける競合をコンフリクトと呼ぶらしい。

例えばmasterブランチにTEST.txtなるファイルを保持していたとする。

そのmasterブランチから、同じタイミングでトピックブランチAとBに派生させたときに
それぞれトピックブランチAではTEST.txtを

test1
test2

とする。

さて、トピックブランチBは

test3
test4

といった修正を加えたとする。

それぞれをmasterブランチにA、Bの順番でマージしようとする。
すると、Bをマージした時点で、コンフリクトが発生する。

同じ時点で別れたブランチで、別々の内容を持つTEST.txtファイルが
存在することになるので、正常にマージできず衝突してしまうようだ。

実際にmasterブランチでトピックブランチAとBをマージしようとすると、masterブランチのTEST.txtに競合を示す記述が記載される。
修正するには、作業者が内容に合わせてファイルを修正して、ステージ、コミットすれば良いことになる。

今回は一連の動作を実践してみることにした。

3.ファイルの新規作成

$ mkdir git-conflict
$ cd git-conflict/


4.リポジトリの初期化

$ git init
Initialized empty Git repository in C:/Users/local-pc/documents/work/git-conflict/.git/

5.TEST.txtを作成してcommitする。

$ touch TEST.txt

$ ls
TEST.txt

$ git add TEST.txt

$ git commit -m "first commit"
[master (root-commit) 8c1f140] first commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 TEST.txt

$ git status
On branch master
nothing to commit, working tree clean

6.トピックブランチAとBを作成する

$ git branch topicA

$ git branch topicB

$ git branch
* master
  topicA
  topicB

7.トピックブランチAのTEST.txtを修正してコミットする。

$ git checkout topicA
Switched to branch 'topicA'

(自分用に備忘:vimのペーストはInsertモードにしてからCTL + Insert、保存して終了はwq。)

$ git add TEST.txt
warning: LF will be replaced by CRLF in TEST.txt.
The file will have its original line endings in your working directory

$ git commit -m "topicA"
[topicA d35d541] topicA
 1 file changed, 2 insertions(+)

8.トピックブランチBのTEST.txtを修正してコミットする。

5と全く同じなので省略。
masterブランチをチェックアウトしておく。

$ git checkout master
Switched to branch 'master'

9.コンフリクトを発生させて、解消する。

まずはトピックブランチAをマージしてみる。

$ git merge --no-ff topicA
hint: Waiting for your editor to close the file...
[main 2019-02-18T13:20:51.237Z] update#setState idle
Merge made by the 'recursive' strategy.
 TEST.txt | 2 ++
 1 file changed, 2 insertions(+)

catでTEXT.txtの中身を除くと…

$ cat TEST.txt
test1
test2

うんうん。ちゃんと入ってる。

では今回の本題。
トピックブランチBをマージしてみる。

$ git merge --no-ff topicB
Auto-merging TEST.txt
CONFLICT (content): Merge conflict in TEST.txt
Automatic merge failed; fix conflicts and then commit the result.

無事(?)コンフリクト発生。

中身をのぞいてみる。

$ cat TEST.txt
<<<<<<< HEAD
test1
test2
=======
test3
test4
>>>>>>> topicB

こんな感じにGitが気を利かせて書き換えをしてくれている。
=======よりも上の行が現在のTEST.txtの内容で、つまりトピックブランチAの内容をマージした状態。
=======よりも下がトピックブランチBの内容を表している。
たぶん、このままaddしてcommitもできるんだろうけど、きちんと修正しとく。
修正した内容をcatする。

$ cat TEST.txt
test1
test2
test3
test4

これをadd、commitできれば、masterブランチで発生したコンフリクトを解消できたことになる。

$ git add TEST.txt
$ git commit -m "conflict clear!"
[master 653eba8] conflict clear!

ログをグラフでみるとこんな感じ。
うん。わかりにくい(´・ω・`)

$ git log --graph
*   commit 653eba813bfd6d0181463f769b6872c4bfbd6edf (HEAD -> master)
|\  Merge: 0d5193d 41afa16
| | Author: 僕の名前 <僕アドレス>
| | Date:   Mon Feb 18 22:28:32 2019 +0900
| |
| |     conflict clear!
| |
| * commit 41afa1692ddd5e251b816e2e2420f4f51bc80921 (topicB)
| | Author: 僕の名前 <僕アドレス>
| | Date:   Mon Feb 18 22:19:13 2019 +0900
| |
| |     topicB
| |
* |   commit 0d5193df3dfea53967673fe13477ffc541ce7645
|\ \  Merge: 8c1f140 d35d541
| |/  Author: 僕の名前 <僕アドレス>
|/|   Date:   Mon Feb 18 22:20:50 2019 +0900
| |
| |       Merge branch 'topicA'
| |
| * commit d35d541744457ed7b7f0f4df173b67db936e26f3 (topicA)
|/  Author: 僕の名前 <僕アドレス>
|   Date:   Mon Feb 18 22:17:03 2019 +0900
|
|       topicA
|
* commit 8c1f140cd4a3622ee1066f83b0900741eca35263
  Author: 僕の名前 <僕アドレス>
  Date:   Mon Feb 18 22:09:43 2019 +0900

      first commit
(END)

無事コンフリクトを解消できました。
慣れてしまえば以外と簡単ね。

今日はここまで!
明日はここで作ったファイルをGitHubのリモートリポジトリにpushしてみます。

こっからはJunitのお勉強だ(:3 」∠)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away