Git のブランチとマージ:branch・switch・merge を使いこなす
前回はコミットで変更履歴を記録する流れを学びました。 今回は Git の最も強力な機能の一つ、ブランチを取り上げます。
ブランチとは、コミット履歴の「分岐点」を作る仕組みです。
本流(main ブランチ)には手を加えず、別の枝(ブランチ)で新機能の開発やバグ修正を進め、完成したら本流に合流させることができます。
「試しに実装してみたいけど、壊れたら困る」という場面でも、ブランチがあれば安心して試せます。
ブランチを操作する
ブランチの一覧を確認する
現在存在するブランチを一覧表示するには git branch を使います。
git branch
# * main
* が現在いるブランチを示しています。
リモートのブランチも含めて表示したい場合は -a オプションをつけます。
git branch -a
ブランチを作成して切り替える
新しいブランチを作って切り替えるには git switch -c <ブランチ名> を使います。
git switch -c feature/add-login
# Switched to a new branch 'feature/add-login'
-c は --create の短縮形です。既存のブランチに切り替えるだけなら -c は不要です。
git switch main
# Switched to branch 'main'
ブランチ名の慣習として、機能追加なら feature/<名前>、バグ修正なら fix/<名前> のように種別をプレフィックスにするチームが多いです。
git checkout との関係
古い Git ドキュメントや記事では git checkout -b <ブランチ名> が同じ操作として登場します。
checkout はブランチ切り替え・ファイル復元など複数の役割を担っていたため、Git 2.23 以降で git switch(ブランチ切り替え専用)と git restore(ファイル操作専用)に分割されました。
新しく学ぶなら switch を使うのがわかりやすいですが、どちらも現在有効です。
ブランチ上で変更・コミットする
ブランチを切り替えたら、通常どおり作業してコミットします。 コミットはそのブランチにのみ記録され、他のブランチには影響しません。
# feature/add-login ブランチ上で作業
git switch -c feature/add-login
# ファイルを編集して...
git add login.py
git commit -m "Add login form"
git add auth.py
git commit -m "Add password hashing"
git log --oneline でコミット履歴を確認すると、このブランチ上のコミットだけが見えます。
git log --oneline
# b7c3e1f Add password hashing
# a4d2b8c Add login form
# e1f9c2a Initial commit ← main と共通のベース
main ブランチに戻ると、ブランチで行った変更は見えません。ファイルの内容も切り替わります。
git switch main
git log --oneline
# e1f9c2a Initial commit ← feature のコミットは存在しない
マージ:ブランチを合流させる
作業が完了したら、main ブランチに戻ってから git merge でブランチを取り込みます。
git switch main
git merge feature/add-login
マージには大きく2種類の動作があります。
fast-forward マージ
main ブランチがブランチ分岐後に何も変更されていない場合、Git は単純にポインタを先へ進めます。
これを fast-forward マージ といいます。マージコミットは作られません。
# 分岐前
main: A → B
# feature ブランチで作業後
main: A → B
feature: → C → D
# fast-forward 後
main: A → B → C → D
3-way マージ
main ブランチにも追加のコミットがあった場合、Git は共通の祖先を基点にして両方の変更を統合します。
これを 3-way マージ といい、結果としてマージコミットが1つ作られます。
# 分岐後、main にも変更が入った状態
main: A → B → E
feature: → C → D
# 3-way マージ後
main: A → B → E → M(マージコミット)
↗
feature: → C → D
3-way マージ時、同じファイルの同じ箇所を両ブランチが別々に変更しているとコンフリクトが発生します。 コンフリクトの解消は次回に詳しく扱います。
ブランチを削除する
マージ済みのブランチは -d オプションで削除できます。
git branch -d feature/add-login
# Deleted branch feature/add-login (was b7c3e1f).
-d はマージ済みかどうかを確認してから削除します。まだマージしていないブランチを強制削除したい場合は -D(大文字)を使いますが、変更が失われるので注意してください。
# マージ済みブランチの一覧確認
git branch --merged
--merged でマージ済みブランチだけを表示できるので、定期的に確認して整理するとよいです。
フィーチャーブランチ運用の流れ
個人開発・チーム開発を問わず、よく使われるシンプルな運用が「フィーチャーブランチ運用」です。
# 1. main を最新にしてからブランチを切る
git switch main
git pull # リモートがある場合(次回以降で解説)
# 2. 作業用ブランチを作って切り替える
git switch -c feature/improve-ui
# 3. こまめにコミットしながら作業を進める
git add <file>
git commit -m "..."
# 4. 作業が完了したら main に戻ってマージ
git switch main
git merge feature/improve-ui
# 5. マージ済みブランチを削除
git branch -d feature/improve-ui
この流れを習慣化しておくと、「あの機能の変更だけ取り消したい」「別の機能と並行して作業したい」という場面でもスムーズに対処できます。
実践的なコツ
ブランチは軽い。気軽に切る
ブランチの作成はポインタを1本追加するだけで、コストはほぼゼロです。 「試しに実装してみる」「設定ファイルを少し変えてみる」といった場面でも、ためらわずブランチを切る習慣をつけましょう。
main を定期的に取り込む
長期間ブランチで作業を続けると、main との乖離が大きくなりコンフリクトが増えます。
定期的に main の変更をブランチに取り込む(git merge main または git rebase main)と、コンフリクトが小さく収まります。
rebase については次回詳しく解説します。
コンフリクトは早めに検知する
同じファイルを複数のブランチで編集していると、マージ時にコンフリクトが起きます。 コンフリクト自体は Git の正常な動作で、怖いものではありません。 ただし解消が後回しになるほど複雑になるので、早めに対処するのがコツです。
まとめ
- ブランチは本流に影響を与えずに作業を分岐させる仕組み。コストはほぼゼロ
git switch -c <名前>でブランチを作成して切り替える- コミットはそのブランチにのみ記録され、他のブランチのファイルには影響しない
git switch main→git merge <ブランチ名>で作業を本流に合流させる- fast-forward はポインタ移動のみ、3-way マージはマージコミットを作る
- マージ済みブランチは
git branch -dで削除して整理する
次回は git rebase を取り上げます。
マージとは別のアプローチでブランチを統合し、コミット履歴を直線的に保つ方法を学びます。