ブランチとマージ——分岐と合流の発想
レッスン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 の使い方を扱います。
確認クイズ
このレッスンの理解度をチェックしましょう。