git merge コマンドは、現在のブランチに別のブランチを統合(マージ)するためのコマンドです。
複数の開発ラインをまとめ、機能追加や修正を取り込むときに利用されます。
構文(Syntax)
git merge [オプション] <ブランチ名>
主なオプション一覧
| オプション | 説明 | 使用例 |
|---|---|---|
<ブランチ名> | 指定ブランチを現在のブランチにマージ | git merge feature-x |
--no-ff | Fast-forward を無効化し、必ずマージコミットを作成 | git merge --no-ff feature-x |
--ff-only | Fast-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コミットの整理・クリーンな履歴 |
マージコンフリクト解消の手順
コンフリクトは同じファイルの同じ行を複数のブランチで変更したときに発生します。以下の手順で解消します。
- マージを実行してコンフリクトを確認する
git merge feature-yを実行し、CONFLICTメッセージが表示されたコンフリクト発生を確認します。 - コンフリクトファイルを特定する
git statusを実行し、both modified:と表示されているファイルがコンフリクト対象です。 - コンフリクトマーカーを確認・編集する
該当ファイルを開くと以下のようなマーカーが挿入されています。
<<<<<<< HEADから=======が現在のブランチ、=======から>>>>>>>がマージ元ブランチの内容です。不要な部分を削除して最終形に編集します。 - 解決済みファイルをステージングする
git add <ファイル名>で解決済みのファイルをステージします。すべてのコンフリクトを解消するまで繰り返します。 - マージコミットを作成する
git commitを実行してマージコミットを完了します(メッセージは自動で入力されます)。 - 解決できない場合はマージを中止する
途中でやり直したい場合は
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 merge と git rebase はどちらもブランチの変更を統合するコマンドですが、履歴の扱い方が根本的に異なります。
| 観点 | git merge | git 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 pull は git 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 を使うことがチームでの基本ルール。
参考
- Git公式ドキュメント: https://git-scm.com/docs/git-merge

コメント