#6 ブランチ命名規則を技術的に強制する - Python OSS開発記録
Git Flowでブランチ戦略を決めても、実際には命名規則がバラバラになりがち。
「あれ、このブランチどのルールで作ったんだっけ?」を技術的に防ぐ方法を実装します。
KEY TAKEAWAYS
この記事でわかること
- GitHub Rulesetsの "creation" ルールで命名パターンに合わないブランチ作成をブロック
- exclude条件で「許可するパターン」を定義(include: ~ALL + exclude: 許可パターン)
- コミュニケーションコスト削減: 命名ルール違反を指摘する手間が消える
用語の定義
TERM 01
Branch Naming Convention
ブランチ命名規則。Git Flowでは feature/、fix/
などのプレフィックスでブランチの種類を識別する。
TERM 02
Ref Name Conditions
GitHub Rulesetsで使う条件指定。include(対象)と
exclude(除外)でブランチ名パターンを制御。
TERM 03
Creation Rule
Rulesetsで「ブランチ作成」を制限するルール。条件に合わないブランチの作成を技術的にブロック。
TERM 04
~ALL
GitHub
Rulesetsの特殊パターン。「すべてのブランチ」を意味する。include: ["~ALL"] + exclude
で「これ以外禁止」を実現。
なぜ「人の注意」に頼ってはいけないのか
wagtail-reusable-blocks では、
Topic #4で決めたGit
Flowのブランチ戦略(feature/*、fix/*、hotfix/*、chore/*、docs/*)を強制する仕組みを入れました。
理由は単純。人間は忘れるし、間違える。
よくある問題1
feature/add-block ←
OKadd-block
← プレフィックスなし
よくある問題2
new-feature ← 適当な名前test ←
論外
結果
ブランチ一覧を見ても
何のブランチか分からない
解決策: GitHub Rulesetsの "creation" ルールで技術的にブロック。「CONTRIBUTING.mdに書いてあるから守ってね」ではなく、ルール違反のブランチは作れないようにする。
特にOSSでは、初めて参加する人がいきなりルールを完璧に守るのは難しい。GitHubで「そのブランチ名は作れません」と返せば、それで終わり。
「branch-naming」Rulesetの実装
命名規則違反をpushすると...
問題: 命名規則がバラバラになる
Git Flowを導入しても、実際には命名規則が守られないことがよくあります。
「ブランチ名、どうすればいいんだっけ?」と毎回CONTRIBUTINGを読み返すのは面倒だし、レビュー時に「ブランチ名がルールと違いますよ」とコメントするのもお互いに消耗します。
解決策: 技術的に制限する
GitHub Rulesetsの "creation" ルールを使えば、条件に合わないブランチは作成できないようにできます。
Topic #5で設定した「default」Rulesetはブランチ保護(削除禁止、force push禁止など)。
今回の「branch-naming」Rulesetはブランチ作成の制限です。
$ git checkout -b test-branch Switched to a new branch 'test-branch' $ git push -u origin test-branch remote: error: GH013: Repository rule violations found for refs/heads/test-branch. remote: remote: - RULE: branch-naming remote: Creation of this ref is not allowed. Only branches matching these patterns are allowed: remote: - refs/heads/main remote: - refs/heads/develop remote: - refs/heads/feature/* remote: - refs/heads/fix/* remote: - refs/heads/hotfix/* remote: - refs/heads/release/* remote: - refs/heads/chore/* remote: - refs/heads/docs/* remote: To github.com:kkm-horikawa/wagtail-reusable-blocks.git ! [remote rejected] test-branch -> test-branch (push declined due to repository rule violations) error: failed to push some refs
test-branch
という名前のブランチは作成できません。
許可されているパターン(feature/* など)に合わせる必要があります。
「branch-naming」Rulesetの全容
設定内容の詳細
wagtail-reusable-blocksの「branch-naming」Rulesetは、非常にシンプルです。
基本設定
- Target: Branch(ブランチ作成を対象)
- Enforcement: Active(有効)
- Rules: Creation(ブランチ作成ルール)
- Conditions: Ref Name(ブランチ名の条件)
Ref Name Conditionsの設定
include: ["~ALL"]
すべてのブランチを対象にする。
exclude: [許可するパターン]
以下のパターンを除外 = 許可する。
refs/heads/mainrefs/heads/developrefs/heads/feature/*refs/heads/fix/*refs/heads/hotfix/*refs/heads/release/*refs/heads/chore/*refs/heads/docs/*
「~ALL +
exclude」の意味:include: ["~ALL"] で「すべてのブランチ」を対象にし、
exclude で「これは例外(許可)」を指定。
つまり、excludeに入っていないパターンはすべてブロックされる。
{
"id": 10492190,
"name": "branch-naming",
"target": "branch",
"enforcement": "active",
"rules": [
{
"type": "creation"
}
],
"conditions": {
"ref_name": {
"include": ["~ALL"],
"exclude": [
"refs/heads/main",
"refs/heads/develop",
"refs/heads/feature/*",
"refs/heads/fix/*",
"refs/heads/hotfix/*",
"refs/heads/release/*",
"refs/heads/chore/*",
"refs/heads/docs/*"
]
}
},
"bypass_actors": []
}bypass_actors
について:
空配列 [] = 誰もバイパスできない。
Admin権限を持っていても、このルールは例外なく適用されます。
GitHub UIでの設定手順
ステップバイステップ
Step 1: Rulesetsページを開く
- リポジトリ → Settings
- 左サイドバー → Rules → Rulesets
- 「New ruleset」→「New branch ruleset」
Step 2: 基本情報を入力
入力項目:
- Ruleset Name:
branch-naming - Enforcement status: Active
- Bypass list: 空(誰もバイパスできない)
Bypass
listについて:
Admin権限を持つ人でもルールをバイパスできなくします。緊急時は一時的にRulesetを無効化する方が安全。
Step 3: ターゲットブランチを指定
Target branches:
- 「Add target」→ 「Include by pattern」
- Pattern:
~ALL - 「Add target」→ 「Exclude by pattern」
- Patterns:
main,develop,feature/**,fix/**,hotfix/**,release/**,chore/**,docs/**
UIとAPIのパターン表記の違い:
UI: feature/**(feature/ 配下すべて)
API: refs/heads/feature/*(ref形式で表記)
意味は同じです。UIの方が簡潔。
Step 4: ルールを選択
チェックする項目:
Step 5: 保存
「Create」ボタンを押して完了。
確認方法: 命名規則に合わないブランチをpushしてみる → エラーが出ればOK
OSS vs 企業プロジェクト: ブランチ命名規則の強制
OSS: 初めての人が迷わないために
OSSプロジェクトでは、初めてPRを送る人がたくさんいます。
その人たちに「ブランチ名はこのルールで」と伝えても、忘れることもあるし、間違えることもある。
技術的に制限すれば、間違えようがない。
「このブランチ名は使えません」とGitHubが教えてくれるので、レビュー時に指摘する手間も消える。
メリット
- コントリビューター側: ルールを完璧に覚えなくても大丈夫(間違えたらGitHubが教えてくれる)
- メンテナー側: 「ブランチ名が違いますよ」と指摘する手間がゼロ
- プロジェクト全体: ブランチ一覧が整理され、「何のブランチか」が一目で分かる
優しさの技術的実装:
「ルールを守ってね」と伝えるだけでは人間の記憶力に依存している。
技術的に制限することで、誰もが迷わず参加できる環境を作る。
企業: 「不安」から「安心」へ
Topic #4, #5で触れた「萎縮による開発効率の激減」問題は、ブランチ命名規則でも同じです。
新入社員や異動者が「どういうブランチ名で作ればいいの?」と質問するのは、不安だからです。
「間違えたら怒られる」「システムを壊すかもしれない」という恐怖が、質問を生みます。
従来の問題: 脅しと萎縮
- 「命名規則を守れ!間違えるな!」 ← 脅し
- 新人は萎縮: 「これで合ってるのかな?」と不安になる
- 質問の嵐: 毎回確認しないと怖い
- 教える側も消耗: 同じ説明を何度も繰り返す
- 開発効率が下がる: 日本の大企業に多い異常なスローペース
GitHub Rulesetsによる解決: システムで守る
システムでちゃんと防御してあげれば、できることは何やってもいい。
- 間違えたらGitHubが教えてくれる: 怒られるのではなく、システムが止めてくれる
- 「えい」ってやってみることができる: 間違えても大丈夫だから、試せる
- 質問が不要: 間違えたら自動で分かるので、いちいち確認しなくていい
- 経験値が溜まりやすい: 失敗を恐れずに試せる = 成長が早い
- 心理的安全性: 「これって合ってるのかな?」と不安にならない
安心して失敗できる環境:
これは教育の本質です(私が教育機関で働いていた経験から)。
失敗を恐れずに試せる環境こそが、人を育てます。
ブランチ命名規則を覚えられなくても大丈夫。間違えたらシステムが教えてくれる。
具体例: 命名規則違反のブランチを作ろうとすると
従来(脅しによる教育):
- 新人: 「test-branchって名前でいいのかな...?先輩に聞かなきゃ...」(不安)
- 先輩: 「ダメだよ!feature/をつけないと!」(指摘)
- 新人: 「また怒られた...」(萎縮)
- 結果: 毎回確認しないと怖い。開発効率が下がる。
GitHub Rulesets(システムによる防御):
- 新人: 「test-branchって名前でpushしてみよう」(試す)
- GitHub: 「エラー: feature/* などのパターンに合わせてください」(システムが止める)
- 新人: 「なるほど、feature/test-branchにすればいいのか」(学習)
- 結果: 失敗を恐れずに試せる。経験値が溜まる。
プロジェクト管理の責任
効果的なプロジェクト管理には、システムやツールに対する理解が重要です。
技術的な背景を持つマネージャーは、以下のような利点があります:
システムを活用した予防: ツールや自動化で問題を未然に防げる
効果的な意思決定: 技術的な制約や可能性を理解した上で判断できる
円滑なコミュニケーション: チームメンバーとの技術的な対話がスムーズになる
重要:
技術的制限は「面倒」に感じるかもしれません。
しかし、新規参画者の目線に立てば、これは最大の親切です。
不十分な説明で「間違えるな!」と脅されるより、システムで守られて安心して試せる方が、遥かに生産的です。
よくある質問と回答
FAQ
Q1: release/* ブランチも許可している理由は?
A: Topic #4で説明したGit
Flowでは、release/*
ブランチは使わないと決めました。でも、将来使うかもしれないので、許可リストには入れておきました。
Q2: Adminもバイパスできないのは厳しすぎない?
A: 緊急時はRulesetを一時的に「Disabled」に変更すればOK。誰もバイパスできないことで、「自分は例外」という意識を防げます。
Q3: ~ALL + exclude
ではなく、include
だけではダメ?
A: できません。Rulesetsの "creation"
ルールは「対象ブランチの作成を制限」するもの。「feature/* 以外の作成を制限」するには、~ALL +
exclude が必要です。
Q4: ローカルではブランチを作れるのに、pushすると弾かれるのはなぜ?
A:GitHub
Rulesetsはリモートリポジトリのルールだからです。ローカルでは好きな名前のブランチを作れますが、git
push した瞬間にGitHubがチェックします。


まだコメントはありません。最初のコメントを残しませんか?