git merge – ブランチを統合するコマンド

コマンドリファレンス

git merge コマンドは、現在のブランチに別のブランチを統合(マージ)するためのコマンドです。
複数の開発ラインをまとめ、機能追加や修正を取り込むときに利用されます。

構文(Syntax)

git merge [オプション] <ブランチ名>

主なオプション一覧

オプション説明使用例
<ブランチ名>指定ブランチを現在のブランチにマージgit merge feature-x
--no-ffFast-forward を無効化し、必ずマージコミットを作成git merge --no-ff feature-x
--ff-onlyFast-forward 可能な場合のみマージを実行git merge --ff-only feature-x
--squash変更をまとめて 1 コミットにする(コミットは別途必要)git merge --squash feature-x
--abortコンフリクトが発生した場合にマージを中止git merge --abort
-m "メッセージ"マージコミットにメッセージを指定git merge -m "Merge feature-x"

fast-forward / non-fast-forward / squash merge の使い分け

マージ方式は 3 種類あり、目的に応じて使い分けることが重要です。

fast-forward マージ(デフォルト)

マージ元ブランチが、マージ先ブランチの直接の延長にある場合、ポインタを前進させるだけで統合します。新たなマージコミットは作成されません。

  • 向いている場面: 短命な個人ブランチ、ホットフィックスなど履歴をシンプルに保ちたいとき
  • コマンド例: git merge feature-x(デフォルト、FF 可能であれば自動選択)
  • 注意点: 履歴が一直線になり、どのブランチでの変更かが分かりにくくなる
# fast-forward マージの例
git checkout main
git merge feature-x
# 出力: Fast-forward

non-fast-forward マージ(–no-ff)

FF 可能な場合でも強制的にマージコミットを作成します。ブランチの存在が履歴に明示的に残るため、チーム開発で標準的に使われます。

  • 向いている場面: フィーチャーブランチを main/develop にマージするとき、レビュー済みの変更をまとめて取り込むとき
  • コマンド例: git merge --no-ff feature-x
  • メリット: git log --graph でブランチの統合ポイントが一目で分かる
# non-fast-forward マージの例
git checkout main
git merge --no-ff feature-x -m "Merge branch 'feature-x'"
# 出力: Merge made by the 'recursive' strategy.

squash マージ(–squash)

フィーチャーブランチの複数コミットを 1 つにまとめて main に統合します。ブランチ自体は自動でマージされず、git commit が別途必要です。

  • 向いている場面: WIP コミットや実験的なコミットを整理してから取り込みたいとき、履歴を綺麗に保ちたいとき
  • コマンド例: git merge --squash feature-x && git commit -m "Add feature-x"
  • 注意点: マージコミットは作成されないため、フィーチャーブランチとの親子関係が git 上に残らない
# squash マージの例
git checkout main
git merge --squash feature-login
git commit -m "Add login feature"

3 つのマージ方式比較

方式マージコミット履歴の見やすさ主な用途
fast-forward作成しない一直線(シンプル)個人ブランチ、ホットフィックス
non-fast-forward(–no-ff)必ず作成分岐が明示されるフィーチャーブランチのマージ
squash(–squash)作成しない(手動 commit)1 コミットに集約WIPコミットの整理・クリーンな履歴

マージコンフリクト解消の手順

コンフリクトは同じファイルの同じ行を複数のブランチで変更したときに発生します。以下の手順で解消します。

  1. マージを実行してコンフリクトを確認する git merge feature-y を実行し、CONFLICT メッセージが表示されたコンフリクト発生を確認します。
  2. コンフリクトファイルを特定する git status を実行し、both modified: と表示されているファイルがコンフリクト対象です。
  3. コンフリクトマーカーを確認・編集する 該当ファイルを開くと以下のようなマーカーが挿入されています。<<<<<<< HEAD から ======= が現在のブランチ、======= から >>>>>>> がマージ元ブランチの内容です。不要な部分を削除して最終形に編集します。
  4. 解決済みファイルをステージングする git add <ファイル名> で解決済みのファイルをステージします。すべてのコンフリクトを解消するまで繰り返します。
  5. マージコミットを作成する git commit を実行してマージコミットを完了します(メッセージは自動で入力されます)。
  6. 解決できない場合はマージを中止する 途中でやり直したい場合は git merge --abort でマージ前の状態に戻せます。
# コンフリクト解消の流れ
git merge feature-y
# CONFLICT (content): Merge conflict in app.py

git status
# both modified: app.py

# エディタで app.py を編集してコンフリクトマーカーを解消

git add app.py
git commit
# [main abc1234] Merge branch 'feature-y'

コンフリクトマーカーの形式:

<<<<<<< HEAD
現在のブランチの内容
=======
マージ元ブランチの内容
>>>>>>> feature-y

実行例

基本的なマージ

git checkout main
git merge feature-x

出力例:

Updating abc123..def456
Fast-forward
 file1.txt | 2 ++
 1 file changed, 2 insertions(+)

マージコミットを必ず作成

git merge --no-ff feature-x

出力例:

Merge made by the 'recursive' strategy.
 file2.txt | 5 +++++

Fast-forward のみ許可

git merge --ff-only hotfix

Squash マージ(1コミットにまとめる)

git merge --squash feature-login
git commit -m "Squash merge feature-login"

コンフリクトが発生した場合

git merge feature-y

出力例:

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

解決後:

git add app.py
git commit

マージを中止

git merge --abort

エラー例(存在しないブランチを指定)

git merge notfound

出力例:

fatal: not something we can merge in: notfound

git merge と git rebase の違い

git mergegit rebase はどちらもブランチの変更を統合するコマンドですが、履歴の扱い方が根本的に異なります。

観点git mergegit rebase
履歴の形分岐と統合が残る(非破壊的)一直線に書き換わる(破壊的)
マージコミット作成される(–no-ff 時)作成されない
コンフリクト解消1 回(マージ時)コミットごとに発生する可能性がある
共有ブランチへの使用安全(推奨)危険(push 済みブランチへは非推奨)
向いている場面チーム共有ブランチへの統合フィーチャーブランチを最新 main に追従させるとき

使い分けの基準

  • git merge を選ぶとき: main や develop など共有ブランチへの取り込み、統合の記録を履歴に残したいとき
  • git rebase を選ぶとき: 自分のフィーチャーブランチを最新の main に追従させたいとき、履歴を一直線にしてレビューしやすくしたいとき
  • rebase を避けるべき状況: すでに push してチームと共有しているブランチには絶対に使わない(他の人の履歴が壊れる)
# merge: 統合履歴が残る
git checkout main
git merge --no-ff feature-x

# rebase: フィーチャーブランチを main の先頭に付け替える
git checkout feature-x
git rebase main

よくある質問(FAQ)

Q. git merge と git pull の違いは?

A. git pullgit fetch + git merge を自動で行うコマンドです。リモートの変更を取得してローカルブランチに統合します。一方 git merge は手動でブランチを指定して統合します。

Q. マージコンフリクトを防ぐ方法はありますか?

A. 完全に防ぐことはできませんが、以下の方法でコンフリクトの頻度を減らせます。

  • フィーチャーブランチの作業期間を短くする(長期ブランチほどコンフリクトが増える)
  • 定期的に git merge main または git rebase main でフィーチャーブランチを最新状態に追従させる
  • チームでファイルの担当範囲を明確にして同一ファイルの同時編集を減らす

Q. –no-ff はいつも使うべきですか?

A. チーム開発では --no-ff を推奨するプロジェクトが多いです。ブランチの統合ポイントが明確になり、git log --graph で変更の流れを追いやすくなります。個人の作業用ブランチや短命なホットフィックスでは不要な場合もあります。

Q. squash merge 後にフィーチャーブランチを削除しても問題ない?

A. 問題ありません。squash merge では Git 上にフィーチャーブランチとの親子関係が残らないため、ブランチは作業が完了したら削除して構いません。ただし git branch -d が「マージ済みでない」と警告する場合は git branch -D で強制削除します。

Q. コンフリクト解消中に元の状態に戻すには?

A. git merge --abort を実行するとマージ前の状態に戻ります。ファイルの編集途中でも安全に中断できます。

Q. “Already up to date.” と表示される場合は?

A. 現在のブランチがすでにマージ元ブランチのすべての変更を含んでいる状態です。マージは不要で、変更は何も行われません。

関連コマンド

  • git rebase : マージの代わりに履歴を付け替えて統合する。
  • git checkout / git switch : マージ先ブランチに切り替える。
  • git log --graph : ブランチの統合履歴を確認する。
  • git status : コンフリクト発生中のファイル状態を確認する。
  • git diff : マージ前後の差分を確認する。

備考

  • Fast-forward マージでは新しいコミットは作成されず、ブランチの先頭が進むだけ。
  • --no-ff を指定すると履歴が分かりやすくなるが、コミット数は増える。
  • コンフリクト解決はマージ作業で最も重要な手順の一つ。
  • push 済みの共有ブランチへの rebase は禁止し、merge を使うことがチームでの基本ルール。

参考

Bash玄

はじめまして!Bash玄です。

エンジニアとしてシステム運用に携わる中で、手作業の多さに限界を感じ、Bashスクリプトを活用して業務を効率化したのがきっかけで、この道に入りました。「手作業は負け」「スクリプトはシンプルに」をモットーに、誰でも実践できるBashスクリプトの書き方を発信しています。

このサイトでは、Bashの基礎から実践的なスクリプト作成まで、初心者でもわかりやすく解説しています。少しでも「Bashって便利だな」と思ってもらえたら嬉しいです!

# 好きなこと
- シンプルなコードを書くこと
- コマンドラインを快適にカスタマイズすること
- 自動化で時間を生み出すこと

# このサイトを読んでほしい人
- Bashに興味があるけど、何から始めればいいかわからない人
- 定型業務を自動化したい人
- 効率よくターミナルを使いこなしたい人

Bashの世界に一歩踏み出して、一緒に「Bash道」を極めていきましょう!

Bash玄をフォローする

コメント