【Git入門】git mergeの使い方!コマンドでブランチをマージする

git Git

gitコマンドを使用してブランチをマージする方法について書いています。
gitのmergeについて解説した後に、実際にコマンドを使用してみています。
Gitのバージョン2.32.0で確認しています。

gitのブランチについては、こちらに記載しましたので、ブランチがわからない場合にはご確認ください。
ブランチを作成して、並行開発したソースコードをgit mergeコマンドを使用することで、任意のブランチにマージすることが可能です。

gitのmerge(マージ)とは?

gitのmergeは、現在使用しているブランチに特定のブランチを取り込むためのコマンドです。
例えば、下記のようにtestブランチを作成して、「D, E」と開発を進めているとします。
Gitのマージ解説図1

開発が終わって、テストをした後にmergeコマンドを使うことで、下記のようにマージすることができます。
Gitのマージ解説図2

これでtestブランチで開発した機能のソースコードが、mainブランチにマージされて、mainブランチでも使用できるようになります。
このようにgit mergeを使用することで、ブランチを作成して、並行して作成したソースコードを他のブランチにまとめることができます。

git mergeコマンドの使い方

実際にmergeコマンドを使用して確認してみます。

下記のようにmainブランチからtestブランチを作成して、コミットを2つ行ってみました。(GUIツールのSorceTreeで表示しています。)
git merge確認のため、testブランチにコミットを2つ行う

最新のコミットはtestブランチになっていて、2つ前のコミットがmainブランチになっています。
testブランチの開発が終わったということにして、mainブランチにgit mergeコマンドを使用してブランチをマージします。

まず、checkoutコマンドでmainブランチを選択した状態にします。

$ git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.

git branchコマンドを使用すると、選択されたことが確認できます。
アスタリスク(*)がついているのが現在のブランチです。

$ git branch
* main
  test

ブランチの選択が終わったら、現在のブランチ(mainブランチ)にmergeコマンドでtestブランチをマージします。
下記のようにgit mergeの後に、現在のブランチにマージしたいブランチを指定します。

$ git merge test

実行すると、下記のようにマージされて、変更されたファイルの内容が表示されます。

$ git merge test
Updating 8b08b59..5aa25e1
Fast-forward
 test2.js | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

SorceTreeで確認すると、マージされたので、下記のようにmainブランチとtestブランチが同じ位置にいることが確認できます。
git mergeの確認、mainブランチにtestブランチをマージする

マージが完了しました。
mainブランチを選択したまま、ソースコードを確認すると、testブランチで追加・修正した内容が入ってきていることが確認できます。
修正の場所が重複していない場合は、基本的にはgitがいい感じにマージしてくれます。

gitでmergeした内容を戻したい

git mergeでマージした後に、やっぱり元に戻したい場合の対処方法です。
git resetコマンドを使用すると、mergeする前の状態に戻すことが可能です。

まず、戻したい位置のコミット番号を確認します。
git logコマンドを使用すると、下記のように履歴が表示されます。

$ git log
commit 5aa25e123024931acc7f83e0cca5828b7a9d5bb9 (HEAD -> main, test)
Author: yasuaki0206 <testhoge+01@example.com>
Date:   Tue May 3 17:34:58 2022 +0900

    add test2 fuga

commit f03fc92e72c0369275b95845d40128ae6b4fdca9
Author: yasuaki0206 <testhoge+01@example.com>
Date:   Tue May 3 17:33:54 2022 +0900

    add test2 message

commit 8b08b5998da508341eb9c1567e4289eb9f987262 (origin/main, origin/HEAD)
Author: yasuaki0206 <testhoge+01@example.com>
Date:   Sat Apr 30 17:52:16 2022 +0900

    add new file

commit aac7a53fe36606826d88146e0488c92db968aace
Merge: 69049e8 a0e5dd5
Author: yasuaki0206 <testhoge+01@example.com>
Date:   Sat Apr 23 22:54:59 2022 +0900

    merge

最新のコミットが一番上で、先ほどマージした状態になっています。
マージする前の状態がリモートプッシュする前のorigin/mainの位置になります。

commitの後に書いてある、ランダムな英数字の羅列がコミット番号です。コピーしておきます。
その後に、git resetコマンドに下記のように戻したい履歴のコミット番号を渡します。

$ git reset 8b08b5998da508341eb9c1567e4289eb9f987262

実際に実行すると、下記のようにリセットされたファイルが表示されます。

$ git reset 8b08b5998da508341eb9c1567e4289eb9f987262
Unstaged changes after reset:
M       test2.js

git logで確認すると、マージ前に戻ったことが確認できました。

$ git log
commit 8b08b5998da508341eb9c1567e4289eb9f987262 (HEAD -> main, origin/main, origin/HEAD)
Author: yasuaki0206 <testhoge+01@example.com>
Date:   Sat Apr 30 17:52:16 2022 +0900

    add new file

commit aac7a53fe36606826d88146e0488c92db968aace
Merge: 69049e8 a0e5dd5
Author: yasuaki0206 <testhoge+01@example.com>
Date:   Sat Apr 23 22:54:59 2022 +0900

    merge

commit 69049e816bc6f8fcb95e78af276965e68deb62d5
Author: yasuaki0206 <testhoge+01@example.com>
Date:   Sat Apr 23 22:52:15 2022 +0900

    add main.js

mergeした時にconflict(コンフリクト)が発生したら?

git mergeをした時に修正内容が衝突(コンフリクト)した場合の対処方法です。
同じファイルを修正すると、gitが自動的にマージすることができずにコンフリクトして、マージに失敗する場合があります。
コンフリクトした場合には、対象のファイルを手動で修正して、コミットするようにします。

コンフリクトする場合の例

例えば、mainブランチのtest2.jsというファイルを、このように修正しています。

console.log("test console2")

let test = "message123"
for(let i = 0; i < 5; i++) {
  console.log(test)
}

同じファイルをtestブランチでは、下記のように修正していました。

console.log("test console2")

for (let i = 0; i < 5; i++) {
  console.log(`hoge ${i}`)
}

修正した行が同じですが、内容が違います。
この時にmainブランチを選択して、mergeコマンドを実行すると、このようにコンフリクトします。

$ git checkout main
Switched to branch 'main'

$ git merge test
Auto-merging test2.js
CONFLICT (content): Merge conflict in test2.js
Automatic merge failed; fix conflicts and then commit the result.

マージした瞬間にコンフリクトが発生して、コンフリクトしたファイルが表示されます。
今回はtest2.jsがコンフリクトしたことがわかります。

コンフリクトを解消する

コンフリクトしたファイルをエディタで開きます。
そうすると、下記のようになっています。

console.log("test console2")

<<<<<<< HEAD
let test = "message123"
for(let i = 0; i < 5; i++) {
  console.log(test)
=======
for (let i = 0; i < 5; i++) {
  console.log(`hoge ${i}`)
>>>>>>> test
}

gitがマージに失敗しましたが、対応が必要な箇所に目印を追加してくれています。

<<<<<<< HEAD」から「=======」が現在使用しているブランチです。
=======」から「>>>>>>> test」がgit mergeでマージしようとしたブランチになります。

今回は対象のファイルを、下記のように修正しました。
どっちのコードも残すようにしました。

console.log("test console2")

let test = "message123"
for(let i = 0; i < 5; i++) {
  console.log(test)
}

for (let i = 0; i < 5; i++) {
  console.log(`hoge ${i}`)
}

修正が完了したら、git addコマンドで再度ステージに載せます。

$ git add test2.js

その後に、git commitコマンドでコミットすると良いです。

$ git commit -m "merge branch test"  
[main d8dcc0c] merge branch test

SourceTreeで確認すると、下記のようにmainブランチから作成したtestブランチが、mainブランチにマージされたことが確認できました。

GitでマージできたのをSourceTreeで確認

SourceTreeやVSCodeを使用している場合は、コンフリクトしたら既にコミットコメントが入力されているので、手動でマージした後にコミットすると良いです。

コメント

タイトルとURLをコピーしました