本文へスキップ
スキルアップカレッジ

ブランチとマージ——分岐と合流の発想

レッスン3:ブランチマージ——分岐と合流の発想

このレッスンで学ぶこと

  • ブランチの概念を「並行する作業ライン」として理解する
  • ブランチの作成・切り替えのコマンドを使える
  • マージ(merge)で並行作業を統合する発想を持つ
  • マージコンフリクトの意味と解消方法を整理する
  • main ブランチ/作業ブランチの基本ルールを把握する
  • 「fast-forward」「3-way merge」の違いを概念として理解する

前のレッスンでは、Git の準備と 3 ステージモデル、初めての commit を扱いました。今回のレッスンでは、ブランチとマージを扱います。ブランチは Git の最大の魅力の 1 つで、「並行する作業」を安全に進める道具です。チーム開発の手前であっても、個人の作業でも、ブランチの発想は強力です。

ブランチとは何か——並行する作業ライン

ブランチの基本イメージ

ブランチ(branch)は、文字通り「枝」の意味です。Git では「作業の流れの枝」を表します。

main:    ●─●─●─●─●─●
                  \
feature:           ●─●─●

main という主要な枝(メインライン)から、feature という枝(作業ブランチ)が分岐し、独立して作業を進めることができます。それぞれの枝で commit を重ね、後でまとめて main に合流(マージ)させることもできます。

なぜブランチが必要か

ブランチがあると、

  • 新機能の開発を、現在動いているコードと分離できる
  • 試験的な変更を、本番のコードに影響を与えずに試せる
  • 複数人が同時に違う作業を進められる
  • 「うまくいかなかったら枝ごと捨てる」ができる

ことができます。これは、現代の開発手法の基盤になっています。

main ブランチ

Git のリポジトリには、最初から「main」というブランチが存在します(古いリポジトリでは master という名前のこともあります)。多くのプロジェクトで、main ブランチは「動く状態」を保つ約束ごとがあります。

💡 ポイント ブランチは「作業の流れの枝」と覚えると、概念がつかみやすくなります。Git では、ブランチが極めて軽量で、何個でも作って消せるのが特徴です。「ブランチを作るのに勇気が要らない」のが Git の文化です。

ブランチの作成と切り替え

ブランチ一覧の確認

git branch

現在のブランチが * 付きで表示されます。

ブランチの作成

git branch ブランチ名

例:

git branch feature-add-readme

これで feature-add-readme という名前のブランチが作られますが、まだ切り替わってはいません。

ブランチの切り替え

新しい書き方(Git 2.23 以降推奨):

git switch ブランチ名

古い書き方(互換性あり):

git checkout ブランチ名

作成と切り替えを 1 行で

新しい書き方:

git switch -c ブランチ名

古い書き方:

git checkout -b ブランチ名

-c(create)または -b で「作って切り替える」を 1 行で実行できます。実務ではこちらをよく使います。

ブランチで作業する流れ

# main ブランチで作業中だが、新機能を試したい
git switch -c feature-add-contact

# このブランチで自由に編集・commit
echo "Contact page" > contact.md
git add contact.md
git commit -m "Add contact page draft"

# main に戻る
git switch main

# main は変わっていない(contact.md は存在しない状態)
ls

feature-add-contact ブランチで作った contact.md は、main ブランチに切り替えると消えます。これが「ブランチが独立している」感覚です。

⚠️ 注意 未 commit の変更があるまま git switch でブランチを切り替えると、状況によってエラーが出ることがあります。基本は「ブランチを切り替える前に commit する」習慣を持ちましょう。

マージ——並行作業の合流

ブランチで作業した内容を、main ブランチに反映するのが「マージ(merge)」です。

マージの基本

# main ブランチに切り替え
git switch main

# feature-add-contact ブランチの変更を main にマージ
git merge feature-add-contact

これで contact.md が main ブランチに取り込まれます。

マージの 2 つのパターン

Git のマージには、内部的に 2 つのパターンがあります。

Fast-forward マージ

main ブランチが、分岐した時点から進んでいない場合、ブランチの履歴をそのまま main の先端として「進める」だけのマージです。

分岐時点:
main:    ●─●─●

feature ブランチで作業:
main:    ●─●─●
              \
feature:       ●─●

merge 後(fast-forward):
main:    ●─●─●─●─●

新しい commit は作らず、main の先端を進めるだけです。

3-way merge

main ブランチも、分岐後に進んでいる場合、「分岐元」「main の先端」「feature の先端」の 3 点を考慮した、新しい「マージコミット」を作ります。

分岐時点:
main:    ●─●─●

main も feature も進んだ後:
main:    ●─●─●─●
              \
feature:       ●─●

merge 後(3-way merge):
main:    ●─●─●─●─●(マージコミット)
              \   /
feature:       ●─●

「マージコミット」が新しく作られ、両方の枝が合流します。

どちらが起きるか

Git は自動で判定します。利用者は通常、どちらが起きるか意識しません。ただし、後述の「コンフリクト」が起きる可能性は 3-way merge の場合だけです。

📝 補足 git merge --no-ff というオプションを使うと、fast-forward が可能な場合でも強制的にマージコミットを作ることができます。「いつブランチがマージされたか」を履歴に残したいときに使います。本コースでは深掘りしませんが、レッスン 8 のブランチ戦略で再度触れます。

マージコンフリクト——同じ箇所を変えた場合

複数のブランチで同じファイルの同じ箇所を変えていると、Git は「どちらを採用すべきか」を判断できず、人間に判断を求めます。これが「マージコンフリクト(merge conflict)」です。

コンフリクトの発生

例:main ブランチで README.md を編集、feature ブランチでも同じ行を編集。merge しようとすると:

$ git merge feature-edit-readme
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.

コンフリクトの中身

README.md を開くと、

# My Project

<<<<<<< HEAD
This is the main branch version.
=======
This is the feature branch version.
>>>>>>> feature-edit-readme

のような特殊な記法が挿入されています。

  • <<<<<<< HEAD から ======= まで:main ブランチ(現在のブランチ)の内容
  • ======= から >>>>>>> feature-edit-readme まで:マージしようとしているブランチの内容

コンフリクトの解消

人間がエディタで開いて、

  • どちらか一方を採用
  • 両方を組み合わせる
  • まったく違う内容に書き直す

を判断し、<<<<<<<=======>>>>>>> の行を削除した上で保存します。

例:

# My Project

This is the main branch version with feature added.

コンフリクト解消後の操作

# 解消したファイルをステージに上げる
git add README.md

# マージコミットを作る
git commit

これでマージが完了します。

マージを中止する

「やっぱりマージしたくない」と思ったら、

git merge --abort

でマージを中止できます。元の状態に戻ります。

⚠️ 注意 コンフリクトは Git の初心者が最も怖がる場面ですが、「Git が困っていて、人間に判断を求めている」状態です。焦らず、コンフリクトの中身を読んで、適切な内容に書き直せば解消できます。

main ブランチ/作業ブランチの基本ルール

業務での Git 利用には、いくつかの共通ルールがあります。

main ブランチ=「動く状態」を保つ

  • main は「いつでも動かせる」状態を保つ
  • 直接 main で commit するのは避ける(個人プロジェクト初期では OK)
  • 機能追加・変更は別ブランチで行い、完成してから main にマージする

作業ブランチの命名

ブランチ名には用途を表す名前を付けます。

  • feature-XXX:新機能の開発
  • fix-XXX:バグ修正
  • hotfix-XXX:緊急の修正
  • refactor-XXX:リファクタリング(コード整理)
  • docs-XXX:ドキュメントの変更

組織によって慣習は変わります。チームで揃えるのが重要です。

ブランチを短命に保つ

長期間生きているブランチは、main から大きく離れて、マージが難しくなります。

  • 1 つのブランチは数日〜数週間で完結
  • 大きな機能は、小さなブランチに分割
  • マージ済みのブランチは削除(git branch -d ブランチ名

💡 ポイント 「ブランチをどう使うか」を決めることを「ブランチ戦略」と呼びます。GitHub Flow、Git Flow など、いくつかの代表的な戦略があり、レッスン 8 で改めて整理します。

講師の現場メモ:「ブランチがあって本当に救われた金曜日の夜」

私(青木)が SaaS スタートアップで開発をしていた、ある金曜日の夜の話です。当時のチームは 5 人で、私は新機能の追加を任されていました。

金曜の夕方、開発を進めていた feature-new-billing ブランチで、別途進めていた仕様変更を取り込もうとマージ作業を始めました。テスト環境にデプロイしたところ、既存のユーザー認証フローで大規模なエラーが発生。サポートチャットに次々と問い合わせが届きました。

私は焦りました。元のコードに戻したい——でも、何を変えたか覚えていない。週末でほかのメンバーは捕まらない。

そのとき、私は冷静になって思い出しました。「main ブランチには、まだこの変更は入っていない」。

私は git switch main で main ブランチに戻り、テスト環境を main の状態でデプロイし直しました。3 分でエラーが解消。問い合わせは止まりました。

その晩、私は別のブランチで原因を調査し、月曜日に修正版をリリースしました。元の feature-new-billing ブランチはそのまま残し、修正後に丁寧にマージし直しました。

そのときに痛感したのは、ブランチが独立しているからこそ、「すぐに戻れる安心感」がある、ということです。もし main で直接作業していたら、その金曜の夜は復旧に何時間もかかっていたでしょう。

本コースで「main は『動く状態』を保つ」「作業は別ブランチで」を繰り返すのは、この金曜の夜の経験があるからです。ブランチを作る習慣は、未来の自分を救う保険になります。

まとめ

このレッスンでは、以下のことを学びました。

  • ブランチは「作業の流れの枝」。並行する作業を独立して進める道具
  • Git のブランチは軽量で、何個でも作って消せる
  • git branch:ブランチ一覧の確認
  • git branch ブランチ名:作成
  • git switch ブランチ名(または古い書き方 git checkout):切り替え
  • git switch -c ブランチ名(または git checkout -b):作成と切り替えを 1 行で
  • マージ:別ブランチの変更を取り込む。git merge ブランチ名
  • Fast-forward マージ:main が進んでいない場合、ブランチの先端をそのまま進める
  • 3-way マージ:両方が進んでいる場合、マージコミットを作る
  • マージコンフリクト:同じ箇所を変えた場合、Git が人間に判断を求める。<<<<<<<=======>>>>>>> の記法を消して保存
  • git merge --abort:マージの中止
  • 基本ルール:main は「動く状態」を保つ、作業は別ブランチで、ブランチ名は用途で命名、ブランチは短命に保つ

次のレッスンでは、リモートと協業の入口として GitHub の使い方を扱います。


確認クイズ

このレッスンの理解度をチェックしましょう。