Git Flow–based branch strategy

環境構築
git
Author

Ryo Nakagami

Published

2025-10-30

Modified

2025-10-30

1. Branch Strategy

  • Git Flow をベースにしたブランチ戦略を採用
  • リリース系列ブランチ,developを統合ブランチとするが,Issue規模・リリース運用の実態に合わせて,Issue用の統合ブランチを活用

%%{ init: {
    'theme': 'default',
    'themeVariables': {
        'fontFamily': 'Meiryo'
    },
    'gitGraph': {
        'orientation': 'LR',
        'nodeSpacing': 150,
        'mainBranchName': 'main'
    }
} }%%

gitGraph
   commit id: "" tag: "v1.0.0"

   branch hotfix
   checkout hotfix
   commit id: "BUGFIX"

   checkout main
   branch develop
   checkout develop
   commit id: "開発開始"

   branch feature/0001/login
   checkout feature/0001/login
   commit id: ""

   checkout main
   merge hotfix tag: "v1.0.1"

   checkout develop
   merge hotfix
   commit id: "incorporate hotfix"

   checkout develop
   merge feature/0001/login
   commit id: "ログイン機能実装"

   branch release/1.1.x
   checkout release/1.1.x
   commit id: "リリース準備"
   commit id: "bugfix"

   checkout develop
   merge release/1.1.x

   checkout main
   merge release/1.1.x  tag: "v1.1.0"

   checkout develop
   commit id: "FEATURE"

2. ブランチの種類

Basic Syntax

<branch-type>/<issue-number>/<task-description>

release 系列ブランチや hotfix ブランチなど,Issue番号を含まない場合もあります.その場合は

release/<major>.<minor>.<patch>
hotfix/<task-description>

命名規則

ブランチ種別 命名規則 目的
本番用 main 本番デプロイ可能な安定版コード.常にリリース済みの状態を保持
開発用 develop 全機能・修正の統合先(メイン開発ブランチ)
機能追加 feature/<issue番号>/<タスク> 新機能開発や改善タスク.小規模IssueはこのままdevelopへPR
機能改善 enhancement/<issue番号>/<タスク> 既存機能の改善タスク.UX改善・処理最適化など
バグ修正 bugfix/<issue番号>/<タスク> 不具合修正用ブランチ.テスト後developへ統合
Issue統合 issue/<issue番号> 中〜大規模Issueの場合のみ作成.複数サブタスクを統合するための統合ブランチ
リリース系列 release/<major>.<minor>.x 特定マイナー系列(例: 1.1.x)の安定維持・軽微修正対応用(長寿命)
リリース準備 release/<version>/create-release-note リリースノート作成・バージョン確定・タグ準備用(短命)
緊急修正 hotfix/<issue番号> 本番環境向けの即時修正.修正後 main / develop 両方に反映
テスト検証用 test/<issue番号>/<タスク> 一時的なテストコード・検証用ブランチ.検証完了後削除
ドキュメント整備 docs/<issue番号>/<タスク> ドキュメント・ガイド・README更新などのためのブランチ
リファクタリング refactor/<issue番号>/<タスク> 挙動を変えずに内部構造を改善するためのブランチ
検証・試作用 sandbox/<タスク> 新しいアイデアやPoCを試すための実験的ブランチ(非公式).安定版にマージしない前提

命名例

ブランチ名 用途
feature/0123-add-login 新機能
bugfix/0123-fix-login-error 修正
issue/0123 複数サブタスクを含むIssue統合
release/1.1.x 1.1 系列のリリース維持
release/1.1.1/create-release-note 1.1.1 リリース準備
hotfix/0145-critical-fix 緊急対応

3. 開発フロー

Step 1. サブタスク開発

各Issueに対して、必要なサブタスクごとにブランチを切ります.

git switch develop
git switch -c feature/0123/add-login
git switch -c bugfix/0123/fix-login-error
  • 小規模Issueなら、このまま develop に直接PR(Step3へ)
  • 中〜大規模Issueなら,Issue統合ブランチを作成し,サブタスクをまとめる (Step 2へ)

Step 2. 中〜大規模Issueの統合ブランチ(任意)

複数のサブタスクをまとめてレビューしたい場合にのみ作成します.

git switch develop
git switch -c issue/0123
git merge feature/0123/add-login
git merge bugfix/0123/fix-login-error
git push -u origin issue/0123
  • 統合PRを作成:issue/0123develop
  • チーム単位でまとめてレビュー/テストを実施

Step 3. developへの統合

  • Issue単位またはサブタスク単位で develop にPR作成
  • ローカルで実行する場合は git merge --no-ff で対応

Step 4. リリース系列ブランチ作成

  • 開発が安定したタイミングでマイナー系列ブランチを作成
  • ブランチ作成は開発規模に応じて,git switch -c または GitHub Actionsで実施
git switch develop
git switch -c release/1.1.x
git push -u origin release/1.1.x

Step 5. リリース準備ブランチ

git switch release/1.1.x
git switch -c release/1.1.1/0130/create-release-note
  • 作業内容例:
    • リリースノート更新
    • バージョン番号更新 (__version__.py など)
    • 最終テスト、修正
  • PR作成:release/1.1.1/create-release-noterelease/1.1.x

Step 6. リリース確定

  • GitHub Release ページに正式リリースノートを公開
  • git タグを付与し,main ブランチにマージ

Step 7. main / develop への反映

# 本番用
git switch main
git merge --ff release/1.1.x
git push origin main

# 開発用
git switch develop
git merge --ff release/1.1.x
git push origin develop
Note運用ポイント
対象 ブランチ命名規則 用途・対象範囲 運用方針
小規模 Issue feature/<issue番号>-<タスク> 小規模な新機能・修正
develop に直接 PR
単一タスク・軽微修正に適用
中〜大規模 Issue issue/<issue番号> 複数サブタスクを統合 サブタスクを統合して develop に PR
feature / bugfix をまとめてレビュー
リリース系列ブランチ release/<major>.<minor>.x 特定マイナー系列(例: 1.1.x) 安定版維持・軽微修正対応
長寿命ブランチ.保守・検証に利用
リリース準備ブランチ release/<version>/<subtask> 各パッチリリース(例: 1.1.1) リリースノート作成・バージョン確定・PR作成など
短命ブランチ.完了後削除

4. ブランチ削除ポリシー

ブランチ種別 削除タイミング 備考
feature / bugfix / issue develop マージ後 即削除(必要ならタグで履歴追跡)
release/<version>/<subtask> main・develop 反映後 削除
release/<series>.x 次マイナー系列発足時 継続保守中は残す

5. 注意事項

ImportantRule 1: 小文字とハイフンを使用する
  • ブランチ名は常に小文字で記述
  • 大文字を含めると,ファイルシステムが大文字・小文字を区別する環境がある
  • 単語の区切りにはハイフン(-)を使用

📘 Example

  • ✅ Good: feature/user-login
  • ❌ Avoid: Feature_UserLogin, FeatUserLogin
ImportantRule 2: 明確なトークンからブランチ名を開始する
  • 各ブランチ名は、目的を示すカテゴリトークンから始めます。
  • トークンの例:
    • feature(新機能開発)
    • bugfix(バグ修正)
    • docs(ドキュメント更新)
  • トークンと説明文はスラッシュ(/)で区切る

📘 Example

  • ✅ Example: bugfix/payment-timeout
  • ❌ Avoid: payment-timeout (purpose unclear)

活用例

# Listing branches by token
$ git branch --list "feature/*"

# Pushing or mapping branches with tokens
$ git push origin 'refs/heads/feature/*'

# Deleting multiple branches by token
$ git branch -D $(git branch --list "feature/*")
ImportantRule 3: ブランチ名は簡潔・明確に
  • 意図を説明できる範囲で,長すぎる名前は避ける
  • 長すぎるブランチ名は,ログ表示の一行に収まらず,可視性が下がるため

📘 Example

  • ✅ 良い例: refactor/api-headers
  • ❌ 悪い例: refactor/update-the-way-we-handle-request-headers-in-api
ImportantRule 4: 衝突を生む可能性のあるブランチは作らない
  • git switch -c feature のように意図が不明瞭な名前や既存ブランチと衝突する可能性のある名前は避ける
  • Gitは内部的に ブランチ名をパス(ディレクトリ構造)として管理しているため,feature が作成されていると feature/login-v2 が名前衝突して作成できなくなってしまう
    • 同じ階層にファイルとディレクトリを同時に作れないため

📘 Example

$ git switch -c bugfix/0123/fix-login-error
Switched to a new branch 'bugfix/0123/fix-login-error'

$ ls .git/refs/heads/bugfix/0123
fix-login-error

Appendix: なぜbranchは名前衝突するのか?

Commit Object

Gitのコアの部分はシンプルなキー・バリュー型データストアです.Gitで追跡されているファイル(blob)はディレクトリの状態(ツリー)と合わせて圧縮された .git/objects にオブジェクトファイルとして保存されます. git commit を実行すると,commit時点でのその状態をスナップショットとして

  • 誰が(user.name, user.email)
  • いつ(現在のタイムスタンプ)
  • どんなメッセージを残して
  • どのcommitのあとに(=親コミット情報)
  • コミットが作成された時点のスナップショットのトップレベルのツリー

を記録します.これがコミットオブジェクトです.このコミットオブジェクトをvalueとすると,それに対応するSHA-1ハッシュ値がキーとなります.

.git/HEAD

    └─ ref: refs/heads/main

           └─ SHA-1 commit object (latest commit)

                  ├─ tree object
                  │     ├─ blob (file1)
                  │     └─ blob (file2)
                  └─ parent commit(s)

ブランチはポインター

各ブランチはブランチ自体が実体を持っているのではなく,どのcommit objectを参照しているか?で状態が管理されています.ここで登場するのが refs/heads/<branch-name> です. main ブランチが参照するCommit Objectは .git/refs/heads/main に記録されており

% cat .git/refs/heads/main
35f61422e59fb8b34bf3a85f82a71669c1eeec30

git add & git commit を実行すると,この値が新たなCommit Objectへの参照へと書き換わります.

なぜブランチは名前衝突するのか?

上記のようにブランチの情報は .git/refs/heads/<branch-name> で管理されています.git switch -c develop とすると

% git switch -c develop
Switched to a new branch 'develop'

% cat .git/refs/heads/develop
35f61422e59fb8b34bf3a85f82a71669c1eeec30

とファイルが生成されます.しかし,ブランチ名に / を含む場合だと

% git switch -c bugfix/0001/test
Switched to a new branch 'bugfix/0001/test'

% tree .git/refs/heads/
.git/refs/heads/
├── bugfix
   └── 0001
       └── test
├── develop
└── main

bugfix/0001/test/(スラッシュ)がディレクトリ区切りと解釈されてしまします.developブランチがある状態で develop/test を作成しようとすると, .git/refs/heads/develop/ ディレクトリを作成してから,その下に test ファイルを作成しようとしますが,すでにdevelop ファイルが存在する = 同姓同名のディレクトリを同じ層では作成できないという状態が発生します

そのため,

% git switch -c develop/test
fatal: cannot lock ref 'refs/heads/develop/test': 'refs/heads/develop' exists; cannot create 'refs/heads/develop/test'

というエラーが発生します.

References