Skip to content

Commit 4f83308

Browse files
Copilotmnriem
andauthored
feat: create extensions/git with manifest, commands, scripts, and auto-install in init
Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> Agent-Logs-Url: https://github.com/github/spec-kit/sessions/809a1dbf-1301-4312-b4d2-e18f9b3e8b2f
1 parent e9c464d commit 4f83308

File tree

13 files changed

+1122
-1
lines changed

13 files changed

+1122
-1
lines changed

extensions/git/README.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Git Branching Workflow Extension
2+
3+
Feature branch creation, numbering (sequential/timestamp), validation, and Git remote detection for Spec Kit.
4+
5+
## Overview
6+
7+
This extension provides Git branching operations as an optional, self-contained module. It manages:
8+
9+
- **Feature branch creation** with sequential (`001-feature-name`) or timestamp (`20260319-143022-feature-name`) numbering
10+
- **Branch validation** to ensure branches follow naming conventions
11+
- **Git remote detection** for GitHub integration (e.g., issue creation)
12+
13+
## Commands
14+
15+
| Command | Description |
16+
|---------|-------------|
17+
| `speckit.git.feature` | Create a feature branch with sequential or timestamp numbering |
18+
| `speckit.git.validate` | Validate current branch follows feature branch naming conventions |
19+
| `speckit.git.remote` | Detect Git remote URL for GitHub integration |
20+
21+
## Hooks
22+
23+
| Event | Command | Optional | Description |
24+
|-------|---------|----------|-------------|
25+
| `before_specify` | `speckit.git.feature` | No | Create feature branch before specification |
26+
| `after_implement` | `speckit.git.validate` | Yes | Validate branch naming after implementation |
27+
28+
## Configuration
29+
30+
Configuration is stored in `.specify/extensions/git/git-config.yml`:
31+
32+
```yaml
33+
# Branch numbering strategy: "sequential" or "timestamp"
34+
branch_numbering: sequential
35+
36+
# Branch name template
37+
branch_template: "{number}-{short_name}"
38+
39+
# Whether to fetch remotes before computing next branch number
40+
auto_fetch: true
41+
```
42+
43+
### Environment Variable Override
44+
45+
Set `SPECKIT_GIT_BRANCH_NUMBERING` to override the `branch_numbering` config value:
46+
47+
```bash
48+
export SPECKIT_GIT_BRANCH_NUMBERING=timestamp
49+
```
50+
51+
## Installation
52+
53+
```bash
54+
# Install from the bundled extension
55+
specify extension add git --from extensions/git/
56+
57+
# Or it auto-installs during specify init (migration period)
58+
```
59+
60+
## Disabling
61+
62+
```bash
63+
# Disable the git extension (spec creation continues without branching)
64+
specify extension disable git
65+
66+
# Re-enable it
67+
specify extension enable git
68+
```
69+
70+
## Graceful Degradation
71+
72+
When Git is not installed or the directory is not a Git repository:
73+
- Spec directories are still created under `specs/`
74+
- Branch creation is skipped with a warning
75+
- Branch validation is skipped with a warning
76+
- Remote detection returns empty results
77+
78+
## Scripts
79+
80+
The extension bundles cross-platform scripts:
81+
82+
- `scripts/bash/create-new-feature.sh` — Bash implementation
83+
- `scripts/bash/git-common.sh` — Shared Git utilities (Bash)
84+
- `scripts/powershell/create-new-feature.ps1` — PowerShell implementation
85+
- `scripts/powershell/git-common.ps1` — Shared Git utilities (PowerShell)
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
description: "Create a feature branch with sequential or timestamp numbering"
3+
---
4+
5+
# Create Feature Branch
6+
7+
Create a new feature branch for the given specification.
8+
9+
## User Input
10+
11+
```text
12+
$ARGUMENTS
13+
```
14+
15+
You **MUST** consider the user input before proceeding (if not empty).
16+
17+
## Prerequisites
18+
19+
- Verify Git is available by running `git rev-parse --is-inside-work-tree 2>/dev/null`
20+
- If Git is not available, warn the user and skip branch creation (spec directory will still be created)
21+
22+
## Branch Numbering Mode
23+
24+
Determine the branch numbering strategy by checking configuration in this order:
25+
26+
1. Check `.specify/extensions/git/git-config.yml` for `branch_numbering` value
27+
2. Check `.specify/init-options.json` for `branch_numbering` value (backward compatibility)
28+
3. Default to `sequential` if neither exists
29+
30+
## Execution
31+
32+
Generate a concise short name (2-4 words) for the branch:
33+
- Analyze the feature description and extract the most meaningful keywords
34+
- Use action-noun format when possible (e.g., "add-user-auth", "fix-payment-bug")
35+
- Preserve technical terms and acronyms (OAuth2, API, JWT, etc.)
36+
37+
Run the appropriate script based on your platform:
38+
39+
- **Bash**: `.specify/extensions/git/scripts/bash/create-new-feature.sh --json --short-name "<short-name>" "<feature description>"`
40+
- **Bash (timestamp)**: `.specify/extensions/git/scripts/bash/create-new-feature.sh --json --timestamp --short-name "<short-name>" "<feature description>"`
41+
- **PowerShell**: `.specify/extensions/git/scripts/powershell/create-new-feature.ps1 -Json -ShortName "<short-name>" "<feature description>"`
42+
- **PowerShell (timestamp)**: `.specify/extensions/git/scripts/powershell/create-new-feature.ps1 -Json -Timestamp -ShortName "<short-name>" "<feature description>"`
43+
44+
**IMPORTANT**:
45+
- Do NOT pass `--number` — the script determines the correct next number automatically
46+
- Always include the JSON flag (`--json` for Bash, `-Json` for PowerShell) so the output can be parsed reliably
47+
- You must only ever run this script once per feature
48+
- The JSON output will contain BRANCH_NAME and SPEC_FILE paths
49+
50+
If the extension scripts are not found at the `.specify/extensions/git/` path, fall back to:
51+
- **Bash**: `scripts/bash/create-new-feature.sh`
52+
- **PowerShell**: `scripts/powershell/create-new-feature.ps1`
53+
54+
## Graceful Degradation
55+
56+
If Git is not installed or the current directory is not a Git repository:
57+
- The script will still create the spec directory under `specs/`
58+
- A warning will be printed: `[specify] Warning: Git repository not detected; skipped branch creation`
59+
- The workflow continues normally without branch creation
60+
61+
## Output
62+
63+
The script outputs JSON with:
64+
- `BRANCH_NAME`: The created branch name (e.g., `003-user-auth` or `20260319-143022-user-auth`)
65+
- `SPEC_FILE`: Path to the created spec file
66+
- `FEATURE_NUM`: The numeric or timestamp prefix used
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
description: "Detect Git remote URL for GitHub integration"
3+
---
4+
5+
# Detect Git Remote URL
6+
7+
Detect the Git remote URL for integration with GitHub services (e.g., issue creation).
8+
9+
## Prerequisites
10+
11+
- Check if Git is available by running `git rev-parse --is-inside-work-tree 2>/dev/null`
12+
- If Git is not available, output a warning and return empty:
13+
```
14+
[specify] Warning: Git repository not detected; cannot determine remote URL
15+
```
16+
17+
## Execution
18+
19+
Run the following command to get the remote URL:
20+
21+
```bash
22+
git config --get remote.origin.url
23+
```
24+
25+
## Output
26+
27+
Parse the remote URL and determine:
28+
29+
1. **Repository owner**: Extract from the URL (e.g., `github` from `https://github.com/github/spec-kit.git`)
30+
2. **Repository name**: Extract from the URL (e.g., `spec-kit` from `https://github.com/github/spec-kit.git`)
31+
3. **Is GitHub**: Whether the remote points to a GitHub repository
32+
33+
Supported URL formats:
34+
- HTTPS: `https://github.com/<owner>/<repo>.git`
35+
- SSH: `git@github.com:<owner>/<repo>.git`
36+
37+
> [!CAUTION]
38+
> ONLY report a GitHub repository if the remote URL actually points to github.com.
39+
> Do NOT assume the remote is GitHub if the URL format doesn't match.
40+
41+
## Graceful Degradation
42+
43+
If Git is not installed, the directory is not a Git repository, or no remote is configured:
44+
- Return an empty result
45+
- Do NOT error — other workflows should continue without Git remote information
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
description: "Validate current branch follows feature branch naming conventions"
3+
---
4+
5+
# Validate Feature Branch
6+
7+
Validate that the current Git branch follows the expected feature branch naming conventions.
8+
9+
## Prerequisites
10+
11+
- Check if Git is available by running `git rev-parse --is-inside-work-tree 2>/dev/null`
12+
- If Git is not available, output a warning and skip validation:
13+
```
14+
[specify] Warning: Git repository not detected; skipped branch validation
15+
```
16+
17+
## Validation Rules
18+
19+
Get the current branch name:
20+
21+
```bash
22+
git rev-parse --abbrev-ref HEAD
23+
```
24+
25+
The branch name must match one of these patterns:
26+
27+
1. **Sequential**: `^[0-9]{3}-` (e.g., `001-feature-name`, `042-fix-bug`)
28+
2. **Timestamp**: `^[0-9]{8}-[0-9]{6}-` (e.g., `20260319-143022-feature-name`)
29+
30+
## Execution
31+
32+
If on a feature branch (matches either pattern):
33+
- Output: `✓ On feature branch: <branch-name>`
34+
- Check if the corresponding spec directory exists under `specs/`:
35+
- For sequential branches, look for `specs/<prefix>-*` where prefix matches the `###` portion
36+
- For timestamp branches, look for `specs/<prefix>-*` where prefix matches the `YYYYMMDD-HHMMSS` portion
37+
- If spec directory exists: `✓ Spec directory found: <path>`
38+
- If spec directory missing: `⚠ No spec directory found for prefix <prefix>`
39+
40+
If NOT on a feature branch:
41+
- Output: `✗ Not on a feature branch. Current branch: <branch-name>`
42+
- Output: `Feature branches should be named like: 001-feature-name or 20260319-143022-feature-name`
43+
44+
## Graceful Degradation
45+
46+
If Git is not installed or the directory is not a Git repository:
47+
- Check the `SPECIFY_FEATURE` environment variable as a fallback
48+
- If set, validate that value against the naming patterns
49+
- If not set, skip validation with a warning

extensions/git/config-template.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Git Branching Workflow Extension Configuration
2+
# Copy this file to .specify/extensions/git/git-config.yml to customize
3+
4+
# Branch numbering strategy: "sequential" (001, 002, ...) or "timestamp" (YYYYMMDD-HHMMSS)
5+
branch_numbering: sequential
6+
7+
# Branch name template (used with sequential numbering)
8+
# Available placeholders: {number}, {short_name}
9+
branch_template: "{number}-{short_name}"
10+
11+
# Whether to run `git fetch --all --prune` before computing the next branch number
12+
auto_fetch: true

extensions/git/extension.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
schema_version: "1.0"
2+
3+
extension:
4+
id: git
5+
name: "Git Branching Workflow"
6+
version: "1.0.0"
7+
description: "Feature branch creation, numbering (sequential/timestamp), validation, and Git remote detection"
8+
author: spec-kit-core
9+
repository: https://github.com/github/spec-kit
10+
license: MIT
11+
12+
requires:
13+
speckit_version: ">=0.2.0"
14+
tools:
15+
- name: git
16+
required: false
17+
18+
provides:
19+
commands:
20+
- name: speckit.git.feature
21+
file: commands/speckit.git.feature.md
22+
description: "Create a feature branch with sequential or timestamp numbering"
23+
- name: speckit.git.validate
24+
file: commands/speckit.git.validate.md
25+
description: "Validate current branch follows feature branch naming conventions"
26+
- name: speckit.git.remote
27+
file: commands/speckit.git.remote.md
28+
description: "Detect Git remote URL for GitHub integration"
29+
30+
hooks:
31+
before_specify:
32+
command: speckit.git.feature
33+
optional: false
34+
description: "Create feature branch before specification"
35+
after_implement:
36+
command: speckit.git.validate
37+
optional: true
38+
prompt: "Verify feature branch naming?"
39+
description: "Validate branch naming after implementation"
40+
41+
tags:
42+
- "git"
43+
- "branching"
44+
- "workflow"
45+
46+
defaults:
47+
branch_numbering: sequential
48+
branch_template: "{number}-{short_name}"
49+
auto_fetch: true

0 commit comments

Comments
 (0)