Gitのブランチとマージ入門|コンフリクト解消も解説
Gitのブランチは、開発の流れを分岐させて独立した作業を行うための機能です。新機能の開発やバグ修正をメインのコードに影響を与えずに進められます。この記事ではブランチの作成からマージ、コンフリクトの解消方法までを初心者向けに解説します。
ブランチとは
ブランチ(branch)は「枝」を意味する言葉で、Gitでは開発の流れを枝分かれさせる機能です。
ブランチが必要な理由
たとえば、Webサイトを公開中に新しい機能を追加したいとします。直接メインのコードを変更すると、開発途中の不完全なコードが公開されてしまう恐れがあります。
ブランチを使えば、メインのコードはそのままに、別の枝で新機能の開発を進められます。完成したらメインに合流(マージ)させます。
main ───o───o───o───────────o─── (本番用の安定した流れ)
\ /
feature ──────o───o───o──── (新機能の開発)
mainブランチ
Gitリポジトリを作成すると、デフォルトでmain(またはmaster)ブランチが作られます。これが開発の「幹」にあたるブランチで、通常は安定したコードを保ちます。
ブランチの基本操作
ブランチの確認
# ブランチの一覧を表示(*が現在のブランチ)
git branch
# * main
# リモートブランチも含めて表示
git branch -a
ブランチの作成と切り替え
# 新しいブランチを作成
git branch feature-login
# ブランチを切り替え
git checkout feature-login
# 作成と切り替えを同時に行う(推奨)
git checkout -b feature-login
# Git 2.23以降ではswitchコマンドも使える
git switch -c feature-login
git checkout -bを使うと、ブランチの作成と切り替えを一度に行えます。
ブランチでの作業
ブランチを切り替えたら、通常通りファイルを編集してコミットします。
# feature-loginブランチで作業中
git checkout -b feature-login
# ファイルを編集
echo "ログイン機能" > login.py
# 変更をコミット
git add login.py
git commit -m "ログイン機能を追加"
# さらに作業を続ける
echo "バリデーション追加" >> login.py
git add login.py
git commit -m "入力バリデーションを追加"
この間、mainブランチのコードには何の影響もありません。
ブランチの削除
# マージ済みのブランチを削除
git branch -d feature-login
# マージしていないブランチを強制削除
git branch -D feature-login
マージの基本
マージ(merge)は、あるブランチの変更を別のブランチに取り込む操作です。
マージの手順
# 1. 取り込み先のブランチに切り替え
git checkout main
# 2. 変更元のブランチをマージ
git merge feature-login
マージは「現在いるブランチに、指定したブランチの変更を取り込む」操作です。そのため、まず取り込み先(通常はmain)に移動してからマージを実行します。
Fast-forwardマージ
mainブランチに新しいコミットがなく、featureブランチだけが進んでいる場合は「Fast-forward」マージが行われます。
マージ前:
main ───o───o
\
feature o───o
マージ後:
main ───o───o───o───o (mainのポインタが移動するだけ)
Fast-forwardマージでは、mainのポインタがfeatureの先端まで移動するだけで、マージコミットは作られません。
マージコミット
mainブランチにも新しいコミットがある場合は、マージコミットが作成されます。
マージ前:
main ───o───o───o
\
feature o───o
マージ後:
main ───o───o───o───M (Mがマージコミット)
\ /
feature o───o
コンフリクトの解消
同じファイルの同じ箇所が両方のブランチで変更されていた場合、Gitは自動的にマージできません。これを「コンフリクト(競合)」と呼びます。
コンフリクトが起きたとき
git merge feature-login
# Auto-merging app.py
# CONFLICT (content): Merge conflict in app.py
# Automatic merge failed; fix conflicts and then commit the result.
コンフリクトの中身を確認する
コンフリクトが発生したファイルには、以下のようなマーカーが挿入されます。
def greeting():
<<<<<<< HEAD
return "こんにちは"
=======
return "Hello"
>>>>>>> feature-login
<<<<<<< HEADから=======まで: 現在のブランチ(main)の内容=======から>>>>>>> feature-loginまで: マージ元のブランチの内容
コンフリクトの解消手順
- コンフリクトが起きたファイルを開く
- マーカー(
<<<<<<<,=======,>>>>>>>)を削除する - 正しい内容に修正する
- ファイルをステージングしてコミットする
# 修正後(どちらか選ぶか、両方を活かす)
def greeting():
return "こんにちは / Hello"
# コンフリクトを解消したらコミット
git add app.py
git commit -m "feature-loginブランチのマージ時のコンフリクトを解消"
VS Codeでのコンフリクト解消
VS Codeでは、コンフリクトが起きた箇所に「Accept Current Change」「Accept Incoming Change」「Accept Both Changes」というボタンが表示されます。クリックするだけでコンフリクトを解消できます。
実践的なブランチ運用
ブランチの命名規則
チーム開発では、ブランチ名にプレフィックスをつけて種類を区別することが一般的です。
feature/login-form : 新機能の開発
fix/header-layout : バグの修正
hotfix/security-patch : 緊急の修正
refactor/user-model : リファクタリング
基本的な開発フロー
# 1. mainから新しいブランチを作成
git checkout main
git pull origin main
git checkout -b feature/search-function
# 2. 開発作業(コミットを繰り返す)
git add .
git commit -m "検索フォームのUIを追加"
git add .
git commit -m "検索ロジックを実装"
# 3. mainの最新状態を取り込む
git checkout main
git pull origin main
git checkout feature/search-function
git merge main
# 4. コンフリクトがあれば解消
# 5. リモートにプッシュ
git push origin feature/search-function
# 6. GitHubでプルリクエストを作成してレビュー
# 7. マージ後にブランチを削除
git checkout main
git pull origin main
git branch -d feature/search-function
git stashで作業を一時退避
ブランチを切り替えたいが、今の変更をコミットしたくない場合はgit stashが便利です。
# 現在の変更を一時退避
git stash
# ブランチを切り替えて作業
git checkout main
# ... 何か作業 ...
# 元のブランチに戻る
git checkout feature/search-function
# 退避した変更を復元
git stash pop
# 退避リストの確認
git stash list
よくあるトラブルと対策
間違ったブランチにコミットしてしまった
# 直前のコミットを取り消して変更を保持
git reset --soft HEAD~1
# 正しいブランチに切り替え
git checkout correct-branch
# 改めてコミット
git add .
git commit -m "正しいブランチにコミット"
マージを取り消したい
# マージ直後(まだコミットを進めていない場合)
git merge --abort
# マージコミット後に取り消す場合
git revert -m 1 HEAD
まとめ
Gitのブランチを使うと、メインのコードに影響を与えずに新機能の開発やバグ修正を進められます。git checkout -bでブランチを作成し、git mergeで変更を取り込みます。コンフリクトが発生した場合は、マーカーを確認して手動で解消します。まずは小さな変更でブランチの作成とマージを練習して、流れを体験してみてください。