ゼロから始める
Git Flow 実践入門
実際のプロジェクトを想定し、セットアップからリリースまでを ステップバイステップで体験するハンズオンガイドです。
事前準備
Git のインストール
Git 2.0 以上が必要です。git --version で確認してください。
未インストールの場合は brew install git (Mac) または公式サイトからダウンロード。
git-flow 拡張 (任意)
手動コマンドでも可能ですが、git-flow 拡張を入れると便利です。
brew install git-flow-avh でインストールできます。
GitHub アカウント
PR の練習には GitHub (または GitLab / Bitbucket) のリモートリポジトリが必要です。 SSH キーの設定も済ませておきましょう。
リポジトリの初期設定
リポジトリを作成
新しいプロジェクトを作成し、最初のコミットを行います。これが main ブランチの起点になります。
mkdir my-project && cd my-project
git init
echo "# My Project" > README.md
git add README.md
git commit -m "initial commit"
git branch -M main
develop ブランチを作成
GitHub などで作成したリモートリポジトリを登録し、main から develop を切ります。以降、日常の開発はすべて develop を起点に行います。
git remote add origin git@github.com:your-name/my-project.git
git push -u origin main
git checkout -b develop main
git push -u origin develop
機能を開発する
feature ブランチで作業開始
develop から feature ブランチを切り、機能を実装します。ブランチ名は feature/ + 機能名。
git checkout -b feature/add-login develop
# コードを書く...
git add .
git commit -m "feat: ログインフォームを追加"
# さらにコードを書く...
git add .
git commit -m "feat: パスワードバリデーションを実装"
# リモートにプッシュ
git push -u origin feature/add-login
GitHub のブラウザだけで進める場合
ローカルのコマンドを使わず、GitHub の画面だけでブランチ作成から PR マージまで進める流れです。README やドキュメントなど、ブラウザ上で直接編集できるファイルから作業を始める場合に便利です。
Browser Flow
まずは「どのブランチから作るか」を確認します。通常の機能追加は develop から feature、緊急修正だけ main から hotfix です。
- リポジトリ画面で、左上のブランチ選択メニューから develop を選ぶ
- 同じメニューの検索欄に feature/add-login と入力する
- Create branch: feature/add-login from develop をクリックする
- 作成された feature ブランチ上で対象ファイルを開き、鉛筆アイコンまたは Edit this file で編集する
- Commit changes を押し、コミットメッセージを書いて Commit directly to the feature/add-login branch を選ぶ
- Pull requests タブから New pull request を押す
- base を develop、compare を feature/add-login にして差分を確認する
- Create pull request を押し、タイトル・変更内容・テスト方法を書いて作成する
- CI が通り、レビュー承認後にマージ方式を選んでマージする
- マージ後に Delete branch を押して feature ブランチを削除する
ポイントは、必ず develop を選んだ状態 で新しい feature ブランチを作ることです。main から切ると Git Flow の流れとずれてしまいます。
押す前に見る場所
PR 画面では base と compare を必ず確認します。 base: develop、compare: feature/add-login なら「feature の変更を develop に入れる」という意味です。 逆になっていると意図しない差分になるので、作成前に直します。
初心者向けのおすすめ
feature ブランチの PR は、迷ったら Squash and merge を選びます。 小さな修正コミットが1つにまとまり、develop の履歴が読みやすくなります。 ただし、チームで「Git Flow はマージコミットを残す」と決めている場合は Create a merge commit を選びます。
Pull Request を作成
GitHub 上で feature/add-login → develop の PR を作成します。チームメンバーにレビューを依頼しましょう。
# GitHub CLI で PR 作成
gh pr create \
--base develop \
--title "feat: ログイン機能を追加" \
--body "## 変更内容
- ログインフォームの実装
- パスワードバリデーション
## テスト方法
- /login にアクセスして確認"
ブラウザで PR を作る場合
GitHub のリポジトリ画面で Pull requests タブを開き、New pull request をクリックします。 base を develop、compare を feature/add-login にして差分を確認し、 Create pull request からタイトル・説明・テスト方法を書いて作成します。
コードレビュー
PR を作成すると、チームメンバーや自動レビューツール(CodeRabbit、GitHub Actions など)がコードをチェックします。以下を確認しましょう:
Review Checklist
- ✓ CI / 自動テストが通っているか(All checks have passed)
- ✓ コンフリクトがないか(No conflicts with base branch)
- ✓ 自動レビューツールの指摘に対応したか
- ✓ チームメンバーの Approve を得たか
レビューで修正が必要な場合は、同じ feature ブランチにコミットして push するだけで PR に反映されます。
# レビュー指摘を修正して再プッシュ
git add .
git commit -m "fix: レビュー指摘を修正"
git push origin feature/add-login
マージを実行
レビューが承認されたら、GitHub 上でマージ方式を選んで実行します。初心者は「何を残したいか」で選ぶと迷いにくいです。
Merge Options
| 選択肢 | 使う場面 | 初心者判断 |
|---|---|---|
| Squash and merge | feature ブランチの細かいコミットを1つにまとめたいとき | 個人・小チームならまずこれ |
| Create a merge commit | PR 単位の履歴や Git Flow の分岐履歴を残したいとき | チームで Git Flow を厳密に運用するならこれ |
| Rebase and merge | 履歴を直線的にしたいとき | 慣れるまでは選ばない |
このサイトでの基本ルール
feature → develop は Squash and merge を基本にします。 release → main と hotfix → main は、リリースや緊急修正の区切りを履歴に残すため Create a merge commit を選びます。 マージ後は GitHub の Delete branch で作業ブランチを削除します。
ローカルを同期 & ブランチ削除
GitHub でマージ後、ローカルの develop を最新にして、不要になった feature ブランチをローカル・リモートの両方から削除します。
# develop を最新に同期
git checkout develop
git pull origin develop
# ローカルの feature ブランチを削除
git branch -d feature/add-login
# リモートの feature ブランチも削除
git push origin --delete feature/add-login
リリースする
release ブランチで最終調整
リリースに含める機能が揃ったら release ブランチを作成。バグ修正やバージョン番号の更新を行います。
git checkout -b release/1.0.0 develop
# バージョン番号を更新
git commit -am "chore: bump version to 1.0.0"
# QA で見つかったバグを修正
git commit -am "fix: 入力欄のフォーカス不具合を修正"
git push -u origin release/1.0.0
main と develop にマージ
ここではローカルでマージする例を示します。PR 運用にする場合は release → main と release → develop の2つを作成し、main にマージしたタイミングでタグを付けます。
GitHub ブラウザで release をマージする場合
まず release/1.0.0 → main の PR を作り、マージ方式は Create a merge commit を選びます。 その後、同じ release ブランチから release/1.0.0 → develop の PR も作り、リリース中の修正を develop に戻します。 release はリリースの区切りなので、Squash で潰さずマージコミットを残すと後から追いやすくなります。
# main にマージ
git checkout main
git merge --no-ff release/1.0.0 -m "release: v1.0.0"
git tag -a v1.0.0 -m "Version 1.0.0"
# develop にもマージ
git checkout develop
git merge --no-ff release/1.0.0
# プッシュ & クリーンアップ
git push origin main develop --tags
git branch -d release/1.0.0
git push origin --delete release/1.0.0
本番の緊急修正
hotfix で素早く修正
本番で致命的バグ発見。main から直接 hotfix ブランチを作り、修正後に main と develop の両方へマージします。
GitHub ブラウザで hotfix を進める場合
hotfix だけは main を選んだ状態 で hotfix/critical-bug ブランチを作ります。 修正後は hotfix/critical-bug → main の PR を作り、マージ方式は Create a merge commit を選びます。 その後、同じ hotfix を develop にも取り込む PR を作ります。これを忘れると、次のリリースで同じバグが戻る可能性があります。
# main から hotfix ブランチを作成
git checkout -b hotfix/critical-bug main
# 修正 & コミット
git commit -am "fix: 決済処理のクラッシュを修正"
# main にマージ & タグ
git checkout main
git merge --no-ff hotfix/critical-bug
git tag -a v1.0.1 -m "Hotfix: 決済クラッシュ修正"
# develop にもマージ
git checkout develop
git merge --no-ff hotfix/critical-bug
git push origin main develop --tags
git branch -d hotfix/critical-bug
git push origin --delete hotfix/critical-bug
実プロジェクトで起きること
ここからは、実際の開発でよく遭遇する「教科書には載っていないつまずきポイント」を、 状況 → 原因 → 解決方法 の流れで紹介します。 エラーメッセージは怖く見えますが、意味がわかれば落ち着いて対処できます。
CI / デプロイが突然 0 秒で失敗する
PR を作ったら自動チェック(CI / CD)が赤くなった。ログを見ると 「failed in 0s」 のように、ほぼ一瞬で終わっています。
# 失敗ログの抜粋
Cloudflare Workers and Pages / Workers Builds: gittest
failed 1 hour ago in 0s
原因
ビルドコマンドが走る前に 必要な設定ファイルが見つからず、即終了 しているケースがほとんど。
Cloudflare Workers なら wrangler.toml、
Vercel / Netlify なら package.json や設定ファイルの不足が典型例です。
解決方法
必要な設定ファイルを追加してコミット → push するだけ。今回は静的サイトなので、リポジトリのルートに wrangler.toml を作りました。
name = "gittest"
compatibility_date = "2025-04-26"
# 静的アセットだけ配信する設定
[assets]
directory = "./"
git add wrangler.toml
git commit -m "chore: wrangler.toml を追加"
git push
覚えておこう: 「0 秒で失敗」は ビルド前 の設定エラー。 「数秒〜数分で失敗」は ビルド中 のコードエラー。 失敗までの時間でアタリがつきます。
Squash merge の後、ブランチ削除で警告が出る
GitHub で「Squash and merge」を選んでマージした後、ローカルブランチを git branch -d で消そうとすると、こんな警告が出ます。
git branch -d feature/add-login
# 出力
warning: deleting branch 'feature/add-login' that has been merged to
'refs/remotes/origin/feature/add-login', but not yet merged to HEAD.
Deleted branch feature/add-login (was 472e3d9).
原因
Squash merge は元の複数コミットを 「全く新しい 1 つのコミット」 にまとめます。 そのため、元の feature ブランチのコミットは develop の履歴には残りません。 Git は「develop に同じコミットが存在しない」=「マージされてない」と判定して、念のため警告を出してくれているのです。
通常マージ vs Squash マージ
通常マージ: develop: A---B---M ← C, D が develop の履歴に残る \ / feature: C-D Squash マージ: develop: A---B---S ← S は C+D を圧縮した「別の新コミット」 feature: C---D ← C, D は develop のどこにも存在しない
解決方法
GitHub 上でマージ済みで、PR の差分が develop に反映されていることを確認できていれば削除してかまいません。
不安な場合は git log や GitHub の PR 画面で、対象の変更が取り込まれているか確認してから削除しましょう。
消したはずのブランチがローカルに残っている
GitHub 上でマージ後にブランチを削除しても、自分の手元には「リモート追跡ブランチ」として情報が残り続けます。
git branch -a で見ると、ゴミがどんどん溜まっていきます。
git fetch -p
# 出力例
From github.com:user/repo
- [deleted] (none) -> origin/feature/add-login
解説
-p は --prune の短縮形で、
「リモートで消えたブランチの追跡情報をローカルからも掃除する」 オプション。
git pull や git fetch の時に習慣的に付けるとよいでしょう。
Tip: 一度だけ git config --global fetch.prune true を設定すれば、
以降は何もしなくても自動で prune されます。忘れがちな人にはおすすめ。
ブランチを切り替えようとしたら拒否された
作業の途中で別のブランチに移ろうとして、こんなエラーが出ることがあります。
git checkout develop
# エラー
error: Your local changes to the following files would be overwritten by checkout:
memo.md
Please commit your changes or stash them before you switch branches.
Aborting
原因
未コミットの変更 がある状態で、移動先のブランチではそのファイルの中身が違うため、 Git が「あなたの変更が上書きされちゃうけど、いいの?」と止めてくれています。 これは 親切なエラー なので、慌てなくて大丈夫。
対処法は3つ。状況に応じて選びましょう。
A. 後で戻す予定 → stash で一時退避
git stash push -m "作業中" memo.md
git checkout develop
# 後で戻すとき
git stash pop
B. 別の作業として継続 → 新ブランチに退避
git checkout -b feature/memo-update
git add memo.md
git commit -m "docs: メモを更新"
C. 変更がもう不要 → 破棄
git checkout -- memo.md
# 変更が消えます。必ず git diff で内容を確認してから実行
迷ったら: まず git diff で何を変更したか確認 → 残したいなら A か B、不要なら C。
「迷ったら stash」が安全策です(後でいつでも戻せます)。
stash pop / マージでコンフリクトが起きた
退避していた変更を git stash pop で戻したら、
「CONFLICT」 と表示されてしまった。あるいは PR マージや
git merge で同じことが起きるパターンです。
git stash pop
# 出力
Auto-merging tsuika.md
CONFLICT (content): Merge conflict in tsuika.md
On branch feature/tsuika-update
Unmerged paths:
both modified: tsuika.md
原因
同じファイルの 近い場所 を、 stash 側(または merge 元)と現在のブランチ側の両方で変更していたため、 Git がどちらを採用すべきか判断できずに止まっています。 コンフリクトは 失敗ではなく「人間に判断を委ねた状態」 です。
解決は4ステップ。順番に進めれば必ず解消できます。
Step 1. ファイルを開いてマーカーを確認
コンフリクトしたファイルを開くと、こんな印が埋め込まれています。
共通部分はそのまま残ります
<<<<<<< Updated upstream
# ← このブロックは「移動先 / 現在のブランチ」の内容
=======
# ← このブロックは「stash / マージ元」の内容
>>>>>>> Stashed changes
ここから下も共通部分
Step 2. どちらを残すか決める
- 上だけ残す(Updated upstream を採用)
- 下だけ残す(Stashed changes を採用)
- 両方を組み合わせて手で書き直す
迷ったら、両方の中身をコピーして別ファイルに退避してから判断するのもアリ。
Step 3. マーカー3行を必ず削除
<<<<<<<、=======、>>>>>>>
の3行はあくまで 目印。残したままコミットするとコードが壊れます。
VSCode などのエディタなら「Accept Current / Incoming / Both」のボタンで一括処理できます。
Step 4. git add で解決を伝えてコミット
git add tsuika.md # これでコンフリクト解消を Git に通知
git commit -m "docs: コンフリクトを解消"
# stash 由来なら、使い終わった stash を消す
git stash drop
覚えておこう:
Updated upstream は 今いる場所、Stashed changes は 取り込もうとしたもの。
マージの場合は HEAD と マージ元ブランチ名 が表示されます。
Tip: 中断したくなったら git merge --abort(マージの場合)や
git checkout -- ファイル名(stash の適用で出た作業ツリーの変更を破棄する場合)で戻せます。後者は変更を消す操作なので、実行前に git diff で確認しましょう。
よくあるミスと対処法
main に直接コミットしてしまった
まだ push していない場合は、git reset --soft HEAD~1 でコミットだけを取り消し、正しいブランチに切り替えてからコミットし直しましょう。
既に push 済みの場合は、revert コミットを作成して対応します。
feature を main から切ってしまった
git rebase --onto develop main feature/xxx で develop ベースに付け替えられます。
ただし、共有済みのブランチでは履歴が変わるため、チームに確認してから実行しましょう。迷う場合は develop から新しい feature ブランチを切り直し、変更を移す方法が安全です。
develop が main より古い
hotfix が main にマージされた後、develop への反映を忘れるケースです。
git checkout develop && git merge main で同期しましょう。
コンフリクトが怖い
feature ブランチで定期的に git merge develop して最新を取り込みましょう。
長寿命の feature ブランチほどコンフリクトリスクが高まります。こまめなマージが鍵です。