「git mergeって何をしているの?」
「マージしたらコンフリクトが発生した…」
「Fast-forwardって何?」
そんな疑問はありませんか?
Gitでのチーム開発に欠かせないのが、マージです。
この記事では、Gitマージの完全ガイドをお届けします。
- マージとは何か
- マージの種類と違い
- 基本的な使い方
- コンフリクト(衝突)の解決方法
- マージとリベースの違い
- ベストプラクティス
- トラブルシューティング
初心者の方でも分かるよう、丁寧に解説します。
マージをマスターして、スムーズなチーム開発を実現しましょう!
Gitマージとは?
まず、マージの基本概念を理解しましょう。
マージの定義
マージ(merge)とは、複数のブランチの変更を1つに統合することです。
「merge」は英語で「合併する」「統合する」という意味です。
通常の開発フロー
- mainブランチから新しいブランチを作成
- 新しいブランチで機能を開発
- 開発が完了したらmainブランチにマージ
これが基本的な流れです。
マージが必要な理由
複数人での並行開発
チーム開発では、複数の人が同時に異なる機能を開発します。
例:
- Aさん:ログイン機能を開発
- Bさん:検索機能を開発
- Cさん:決済機能を開発
それぞれ別のブランチで作業して、完成したらmainブランチにマージします。
機能ごとに開発を分離
1つの大きな機能も、小さな単位に分けて開発します。
- ブランチ1:データベース設計
- ブランチ2:API実装
- ブランチ3:画面実装
完成した順にmainブランチにマージしていきます。
マージの仕組み
Gitのマージは賢い仕組みを持っています。
3つのコミットを比較
Gitは以下の3つを比較します:
- 共通祖先(マージベース):2つのブランチが分岐した地点
- マージ元ブランチ:取り込みたいブランチの最新コミット
- マージ先ブランチ:取り込む側のブランチの最新コミット
自動統合
重複しない変更は、自動的に統合されます。
例:
- マージ元:file1.txtを変更
- マージ先:file2.txtを変更
→ 両方の変更が自動的に統合される
コンフリクト発生
同じファイルの同じ場所を変更していると、コンフリクト(衝突)が発生します。
この場合、手動で解決する必要があります。
マージの種類
Gitには主に2種類のマージ方法があります。
Fast-forward マージ(早送りマージ)
特徴
最もシンプルなマージ方法です。
ブランチポインタを前に進めるだけです。
発生条件
マージ先ブランチに新しいコミットがない場合に発生します。
図解
初期状態:
main: A---B
feature: C---D
マージ後:
main: A---B---C---D
feature: D
mainブランチのポインタが、単純にDまで移動しただけです。
特徴
- マージコミットは作成されない
- 履歴が一直線になる
- シンプルで分かりやすい
メリット
- 履歴がきれい
- コンフリクトが発生しない
デメリット
- マージした履歴が残らない
- どこでマージしたか分かりにくい
3-wayマージ(三方向マージ)
特徴
ブランチが分岐している場合に行われるマージです。
新しい「マージコミット」が作成されます。
発生条件
マージ先ブランチに新しいコミットがある場合に発生します。
図解
初期状態:
main: A---B---C
\
feature: D---E
マージ後:
main: A---B---C-------F(マージコミット)
\ /
feature: D---E---
FはCとEの両方の変更を含む新しいコミットです。
特徴
- マージコミットが作成される
- 履歴が分岐・統合する
- マージの記録が残る
メリット
- マージの履歴が明確
- どのブランチをマージしたか分かる
- 並行開発の流れが見える
デメリット
- 履歴が複雑になる
- コンフリクトが発生する可能性がある
No-fast-forward マージ
特徴
Fast-forwardが可能な状況でも、強制的にマージコミットを作成します。
コマンド
git merge --no-ff ブランチ名
使用シーン
マージの記録を明確に残したい場合に使います。
例:
- 機能ブランチのマージ履歴を残したい
- コードレビュー後のマージを記録したい
マージの基本的な使い方
実際にマージを行う手順を解説します。
事前準備
手順1:現在のブランチを確認
git branch
現在いるブランチに*マークが付きます。
手順2:マージ先ブランチに移動
git checkout main
または
git switch main
重要:マージは「現在いるブランチ」に「指定したブランチ」を取り込みます。
手順3:最新の状態に更新
git pull origin main
リモートの最新の変更を取り込みます。
手順4:作業ディレクトリをきれいにする
git status
未コミットの変更がないことを確認します。
変更がある場合:
- コミットする
- または
git stashで一時退避
マージの実行
基本コマンド
git merge ブランチ名
例:featureブランチをmainブランチにマージ
# mainブランチに移動
git checkout main
# featureブランチをマージ
git merge feature
成功した場合の出力例
Merge made by the 'recursive' strategy.
file1.txt | 10 ++++++++--
file2.txt | 5 +++++
2 files changed, 13 insertions(+), 2 deletions(-)
マージコミットメッセージの編集
マージ時、コミットメッセージの編集画面が開くことがあります。
デフォルトメッセージ
Merge branch 'feature' into main
カスタムメッセージを指定
git merge feature -m "機能Xを追加"
マージ後の確認
履歴を確認
git log --oneline --graph
マージの履歴がグラフで表示されます。
変更内容を確認
git diff HEAD~1 HEAD
マージで加わった変更を確認できます。
リモートへのプッシュ
マージが完了したら、リモートにプッシュします。
git push origin main
これで、他のメンバーもマージ後の状態を取得できます。
コンフリクト(衝突)の解決方法
マージ時に最も困るのがコンフリクトです。
コンフリクトとは
定義
同じファイルの同じ場所を、両方のブランチで変更している状態です。
Gitが自動的に統合できず、手動での解決が必要です。
発生例
mainブランチ:
行10: こんにちは
featureブランチ:
行10: Hello
両方が同じ行を変更しているため、コンフリクトが発生します。
コンフリクトの発生
マージ実行時
git merge feature
コンフリクト発生時の出力
Auto-merging file1.txt
CONFLICT (content): Merge conflict in file1.txt
Automatic merge failed; fix conflicts and then commit the result.
「file1.txtでコンフリクトが発生しました」という意味です。
コンフリクトの確認
ステータスを確認
git status
出力例
On branch main
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: file1.txt
「both modified」と表示されたファイルがコンフリクトしています。
コンフリクトマーカー
コンフリクトしたファイルを開くと、特殊なマーカーが挿入されています。
コンフリクトマーカーの構造
<<<<<<< HEAD
こんにちは(現在のブランチの内容)
=======
Hello(マージしようとしたブランチの内容)
>>>>>>> feature
各部分の意味
<<<<<<< HEAD:現在のブランチ(マージ先)の変更開始=======:境界線>>>>>>> feature:マージ元ブランチの変更終了
コンフリクトの解決手順
手順1:ファイルを開く
テキストエディタでコンフリクトしたファイルを開きます。
手順2:コンフリクト箇所を編集
マーカーを削除して、残したい内容に編集します。
選択肢
- 現在のブランチを採用
こんにちは
- マージ元ブランチを採用
Hello
- 両方を採用
こんにちは
Hello
- 全く新しい内容
こんにちは / Hello
必ずマーカーを削除
<<<<<<<、=======、>>>>>>>は必ず削除してください。
手順3:ファイルを保存
編集が完了したら、ファイルを保存します。
手順4:ステージに追加
git add file1.txt
これで「コンフリクトを解決した」とGitに伝えます。
手順5:マージコミットを作成
git commit
または、すべてのコンフリクトを解決した後:
git commit -m "コンフリクトを解決してfeatureをマージ"
手順6:確認
git log --oneline --graph
マージコミットが作成されたことを確認します。
コンフリクト解決の中止
マージを取り消す
コンフリクト解決が難しい場合、マージを中止できます。
git merge --abort
マージ前の状態に戻ります。
便利なツール
VS Code
VS Codeでは、コンフリクトを視覚的に解決できます。
- 「Accept Current Change」:現在のブランチを採用
- 「Accept Incoming Change」:マージ元を採用
- 「Accept Both Changes」:両方を採用
- 「Compare Changes」:差分を比較
Git GUIツール
- GitKraken:視覚的なマージツール
- SourceTree:コンフリクト解決が簡単
- SmartGit:3-wayマージエディタ
git mergetool
git mergetool
設定したマージツールが起動します。
マージとリベースの違い
Gitには、ブランチを統合する方法が2つあります。
マージ(merge)
特徴
履歴をそのまま残しながら統合します。
マージコミットが作成されます。
履歴
A---B---C---F(マージコミット)
\ /
D---E
分岐と統合の履歴が明確に残ります。
メリット
- 実際の開発の流れが分かる
- マージの記録が残る
- 安全(履歴を書き換えない)
デメリット
- 履歴が複雑になる
- マージコミットが増える
リベース(rebase)
特徴
履歴を一直線に書き換えます。
分岐がなかったかのように見えます。
履歴
A---B---C---D'---E'
D’とE’は、Dと
Eと同じ内容ですが、Cの後に移動しています。
メリット
- 履歴がきれい
- 一直線で分かりやすい
デメリット
- 履歴を書き換える(危険)
- 既にプッシュしたコミットには使えない
使い分け
マージを使う場面
- メインブランチへの統合
- チーム開発
- 既にプッシュしたブランチ
- マージの記録を残したい
リベースを使う場面
- ローカルの整理
- 自分だけが使っているブランチ
- 履歴をきれいにしたい
- プッシュ前のコミット整理
原則
「他の人が使っているブランチはリベースしない」
これを守れば安全です。
プルリクエストとマージ
GitHub/GitLabなどでの開発フローを解説します。
プルリクエスト(Pull Request)とは
定義
「このブランチをマージしてください」というリクエストです。
GitHubでは「Pull Request(PR)」、GitLabでは「Merge Request(MR)」と呼ばれます。
目的
- コードレビュー
- 議論の場
- マージの承認プロセス
プルリクエストの流れ
手順1:ブランチを作成
git checkout -b feature/new-function
手順2:開発してコミット
git add .
git commit -m "新機能を追加"
手順3:リモートにプッシュ
git push origin feature/new-function
手順4:プルリクエストを作成
GitHub/GitLabの画面で「Create Pull Request」をクリックします。
手順5:レビュー
チームメンバーがコードをレビューします。
手順6:マージ
承認されたら、「Merge」ボタンでマージします。
GitHubでのマージ方法
GitHubでは、3種類のマージ方法を選べます。
1. Create a merge commit(マージコミット)
通常の3-wayマージです。
マージコミットが作成されます。
2. Squash and merge(スカッシュ)
すべてのコミットを1つにまとめてマージします。
履歴がきれいになります。
3. Rebase and merge(リベース)
リベースしてからマージします。
一直線の履歴になります。
どれを選ぶ?
チームのルールに従ってください。
一般的には:
- 大きな機能:Create a merge commit
- 小さな修正:Squash and merge
マージのベストプラクティス
効率的で安全なマージのコツを紹介します。
1. こまめにマージする
理由
長期間ブランチを分けたままにすると、コンフリクトが増えます。
推奨
- 毎日または数日おきにmainから変更を取り込む
- 機能が完成したらすぐにマージ
2. マージ前にテストする
チェックリスト
- [ ] ユニットテストが通る
- [ ] ビルドが成功する
- [ ] 動作確認が完了している
- [ ] コードレビューが完了している
3. 意味のあるコミットメッセージ
良い例
git merge feature -m "ユーザー認証機能を追加"
悪い例
git merge feature -m "マージ"
何をマージしたか分かるメッセージにしましょう。
4. Fast-forwardの制御
–no-ff オプション
git merge --no-ff feature
Fast-forwardが可能でも、マージコミットを作成します。
使用シーン
- 機能ブランチのマージ記録を残したい
- どこでマージしたか明確にしたい
5. マージ前に最新の状態にする
# マージ先ブランチで
git pull origin main
# マージ元ブランチで
git pull origin feature
両方を最新にしてからマージします。
6. 小さな単位でマージ
推奨
- 1つの機能ごとにマージ
- 数日分の作業ごとにマージ
避ける
- 1ヶ月分の変更を一度にマージ
- 複数の機能をまとめてマージ
7. コンフリクトの予防
方法
- 同じファイルを複数人で編集しない
- 役割分担を明確にする
- こまめに情報共有する
8. マージ後は削除
不要になったブランチは削除します。
# ローカルブランチ削除
git branch -d feature
# リモートブランチ削除
git push origin --delete feature
よくあるトラブルと解決方法
マージ時のトラブル対処法を紹介します。
トラブル1:マージができない
エラーメッセージ
error: Your local changes to the following files would be overwritten by merge:
file1.txt
Please commit your changes or stash them before you merge.
原因
未コミットの変更があります。
解決方法
方法1:コミットする
git add .
git commit -m "作業中の変更をコミット"
git merge feature
方法2:一時退避する
git stash
git merge feature
git stash pop
トラブル2:間違ったブランチにマージした
対処法
マージコミット前なら
git merge --abort
マージコミット後なら
git reset --hard HEAD~1
注意:--hardは変更を完全に削除します。
トラブル3:コンフリクトが多すぎる
原因
- 長期間ブランチを分けていた
- 大量の変更を一度にマージしようとした
対処法
方法1:マージを中止
git merge --abort
方法2:段階的にマージ
mainから定期的に変更を取り込んでいれば、コンフリクトが減ります。
# featureブランチで
git merge main
トラブル4:マージ後にバグが発生
対処法
方法1:マージを取り消す
git revert -m 1 HEAD
マージコミットを打ち消すコミットが作成されます。
方法2:特定のコミットに戻る
git reset --hard <コミットID>
トラブル5:リモートとローカルが同期しない
エラーメッセージ
! [rejected] main -> main (non-fast-forward)
原因
リモートに新しいコミットがあります。
解決方法
git pull origin main
git push origin main
トラブル6:コンフリクトマーカーが残ったままコミット
症状
ファイルに<<<<<<<が残ったままです。
対処法
方法1:修正し直す
# ファイルを編集してマーカー削除
git add file1.txt
git commit --amend
方法2:最新のコミットをやり直す
git reset --soft HEAD~1
# ファイルを修正
git add file1.txt
git commit -m "コンフリクトを解決"
よくある質問(FAQ)
マージについて、よくある質問に答えます。
Q1. マージとリベースはどちらを使うべきですか?
基本的にはマージを使いましょう。
リベースは履歴を書き換えるため、慎重に使う必要があります。
マージ:チーム開発、メインブランチへの統合
リベース:ローカルでの整理、自分だけのブランチ
Q2. Fast-forwardとNo-fast-forwardはどちらがいいですか?
機能ブランチのマージにはNo-fast-forward(--no-ff)がおすすめです。
マージの記録が残るためです。
git merge --no-ff feature
Q3. コンフリクトを避ける方法はありますか?
完全には避けられませんが、以下で減らせます:
- こまめにmainから変更を取り込む
- 同じファイルを複数人で編集しない
- 機能を小さく分割する
- コミュニケーションを取る
Q4. マージコミットは削除できますか?
git resetやgit revertで取り消せますが、慎重に行ってください。
特に、既にプッシュしたコミットは削除しない方が安全です。
Q5. マージ中に作業を中断できますか?
はい、できます。
git merge --abort
これでマージ前の状態に戻ります。
Q6. 複数のブランチを一度にマージできますか?
可能ですが、推奨しません。
1つずつマージする方が、コンフリクト解決が簡単です。
Q7. マージ後にブランチは自動削除されますか?
いいえ、自動削除されません。
手動で削除する必要があります。
git branch -d feature
Q8. GitHubのマージボタンとコマンドラインの違いは?
基本的に同じですが、GitHubでは:
- コードレビューの記録が残る
- プルリクエストの履歴が残る
- ブラウザで完結する
まとめ:マージをマスターしよう
Gitマージについて、詳しく解説しました。
この記事のポイント
マージとは
- 複数のブランチを1つに統合すること
- チーム開発に不可欠
- 自動統合とコンフリクト解決
マージの種類
- Fast-forward:ポインタを前に進めるだけ
- 3-wayマージ:マージコミットを作成
- No-fast-forward:強制的にマージコミット作成
基本的な使い方
git checkout main
git merge feature
コンフリクト解決
- コンフリクト箇所を確認
- マーカーを削除して編集
git addでステージgit commitでコミット
マージとリベースの違い
- マージ:履歴を残す(安全)
- リベース:履歴を書き換える(注意)
ベストプラクティス
- こまめにマージ
- マージ前にテスト
- 意味のあるコミットメッセージ
- 小さな単位でマージ
トラブル対処
- 未コミットの変更→コミットまたはstash
- 間違ったマージ→
git merge --abort - マージ後のバグ→
git revert
Gitマージは、チーム開発の基本中の基本です。
マージをマスターするコツ
- 実際に手を動かして練習する
- 小さなプロジェクトで試す
- チームのルールを確認する
- ツールを活用する
この記事を参考に、Gitマージを使いこなして、スムーズなチーム開発を実現してください!
最終チェックリスト
- [ ] マージの概念を理解した
- [ ] Fast-forwardと3-wayマージの違いが分かる
- [ ] 基本的なマージコマンドを覚えた
- [ ] コンフリクトの解決方法を理解した
- [ ] マージとリベースの違いを知った
- [ ] ベストプラクティスを学んだ
これで、Gitマージをマスターできました!
自信を持ってチーム開発に参加してください。

コメント