このチュートリアルで学ぶこと
- ブランチの基本操作
- Feature Branch Workflow
- Git FlowとGitHub Flowの違い
- マージとリベースの使い分け
- コンフリクトの解決
ブランチ戦略とは?なぜ重要なのか
ブランチ戦略の歴史
ブランチ戦略が注目されるようになったのは、チーム開発が複雑化した2000年代後半からです。
2010年、Vincent Driessenが「A successful Git branching model」という記事でGit Flowを提唱。これが最初の体系的なブランチ戦略として広く普及しました。
その後、GitHubが2011年にシンプルなGitHub Flowを提唱。継続的デプロイを行うチームに最適なモデルとして支持を集めました。
「ブランチ戦略は、チームのワークフローに合わせて選択すべきもの。万能な戦略は存在しない」— Vincent Driessen, 2020年の補足記事より
なぜブランチ戦略が必要なのか
- 並行開発: 複数の機能を同時に開発できる
- リスク分離: 不安定なコードをメインラインから隔離
- コードレビュー: プルリクエストによる品質担保
- リリース管理: 本番環境への反映をコントロール
主要なブランチ戦略の比較
| 戦略 | 複雑さ | 適したチーム | デプロイ頻度 |
|---|---|---|---|
| Feature Branch | 低 | 小規模 | 任意 |
| GitHub Flow | 低 | 継続的デプロイ | 毎日〜週数回 |
| Git Flow | 高 | リリースサイクルが明確 | 週〜月1回 |
| Trunk Based | 中 | 大規模・成熟したチーム | 毎日〜複数回/日 |
ブランチの基本操作
ブランチの作成と切り替え
# ブランチ一覧を表示
git branch
# リモートブランチも含めて表示
git branch -a
# 新しいブランチを作成
git branch feature/login
# ブランチを切り替え
git checkout feature/login
# 作成と切り替えを同時に(推奨)
git checkout -b feature/login
# Git 2.23以降の新しいコマンド(推奨)
git switch -c feature/login
git switch feature/login
公式ドキュメント: git-branch
ブランチの命名規則
チームで一貫した命名規則を使うことが重要です:
# 機能開発
feature/user-authentication
feature/payment-integration
# バグ修正
fix/login-button-crash
bugfix/memory-leak
# 緊急修正
hotfix/security-vulnerability
# リリース準備
release/v1.2.0
# 実験的な機能
experiment/new-algorithm
ベストプラクティス: ブランチ名は小文字、ハイフン区切り、課題番号を含めると追跡しやすい(例:
feature/JIRA-123-add-login)
リモートブランチの操作
# リモートブランチを含めて表示
git branch -a
# リモートブランチをローカルにチェックアウト
git checkout -b feature/login origin/feature/login
# または(Git 2.23以降)
git switch feature/login # 自動的にリモート追跡
# ブランチをリモートにプッシュ
git push -u origin feature/login
# リモートブランチを削除
git push origin --delete feature/login
# ローカルブランチを削除
git branch -d feature/login
# マージされていないブランチを強制削除
git branch -D feature/login
ブランチの状態確認
# ブランチ間の差分を確認
git diff main..feature/login
# マージ済みのブランチを表示
git branch --merged
# 未マージのブランチを表示
git branch --no-merged
# ブランチの最後のコミットを表示
git branch -v
Feature Branch Workflow
最も基本的なブランチ戦略です。機能ごとにブランチを作成し、完了後にメインブランチにマージします。
ワークフロー図
gitGraph
commit
branch feature/A
commit
commit
commit
commit
checkout main
merge feature/A
commit
実践シナリオ: ログイン機能の追加
# 1. メインブランチを最新に
git checkout main
git pull origin main
# 2. 機能ブランチを作成
git checkout -b feature/login
# 3. 実装とコミット
# (コードを編集)
git add .
git commit -m "feat: Add login form component"
# (さらに実装)
git add .
git commit -m "feat: Add login API integration"
# (テスト追加)
git add .
git commit -m "test: Add login validation tests"
# 4. リモートにプッシュ
git push -u origin feature/login
# 5. プルリクエストを作成(GitHub上で)
# 6. レビュー後、マージ
プルリクエストのベストプラクティス
「プルリクエストは小さく保つ。レビュアーが20分以内に確認できるサイズが理想」— Google Engineering Practices
- 適切なサイズ: 200-400行が目安
- 単一の目的: 1つのPRに1つの機能/修正
- 説明を丁寧に: 背景、変更内容、テスト方法を記載
- セルフレビュー: 提出前に自分でチェック
Git Flow
リリースサイクルが明確なプロジェクト向けの戦略です。Vincent Driessenが2010年に提唱しました。
主要ブランチ
flowchart TB
main["main(またはmaster)"]
develop["develop(開発統合ブランチ)"]
feature["feature/*(機能開発)"]
release["release/*(リリース準備)"]
hotfix["hotfix/*(緊急バグ修正)"]
main --> develop
develop --> feature
develop --> release
main --> hotfix
| ブランチ | 目的 | 派生元 | マージ先 |
|---|---|---|---|
| main | 本番リリース | - | - |
| develop | 開発統合 | main | main, release |
| feature/* | 機能開発 | develop | develop |
| release/* | リリース準備 | develop | main, develop |
| hotfix/* | 緊急修正 | main | main, develop |
Git Flowの実践
# developから機能ブランチを作成
git checkout develop
git checkout -b feature/user-profile
# 機能完了後、developにマージ
git checkout develop
git merge --no-ff feature/user-profile
git branch -d feature/user-profile
# リリース準備
git checkout -b release/1.0.0 develop
# バージョン番号更新、バグ修正など
git commit -m "chore: Bump version to 1.0.0"
# リリース完了
git checkout main
git merge --no-ff release/1.0.0
git tag -a v1.0.0 -m "Version 1.0.0"
git checkout develop
git merge --no-ff release/1.0.0
git branch -d release/1.0.0
# 緊急修正(Hotfix)
git checkout main
git checkout -b hotfix/security-fix
# 修正後
git checkout main
git merge --no-ff hotfix/security-fix
git tag -a v1.0.1 -m "Security patch"
git checkout develop
git merge --no-ff hotfix/security-fix
git branch -d hotfix/security-fix
git-flowツール
git-flowコマンドを使うと操作が簡単になります:
# インストール
# macOS
brew install git-flow
# Ubuntu
apt install git-flow
# 初期化
git flow init
# 機能開発
git flow feature start user-profile
git flow feature finish user-profile
# リリース
git flow release start 1.0.0
git flow release finish 1.0.0
# ホットフィックス
git flow hotfix start security-fix
git flow hotfix finish security-fix
Git Flowの適用シーン
✅ 適している場合:
- 定期的なリリースサイクルがある
- 複数バージョンのサポートが必要
- QAチームがある
❌ 適さない場合:
- 継続的デプロイを行っている
- 小規模チーム
- Webアプリで常に最新版のみ運用
Vincent Driessenの2020年の補足: 「Web開発のように継続的デプロイが一般的になった今、Git Flowは多くのプロジェクトに過剰。GitHub Flowなどシンプルなモデルを検討してほしい」
GitHub Flow
シンプルで継続的デプロイに適した戦略です。GitHubが公式に推奨しています。
ワークフロー図
gitGraph
commit
branch pr-1
commit
commit
commit
checkout main
merge pr-1
branch pr-2
commit
commit
commit
checkout main
merge pr-2
commit
6つのルール
- mainブランチは常にデプロイ可能
- 機能開発はmainから分岐
- 定期的にリモートにプッシュ
- プルリクエストでコードレビュー
- レビュー後、mainにマージ
- マージ後すぐにデプロイ
GitHub公式ブログ: GitHub Flow
GitHub Flowの実践
# mainから機能ブランチを作成
git checkout main
git pull origin main
git checkout -b add-dark-mode
# 開発・コミット(小さく頻繁に)
git add .
git commit -m "feat: Add dark mode toggle"
git push -u origin add-dark-mode
# プルリクエストを作成(GitHub上)
# コードレビュー
# CI/CDパイプラインが自動実行
# PR承認後、マージ & デプロイ
# マージ後、ブランチを削除
git checkout main
git pull origin main
git branch -d add-dark-mode
GitHub Flowの適用シーン
✅ 適している場合:
- 継続的デプロイを行っている
- 常に最新版のみを運用
- 小〜中規模チーム
Trunk Based Development
GoogleやFacebookなど大規模チームで採用されている戦略です。
特徴
- mainブランチ(trunk)に直接、または短命なブランチからマージ
- ブランチは1-2日以内にマージ
- 大きな機能はフィーチャーフラグで制御
gitGraph
commit
branch short-1
commit
checkout main
merge short-1
branch short-2
commit
checkout main
merge short-2
branch short-3
commit
checkout main
merge short-3
commit
マージ vs リベース
マージ(Merge)
履歴を保持し、マージコミットを作成します。
# feature/loginをmainにマージ
git checkout main
git merge feature/login
# マージコミットを必ず作成(--no-ff)
git merge --no-ff feature/login
結果:
gitGraph
commit
branch feature
commit
commit
checkout main
merge feature
リベース(Rebase)
履歴を直線的に書き換えます。
# mainの最新をfeatureブランチに取り込む
git checkout feature/login
git rebase main
# インタラクティブリベース(コミット整理)
git rebase -i HEAD~3
結果(リベース後):
- mainの最新コミットの後ろにfeatureのコミットが直線的に並ぶ
- マージコミットは作成されない
どちらを使うべきか?
| シナリオ | 推奨 | 理由 |
|---|---|---|
| 共有ブランチへの統合 | マージ | 履歴を保持、安全 |
| ローカルのコミット整理 | リベース | きれいな履歴 |
| mainの最新をfeatureに取り込む | リベース | 線形な履歴 |
| プッシュ済みコミット | マージのみ | 履歴の書き換えは危険 |
黄金律: 「他の人と共有しているコミットは絶対にリベースしない」
インタラクティブリベースでコミットを整理
git rebase -i HEAD~3
エディタが開きます:
pick abc1234 WIP: 作業中
pick def5678 fix: typo
pick ghi9012 feat: ログイン機能追加
# Commands:
# p, pick = コミットを使う
# r, reword = メッセージを編集
# s, squash = 前のコミットと統合
# f, fixup = 前のコミットと統合(メッセージは捨てる)
# d, drop = コミットを削除
# コミットを整理
pick abc1234 WIP: 作業中
squash def5678 fix: typo
squash ghi9012 feat: ログイン機能追加
コンフリクトの解決
コンフリクトが発生する仕組み
flowchart TB
Original["main: Hello World"]
OtherMerge["Hello Everyone<br/>(別の人がマージ)"]
YourChange["feature: Hello Universe<br/>(あなたの変更)"]
Conflict["コンフリクト発生!"]
Original --> OtherMerge
Original --> YourChange
OtherMerge --> Conflict
YourChange --> Conflict
コンフリクトの解決手順
# マージ中にコンフリクトが発生した場合
git status # コンフリクトファイルを確認
# ファイルを編集してコンフリクトを解決
コンフリクトのマーカー:
<<<<<<< HEAD
現在のブランチの内容
=======
マージしようとしているブランチの内容
>>>>>>> feature/login
解決後:
# コンフリクトを解決したファイルをステージング
git add conflicted-file.js
# マージを完了
git commit -m "Merge feature/login with conflict resolution"
# または、マージを中止する場合
git merge --abort
コンフリクト解決のベストプラクティス
- こまめにmainをマージ/リベース: コンフリクトを小さく保つ
- コミュニケーション: 同じファイルを編集する場合は事前に相談
- ツールを活用: VS Code、GitKrakenなどのGUIツール
- テストを実行: 解決後は必ずテストを通す
VS Codeでのコンフリクト解決
VS Codeはコンフリクトを視覚的に解決できます:
Accept Current Change | Accept Incoming Change | Accept Both Changes
実践: チーム開発シミュレーション
2人の開発者がコンフリクトを経験するシナリオを再現します。
# 1. リポジトリを初期化
mkdir team-dev-simulation
cd team-dev-simulation
git init
echo "# Team Project" > README.md
git add README.md
git commit -m "Initial commit"
# 2. 開発者Aのブランチ
git checkout -b feature/header
echo "<header>Header A</header>" > index.html
git add index.html
git commit -m "feat: Add header by Dev A"
# 3. mainに戻って開発者Bのブランチ
git checkout main
git checkout -b feature/footer
echo "<footer>Footer B</footer>" > index.html
git add index.html
git commit -m "feat: Add footer by Dev B"
# 4. feature/headerを先にマージ
git checkout main
git merge feature/header
# 5. feature/footerをマージ(コンフリクト発生!)
git merge feature/footer
# CONFLICT (add/add): Merge conflict in index.html
# 6. コンフリクトを解決
# index.htmlを編集して両方の変更を含める
cat > index.html << 'EOF'
<header>Header A</header>
<footer>Footer B</footer>
EOF
git add index.html
git commit -m "merge: Resolve conflict between header and footer"
ブランチ戦略の選択ガイド
質問に答えてフローを選択
-
継続的にデプロイしますか?
- はい → GitHub Flow または Trunk Based
- いいえ → Git Flow を検討
-
リリースサイクルは?
- 毎日〜週数回 → GitHub Flow
- 週1回〜月1回 → Git Flow
- 1日に複数回 → Trunk Based
-
チームサイズは?
- 1-5人 → GitHub Flow
- 5-20人 → GitHub Flow または Git Flow
- 20人以上 → Trunk Based(フィーチャーフラグ必須)
よくある間違いとアンチパターン
1. 長寿命ブランチ
# アンチパターン: 数週間マージされないブランチ
# コンフリクトが巨大になり、マージが困難に
# ベストプラクティス: こまめにマージ
git checkout feature/big-feature
git fetch origin
git rebase origin/main # 毎日実行
2. プッシュ後のリベース
# 危険!共有されたコミットの書き換え
git push origin feature/x
git rebase -i HEAD~3
git push --force # 他の人の変更を上書き
# 安全: force-with-leaseを使う
git push --force-with-lease
3. mainへの直接コミット
# アンチパターン
git checkout main
git commit -m "Quick fix"
# ベストプラクティス: 必ずPRを通す
git checkout -b fix/quick-fix
git commit -m "Quick fix"
git push -u origin fix/quick-fix
# PRを作成
参考リンク
公式ドキュメント・原典
- A successful Git branching model - Vincent Driessenの原典記事
- GitHub Flow - GitHub公式ドキュメント
- Trunk Based Development - TBDの詳細な解説
ツール
- git-flow - Git Flow用のGit拡張
- GitHub CLI - コマンドラインからPRを管理
関連記事・書籍
- Atlassian Git Tutorials - Branching - 各種ワークフローの比較
- Pro Git Book - Branching - ブランチの詳細な解説
- Google Engineering Practices - コードレビューのベストプラクティス