Skip to content

Support namespaced git feature branch templates#3293

Open
PascalThuet wants to merge 6 commits into
github:mainfrom
PascalThuet:feat/3081-monorepo-branch-template
Open

Support namespaced git feature branch templates#3293
PascalThuet wants to merge 6 commits into
github:mainfrom
PascalThuet:feat/3081-monorepo-branch-template

Conversation

@PascalThuet

@PascalThuet PascalThuet commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds git extension branch_template config with {author}, {app}, {number}, and {slug} tokens, plus branch_prefix as a shorthand namespace.
  • Applies templates in both Bash and PowerShell feature-branch scripts while preserving the default {number}-{slug} branch shape.
  • Makes feature number extraction, branch-number scanning, and validation tolerant of path-style branch namespaces without confusing numeric namespace segments for feature numbers.

Why

Monorepo installs can have separate Spec Kit projects but one shared root Git branch namespace. This lets projects opt into names like jdoe/app-a/008-guided-tour without requiring separate Git repositories or changing downstream feature path resolution.

Fixes #3081.

Issue context

The implementation follows the concrete monorepo use case described in #3081 (comment). That comment is relevant because it identifies the target branch shape ({author}/{app}/{number}-{slug}) and points out that downstream commands already resolve feature directories through .specify/feature.json / SPECIFY_FEATURE_DIRECTORY, so branch creation and validation are the important places to make namespace-aware.

TDD sequence

  • dbe9203 adds failing coverage for branch templates, branch-prefix shorthand, namespace-scoped numbering, namespaced GIT_BRANCH_NAME extraction, and nested-prefix validation.
  • f48178d implements the first pass that makes those tests pass.
  • ee0574b adds failing edge-case coverage for numeric namespace segments, templates missing {number}, namespaced GIT_BRANCH_NAME, and validation false positives.
  • 7a2a8b2 hardens parsing/validation and updates config discoverability so those edge cases pass.
  • 8c5f2d7 addresses Copilot review feedback and the follow-up local review findings: branch_prefix help text, GIT_BRANCH_NAME fallback behavior, final-segment template validation, validation docs, config comments, and Bash UTF-8 byte reporting.

Validation

  • Red check after dbe9203: 5 targeted tests failed as expected.
  • Red check after ee0574b: 4 targeted tests failed as expected.
  • Red check before 8c5f2d7: 4 targeted Bash tests failed as expected.
  • Green check after 8c5f2d7: .venv/bin/python -m pytest tests/extensions/git/test_git_extension.py tests/test_timestamp_branches.py -q
  • Result: 113 passed, 50 skipped.
  • Additional local checks after 8c5f2d7: bash -n extensions/git/scripts/bash/create-new-feature-branch.sh extensions/git/scripts/bash/git-common.sh, git diff --check origin/main...HEAD, and uvx ruff check tests/extensions/git/test_git_extension.py.

Disclosure

Prepared on behalf of @PascalThuet by Codex (model: GPT-5, autonomous). Each commit includes an Assisted-by: trailer.

@mnriem

mnriem commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

I realize this still a draft, but I wanted to make sure that you should merge the template into the git-config.yml for ease of use

Assisted-by: Codex (model: GPT-5, autonomous)
Assisted-by: Codex (model: GPT-5, autonomous)
@PascalThuet PascalThuet force-pushed the feat/3081-monorepo-branch-template branch from 995f4cc to f48178d Compare July 1, 2026 21:32
@PascalThuet PascalThuet changed the title Add configurable git branch templates for monorepos Support namespaced git feature branch templates Jul 1, 2026
@PascalThuet

Copy link
Copy Markdown
Contributor Author

Thanks, done in the latest push. branch_template is now included in both git-config.yml and config-template.yml.

It defaults to "", which preserves the existing {number}-{slug} behavior. Users can set it to {author}/{app}/{number}-{slug} for monorepo-style branch names.

Assisted-by: Codex (model: GPT-5, autonomous)
Assisted-by: Codex (model: GPT-5, autonomous)
@PascalThuet

Copy link
Copy Markdown
Contributor Author

Posted on behalf of @PascalThuet by Codex (model: GPT-5, autonomous).

Updated the draft PR after a local code review pass:

  • Added edge-case tests in ee0574b for numeric namespace segments, templates missing {number}, namespaced GIT_BRANCH_NAME, and validation false positives.
  • Fixed those cases in 7a2a8b2 by extracting feature numbers from the feature segment instead of arbitrary numeric namespace segments, requiring {number} in custom templates, and making branch_prefix visible in the default config.
  • Re-ran .venv/bin/python -m pytest tests/extensions/git/test_git_extension.py tests/test_timestamp_branches.py -q: 109 passed, 47 skipped.

@mnriem

mnriem commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

I triggered a Copilot review and a test & lint cycle so you can see where you are at from that perspective

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for namespaced/templated feature-branch names in the Git extension so monorepo projects can share a single Git branch namespace while keeping per-project feature numbering intact.

Changes:

  • Introduces branch_template and branch_prefix config options to render namespaced branch names (Bash + PowerShell).
  • Updates branch-number scanning and feature-branch validation to treat the feature marker as the final path segment (after /).
  • Adds/extends test coverage for templates, namespace-scoped numbering, and nested-prefix validation.
Show a summary per file
File Description
tests/extensions/git/test_git_extension.py Adds coverage for branch templates/prefixes, namespace-scoped numbering, and namespaced validation across Bash/PowerShell.
extensions/git/scripts/bash/create-new-feature-branch.sh Applies branch_template / branch_prefix for branch rendering and namespace-scoped number scanning; adjusts truncation behavior.
extensions/git/scripts/powershell/create-new-feature-branch.ps1 PowerShell parity for template/prefix rendering, scoped numbering, and UTF-8 byte-limit truncation.
extensions/git/scripts/bash/git-common.sh Updates feature-branch validation to accept path-style namespaces by validating only the final segment.
extensions/git/scripts/powershell/git-common.ps1 Mirrors Bash validation changes for namespaced branches (final-segment matching).
extensions/git/README.md Documents new template/prefix configuration and intended monorepo branch shapes.
extensions/git/git-config.yml Adds branch_template / branch_prefix to the extension’s default config.
extensions/git/config-template.yml Adds template/prefix keys to the user-facing config template.
extensions/git/extension.yml Updates extension metadata + default config values for new keys.
extensions/git/commands/speckit.git.feature.md Documents template/prefix behavior and namespaced GIT_BRANCH_NAME extraction semantics.
extensions/git/commands/speckit.git.validate.md Updates validation docs for namespaced feature markers.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comments suppressed due to low confidence (1)

extensions/git/scripts/bash/create-new-feature-branch.sh:529

  • These log lines label the counts as "bytes" but use Bash string length (${#...}), which is character-count under most locales and can be wrong for UTF-8. Since the limit check uses _byte_length, the reporting should too.
    >&2 echo "[specify] Warning: Branch name exceeded GitHub's 244-byte limit"
    >&2 echo "[specify] Original: $ORIGINAL_BRANCH_NAME (${#ORIGINAL_BRANCH_NAME} bytes)"
    >&2 echo "[specify] Truncated to: $BRANCH_NAME (${#BRANCH_NAME} bytes)"
  • Files reviewed: 11/11 changed files
  • Comments generated: 4
  • Review effort level: Low

Comment thread extensions/git/scripts/bash/create-new-feature-branch.sh
Comment thread extensions/git/scripts/bash/create-new-feature-branch.sh
Comment thread extensions/git/scripts/powershell/create-new-feature-branch.ps1
Comment thread extensions/git/commands/speckit.git.validate.md Outdated
Address Copilot review feedback for branch_prefix help text, namespaced GIT_BRANCH_NAME fallback behavior, final-segment validation docs, and Bash UTF-8 byte reporting.

Assisted-by: Codex (model: GPT-5, autonomous)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 11/11 changed files
  • Comments generated: 1
  • Review effort level: Low

Comment thread extensions/git/scripts/bash/create-new-feature-branch.sh
Reject branch templates that place {slug} before {number}, because that makes namespace scanning depend on the generated feature slug and can reset numbering per feature name.

Assisted-by: Codex (model: GPT-5, autonomous)
@PascalThuet PascalThuet marked this pull request as ready for review July 2, 2026 17:03
@PascalThuet PascalThuet requested a review from mnriem as a code owner July 2, 2026 17:03
@mnriem mnriem requested a review from Copilot July 2, 2026 17:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 11/11 changed files
  • Comments generated: 3
  • Review effort level: Low

Comment on lines 151 to +152
if echo "$name" | grep -Eq '^[0-9]{3,}-' && ! echo "$name" | grep -Eq '^[0-9]{8}-[0-9]{6}-'; then
number=$(echo "$name" | grep -Eo '^[0-9]+' || echo "0")
number=$(echo "$name" | grep -Eo '^[0-9]{3,}-' | sed -E 's/-$//' || echo "0")
$name = $name.Substring($ScopePrefix.Length)
}
$name = ($name -split '/')[-1]
if ($name -match '^(\d{3,})-' -and $name -notmatch '^\d{8}-\d{6}-') {
# Accepts sequential (###-* with >=3 digits) or timestamp (YYYYMMDD-HHMMSS-*) formats.
# Accepts sequential (###-* with >=3 digits) or timestamp (YYYYMMDD-HHMMSS-*) formats,
# either at the start of the branch or after path-style namespace prefixes.
# Logic aligned with scripts/bash/common.sh check_feature_branch after effective-name normalization.
@mnriem

mnriem commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Please address Copilot feedback

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Monorepo: feature branches share the root repo's branch namespace (no per-project Git scoping)

3 participants