gitコマンドの使い方 ~ git merge ~
git merge コマンド概要
git merge コマンドはcheckout中のブランチに対して、指定したブランチの内容を取り込み新しいcommitを作成します。
以下は、masterブランチにdevelopブランチのcommit(B)とcommit(D)の変更内容を取り込んで新しいcommit(E)を作成するイメージです。
git merge コマンドの使い方
git merge [branch | remote-tracking-branch]
取り込み対象に指定するブランチは通常のbrachもしくはremote-trachking-branchを指定することができます。
branch-Aにbranch-Bの内容を取り込みたい場合は、branch-Aでgit mergeコマンドを実行する必要があります。
具体的なコマンド例で操作の流れを確認しましょう。
masterブランチにdevelopブランチの変更内容を取り込む
以下の内容を実際のgitコマンドで操作しました。
(master)
$ echo 'aaa' > file-A.txt
(master)
$ git add .
(master)
$ git commit -m 'commit-A'
[master (root-commit) e708da0] commit-A
1 file changed, 1 insertion(+)
create mode 100644 file-A.txt
(master)
$ git checkout -b develop
Switched to a new branch 'develop'
(develop)
$ echo 'bbb' > file-B.txt
(develop)
$ git add .
(develop)
$ git commit -m 'commit-B'
[develop 56ed527] commit-B
1 file changed, 1 insertion(+)
create mode 100644 file-B.txt
(develop)
$ echo 'ddd' > file-D.txt
(develop)
$ git add .
(develop)
$ git commit -m 'commit-D'
[develop 97fc8ae] commit-D
1 file changed, 1 insertion(+)
create mode 100644 file-D.txt
(develop)
$ git checkout master
Switched to branch 'master'
(master)
$ echo 'ccc' > file-C.txt
(master)
$ git add .
(master)
$ git commit -m 'commit-C'
[master f04350f] commit-C
1 file changed, 1 insertion(+)
create mode 100644 file-C.txt
(master)
$ git merge develop
Merge made by the 'recursive' strategy.
file-B.txt | 1 +
file-D.txt | 1 +
2 files changed, 2 insertions(+)
create mode 100644 file-B.txt
create mode 100644 file-D.txt
(master)
$ git log --oneline --all --graph
* 7acc226 (HEAD -> master) Merge branch 'develop'
|\
| * 97fc8ae (develop) commit-D
| * 56ed527 commit-B
* | f04350f commit-C
|/
* e708da0 commit-A
(master)
$ ll
total 4
-rw-r--r-- 1 snow 197609 4 4月 5 16:27 file-A.txt
-rw-r--r-- 1 snow 197609 5 4月 5 16:30 file-B.txt
-rw-r--r-- 1 snow 197609 4 4月 5 16:29 file-C.txt
-rw-r--r-- 1 snow 197609 5 4月 5 16:30 file-D.txt
(master)
$ git ls-files
file-A.txt
file-B.txt
file-C.txt
file-D.txt
conflict(コンクリフト)の解決方法
以下の内容を例に実際のgitコマンドで操作してみました。
masterブランチとdevelopブランチでfile-B.txtの同じ行を変更した場合
$ git chekcout master
(master)
$ echo 'bbb master upd' > file-B.txt
(master)
$ cat file-B.txt
bbb master upd
(master)
$ git commit -am 'conflict test master'
[master bd71826] conflict test master
1 file changed, 1 insertion(+), 1 deletion(-)
(master)
$ git checkout develop
Switched to branch 'develop'
(develop)
$ echo 'bbb develop upd' > file-B.txt
(develop)
$ cat file-B.txt
bbb develop upd
(develop)
$ git commit -am 'conflict test develop'
[develop d089509] conflict test develop
1 file changed, 1 insertion(+), 1 deletion(-)
(develop)
$ git checkout master
Switched to branch 'master'
(master)
$ git log --oneline --all
d089509 (develop) conflict test develop
bd71826 (HEAD -> master) conflict test master
(master)
$ git merge develop
Auto-merging file-B.txt
CONFLICT (content): Merge conflict in file-B.txt
Automatic merge failed; fix conflicts and then commit the result.
(master)
$ cat file-B.txt
<<<<<<< HEAD
bbb master upd
=======
bbb develop upd
>>>>>>> develop
// develop側を採用
// Visual Studio Codeなどで編集すると視覚的でわかりやすい
// 今回はdevelop側の修正を採用しファイルの状態を以下の内容にする
bbb develop upd
// コンクリフト解消したファイルをステージング
(master)
$ git add file-B.txt
// コンクリフト解消後のcommit作成
(master)
$ git commit -m 'no conflict'
ポイントを整理すると
git mergeコマンドでconflict(コンフリクト)が発生すると以下のようなメッセージが表示されます。
CONFLICT (content): Merge conflict in file-B.txt
Automatic merge failed; fix conflicts and then commit the result.
conflict(コンフリクト)が発生したファイルの内容は以下のようになっています。
上側がHEADつまり操作中のブランチなのでmasterの内容になります。
下側がdevelopブランチの内容になります。
何かのエディタ(VimでもVS Codeでも何でもOK)で修正します。
<<<<<<< HEAD
bbb master upd
=======
bbb develop upd
>>>>>>> develop
fast-forwardマージ
git mergeやgit push、git rebaseを実行する場合にfast-forwardマージについて覚えておくことでより理解が深まります。
fast-forwardマージとは、分岐元のブランチからconflict(コンフリクト)が発生する可能性のないマージで、マージ元のbranch(ブランチ)の HEAD をマージするブランチの最新のcommitに移動させるマージを指します。
図で示すと以下のような場合にgit mergeするとfast-forwardマージになります。
ポイントは、commit(B)の後にmasterブランチで変更がないことです。
masterとHEADの示すcommitの位置が変更しているだけになりますね。
実際にgitコマンドで確認するとこのようになります。
(master)
$ echo 'aaa' > file-A.txt
(master)
$ git add .
(master)
$ git commit -m 'commit-A'
[master (root-commit) 2959319] commit-A
1 file changed, 1 insertion(+)
create mode 100644 file-A.txt
(master)
$ echo 'bbb' > file-B.txt
(master)
$ git add .
(master)
$ git commit -m 'commit-B'
[master db4b456] commit-B
1 file changed, 1 insertion(+)
create mode 100644 file-B.txt
(master)
$ git checkout -b develop
Switched to a new branch 'develop'
(develop)
$ echo 'ccc' > file-C.txt
(develop)
$ git add .
(develop)
$ git commit -m 'commit-C'
[develop aa6cae4] commit-C
1 file changed, 1 insertion(+)
create mode 100644 file-C.txt
(develop)
$ echo 'ddd' > file-D.txt
(develop)
$ git add .
(develop)
$ git commit -m 'commit-D'
[develop 78b8fb7] commit-D
1 file changed, 1 insertion(+)
create mode 100644 file-D.txt
(develop)
$ git checkout master
Switched to branch 'master'
(master)
$ git log --oneline --all --graph
* 78b8fb7 (develop) commit-D
* aa6cae4 commit-C
* db4b456 (HEAD -> master) commit-B
* 2959319 commit-A
(master)
$ git merge develop
Updating db4b456..78b8fb7
Fast-forward
file-C.txt | 1 +
file-D.txt | 1 +
2 files changed, 2 insertions(+)
create mode 100644 file-C.txt
create mode 100644 file-D.txt
(master)
$ git log --oneline --all --graph
* 78b8fb7 (HEAD -> master, develop) commit-D
* aa6cae4 commit-C
* db4b456 commit-B
* 2959319 commit-A
git mergeコマンドの実行結果に「Fast-forward」と表示されていますね。
git merge の全てのオプションを確認する方法
以下のコマンドを実行するとブラウザでgit mergeのヘルプページが表示される
git merge --help