Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion extensions/git/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Git repository initialization, feature branch creation, numbering (sequential/ti
This extension provides Git operations as an optional, self-contained module. It manages:

- **Repository initialization** with configurable commit messages
- **Feature branch creation** with sequential (`001-feature-name`) or timestamp (`20260319-143022-feature-name`) numbering
- **Feature branch creation** with sequential (`001-feature-name`) or timestamp (`20260319-143022-feature-name`) numbering and optional templates for branch namespaces
- **Branch validation** to ensure branches follow naming conventions
- **Git remote detection** for GitHub integration (e.g., issue creation)
- **Auto-commit** after core commands (configurable per-command with custom messages)
Expand Down Expand Up @@ -53,6 +53,11 @@ Configuration is stored in `.specify/extensions/git/git-config.yml`:
# Branch numbering strategy: "sequential" or "timestamp"
branch_numbering: sequential

# Optional branch name template. Leave empty for the default "{number}-{slug}".
# Supported tokens: {author}, {app}, {number}, {slug}
# Example for monorepos: "{author}/{app}/{number}-{slug}"
branch_template: ""

# Custom commit message for git init
init_commit_message: "[Spec Kit] Initial commit"

Expand All @@ -65,6 +70,10 @@ auto_commit:
message: "[Spec Kit] Add specification"
```

`{author}` is derived from Git config and sanitized for branch names. `{app}` is derived from the Spec Kit init directory name. For a monorepo project at `apps/web/.specify/`, a template such as `{author}/{app}/{number}-{slug}` produces branches like `jdoe/web/008-guided-tour`.

For simple namespace-only customization, `branch_prefix` is also accepted as a shorthand and expands to `<branch_prefix>/{number}-{slug}`.

## Installation

```bash
Expand Down
18 changes: 16 additions & 2 deletions extensions/git/commands/speckit.git.feature.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ You **MUST** consider the user input before proceeding (if not empty).
If the user explicitly provided `GIT_BRANCH_NAME` (e.g., via environment variable, argument, or in their request), pass it through to the script by setting the `GIT_BRANCH_NAME` environment variable before invoking the script. When `GIT_BRANCH_NAME` is set:
- The script uses the exact value as the branch name, bypassing all prefix/suffix generation
- `--short-name`, `--number`, and `--timestamp` flags are ignored
- `FEATURE_NUM` is extracted from the name if it starts with a numeric prefix, otherwise set to the full branch name
- `FEATURE_NUM` is extracted from the first numeric or timestamp segment (for example `042-name`, `feat/042-name`, or `jdoe/app/042-name`), otherwise set to the full branch name

## Prerequisites

Expand All @@ -35,6 +35,19 @@ Determine the branch numbering strategy by checking configuration in this order:
3. Check `.specify/init-options.json` for `branch_numbering` value (deprecated, backward compatibility — will be removed in a future release)
4. Default to `sequential` if none of the above exist

## Branch Name Template

Check `.specify/extensions/git/git-config.yml` for an optional `branch_template` value. If it is empty or missing, use the default branch shape `{number}-{slug}`. If it is set, the script expands these tokens:

- `{author}`: sanitized Git config author (`user.name`, falling back to the email local part)
- `{app}`: sanitized Spec Kit init directory name
- `{number}`: sequential number or timestamp
- `{slug}`: generated short branch slug

For monorepos, a template such as `{author}/{app}/{number}-{slug}` creates names like `jdoe/web/008-guided-tour` while preserving per-project feature numbering.

The script also accepts `branch_prefix` as a shorthand for simple namespaces; it expands to `<branch_prefix>/{number}-{slug}`.

## Execution

Generate a concise short name (2-4 words) for the branch:
Expand All @@ -54,6 +67,7 @@ Run the appropriate script based on your platform:
- Always include the JSON flag (`--json` for Bash, `-Json` for PowerShell) so the output can be parsed reliably
- You must only ever run this script once per feature
- The JSON output will contain `BRANCH_NAME` and `FEATURE_NUM`
- Do not manually expand `branch_template`; the script reads the git extension config and applies it consistently

## Graceful Degradation

Expand All @@ -64,5 +78,5 @@ If Git is not installed or the current directory is not a Git repository:
## Output

The script outputs JSON with:
- `BRANCH_NAME`: The branch name (e.g., `003-user-auth` or `20260319-143022-user-auth`)
- `BRANCH_NAME`: The branch name (e.g., `003-user-auth`, `20260319-143022-user-auth`, or `jdoe/web/003-user-auth`)
- `FEATURE_NUM`: The numeric or timestamp prefix used
12 changes: 6 additions & 6 deletions extensions/git/commands/speckit.git.validate.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,24 @@ Get the current branch name:
git rev-parse --abbrev-ref HEAD
```

The branch name must match one of these patterns:
The branch name must contain one of these feature markers either at the start or after one or more namespace path segments:

1. **Sequential**: `^[0-9]{3,}-` (e.g., `001-feature-name`, `042-fix-bug`, `1000-big-feature`)
2. **Timestamp**: `^[0-9]{8}-[0-9]{6}-` (e.g., `20260319-143022-feature-name`)
1. **Sequential**: `(^|/)[0-9]{3,}-` (e.g., `001-feature-name`, `042-fix-bug`, `1000-big-feature`, `jdoe/web/008-guided-tour`)
2. **Timestamp**: `(^|/)[0-9]{8}-[0-9]{6}-` (e.g., `20260319-143022-feature-name`, `jdoe/web/20260319-143022-feature-name`)

## Execution

If on a feature branch (matches either pattern):
- Output: `✓ On feature branch: <branch-name>`
- Check if the corresponding spec directory exists under `specs/`:
- For sequential branches, look for `specs/<prefix>-*` where prefix matches the numeric portion
- For timestamp branches, look for `specs/<prefix>-*` where prefix matches the `YYYYMMDD-HHMMSS` portion
- For sequential branches, look for `specs/<prefix>-*` where prefix matches the numeric portion, regardless of branch namespace prefixes
- For timestamp branches, look for `specs/<prefix>-*` where prefix matches the `YYYYMMDD-HHMMSS` portion, regardless of branch namespace prefixes
- If spec directory exists: `✓ Spec directory found: <path>`
- If spec directory missing: `⚠ No spec directory found for prefix <prefix>`

If NOT on a feature branch:
- Output: `✗ Not on a feature branch. Current branch: <branch-name>`
- Output: `Feature branches should be named like: 001-feature-name or 20260319-143022-feature-name`
- Output: `Feature branches should be named like: 001-feature-name, 20260319-143022-feature-name, or <namespace>/001-feature-name`

## Graceful Degradation

Expand Down
5 changes: 5 additions & 0 deletions extensions/git/config-template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
# Branch numbering strategy: "sequential" (001, 002, ...) or "timestamp" (YYYYMMDD-HHMMSS)
branch_numbering: sequential

# Optional branch name template. Leave empty for the default "{number}-{slug}".
# Supported tokens: {author}, {app}, {number}, {slug}
# Example for monorepos: "{author}/{app}/{number}-{slug}"
branch_template: ""

# Commit message used by `git commit` during repository initialization
init_commit_message: "[Spec Kit] Initial commit"

Expand Down
5 changes: 3 additions & 2 deletions extensions/git/extension.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ extension:
id: git
name: "Git Branching Workflow"
version: "1.0.0"
description: "Feature branch creation, numbering (sequential/timestamp), validation, and Git remote detection"
description: "Feature branch creation, numbering (sequential/timestamp), templating, validation, and Git remote detection"
author: spec-kit-core
repository: https://github.com/github/spec-kit
license: MIT
Expand All @@ -19,7 +19,7 @@ provides:
commands:
- name: speckit.git.feature
file: commands/speckit.git.feature.md
description: "Create a feature branch with sequential or timestamp numbering"
description: "Create a feature branch with sequential or timestamp numbering and optional templates"
- name: speckit.git.validate
file: commands/speckit.git.validate.md
description: "Validate current branch follows feature branch naming conventions"
Expand Down Expand Up @@ -137,4 +137,5 @@ tags:
config:
defaults:
branch_numbering: sequential
branch_template: ""
init_commit_message: "[Spec Kit] Initial commit"
5 changes: 5 additions & 0 deletions extensions/git/git-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
# Branch numbering strategy: "sequential" (001, 002, ...) or "timestamp" (YYYYMMDD-HHMMSS)
branch_numbering: sequential

# Optional branch name template. Leave empty for the default "{number}-{slug}".
# Supported tokens: {author}, {app}, {number}, {slug}
# Example for monorepos: "{author}/{app}/{number}-{slug}"
branch_template: ""

# Commit message used by `git commit` during repository initialization
init_commit_message: "[Spec Kit] Initial commit"

Expand Down
Loading