Git マージ完全ガイド|基本からコンフリクト解決まで

「git mergeって何をしているの?」

「マージしたらコンフリクトが発生した…」

「Fast-forwardって何?」

そんな疑問はありませんか?

Gitでのチーム開発に欠かせないのが、マージです。

この記事では、Gitマージの完全ガイドをお届けします。

  • マージとは何か
  • マージの種類と違い
  • 基本的な使い方
  • コンフリクト(衝突)の解決方法
  • マージとリベースの違い
  • ベストプラクティス
  • トラブルシューティング

初心者の方でも分かるよう、丁寧に解説します。

マージをマスターして、スムーズなチーム開発を実現しましょう!

スポンサーリンク
  1. Gitマージとは?
    1. マージの定義
    2. マージが必要な理由
    3. マージの仕組み
  2. マージの種類
    1. Fast-forward マージ(早送りマージ)
    2. 3-wayマージ(三方向マージ)
    3. No-fast-forward マージ
  3. マージの基本的な使い方
    1. 事前準備
    2. マージの実行
    3. マージコミットメッセージの編集
    4. マージ後の確認
    5. リモートへのプッシュ
  4. コンフリクト(衝突)の解決方法
    1. コンフリクトとは
    2. コンフリクトの発生
    3. コンフリクトの確認
    4. コンフリクトマーカー
    5. コンフリクトの解決手順
    6. コンフリクト解決の中止
    7. 便利なツール
  5. マージとリベースの違い
    1. マージ(merge)
    2. リベース(rebase)
    3. 使い分け
  6. プルリクエストとマージ
    1. プルリクエスト(Pull Request)とは
    2. プルリクエストの流れ
    3. GitHubでのマージ方法
  7. マージのベストプラクティス
    1. 1. こまめにマージする
    2. 2. マージ前にテストする
    3. 3. 意味のあるコミットメッセージ
    4. 4. Fast-forwardの制御
    5. 5. マージ前に最新の状態にする
    6. 6. 小さな単位でマージ
    7. 7. コンフリクトの予防
    8. 8. マージ後は削除
  8. よくあるトラブルと解決方法
    1. トラブル1:マージができない
    2. トラブル2:間違ったブランチにマージした
    3. トラブル3:コンフリクトが多すぎる
    4. トラブル4:マージ後にバグが発生
    5. トラブル5:リモートとローカルが同期しない
    6. トラブル6:コンフリクトマーカーが残ったままコミット
  9. よくある質問(FAQ)
    1. Q1. マージとリベースはどちらを使うべきですか?
    2. Q2. Fast-forwardとNo-fast-forwardはどちらがいいですか?
    3. Q3. コンフリクトを避ける方法はありますか?
    4. Q4. マージコミットは削除できますか?
    5. Q5. マージ中に作業を中断できますか?
    6. Q6. 複数のブランチを一度にマージできますか?
    7. Q7. マージ後にブランチは自動削除されますか?
    8. Q8. GitHubのマージボタンとコマンドラインの違いは?
  10. まとめ:マージをマスターしよう

Gitマージとは?

まず、マージの基本概念を理解しましょう。

マージの定義

マージ(merge)とは、複数のブランチの変更を1つに統合することです。

「merge」は英語で「合併する」「統合する」という意味です。

通常の開発フロー

  1. mainブランチから新しいブランチを作成
  2. 新しいブランチで機能を開発
  3. 開発が完了したらmainブランチにマージ

これが基本的な流れです。

マージが必要な理由

複数人での並行開発

チーム開発では、複数の人が同時に異なる機能を開発します。

例:

  • Aさん:ログイン機能を開発
  • Bさん:検索機能を開発
  • Cさん:決済機能を開発

それぞれ別のブランチで作業して、完成したらmainブランチにマージします。

機能ごとに開発を分離

1つの大きな機能も、小さな単位に分けて開発します。

  • ブランチ1:データベース設計
  • ブランチ2:API実装
  • ブランチ3:画面実装

完成した順にmainブランチにマージしていきます。

マージの仕組み

Gitのマージは賢い仕組みを持っています。

3つのコミットを比較

Gitは以下の3つを比較します:

  1. 共通祖先(マージベース):2つのブランチが分岐した地点
  2. マージ元ブランチ:取り込みたいブランチの最新コミット
  3. マージ先ブランチ:取り込む側のブランチの最新コミット

自動統合

重複しない変更は、自動的に統合されます。

例:

  • マージ元: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:コンフリクト箇所を編集

マーカーを削除して、残したい内容に編集します。

選択肢

  1. 現在のブランチを採用
こんにちは
  1. マージ元ブランチを採用
Hello
  1. 両方を採用
こんにちは
Hello
  1. 全く新しい内容
こんにちは / 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 resetgit 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

コンフリクト解決

  1. コンフリクト箇所を確認
  2. マーカーを削除して編集
  3. git addでステージ
  4. git commitでコミット

マージとリベースの違い

  • マージ:履歴を残す(安全)
  • リベース:履歴を書き換える(注意)

ベストプラクティス

  • こまめにマージ
  • マージ前にテスト
  • 意味のあるコミットメッセージ
  • 小さな単位でマージ

トラブル対処

  • 未コミットの変更→コミットまたはstash
  • 間違ったマージ→git merge --abort
  • マージ後のバグ→git revert

Gitマージは、チーム開発の基本中の基本です。

マージをマスターするコツ

  • 実際に手を動かして練習する
  • 小さなプロジェクトで試す
  • チームのルールを確認する
  • ツールを活用する

この記事を参考に、Gitマージを使いこなして、スムーズなチーム開発を実現してください!

最終チェックリスト

  • [ ] マージの概念を理解した
  • [ ] Fast-forwardと3-wayマージの違いが分かる
  • [ ] 基本的なマージコマンドを覚えた
  • [ ] コンフリクトの解決方法を理解した
  • [ ] マージとリベースの違いを知った
  • [ ] ベストプラクティスを学んだ

これで、Gitマージをマスターできました!

自信を持ってチーム開発に参加してください。

コメント

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