fix(branching): capture decimal phase numbers in commit regex

The phase-extraction regex /(\d+)-/ only matched the last integer
segment before a dash, so decimal phases like 45.14 were misresolved
to phase 14 — silently switching to the wrong branch.

Closes #1402

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tibsfox
2026-03-26 19:42:19 -07:00
parent b5cbd47373
commit c1fd72f81f
2 changed files with 36 additions and 1 deletions

View File

@@ -255,7 +255,7 @@ function cmdCommit(cwd, message, files, raw, amend, noVerify) {
let branchName = null;
if (config.branching_strategy === 'phase') {
// Determine which phase we're committing for from the file paths
const phaseMatch = (files || []).join(' ').match(/(\d+)-/);
const phaseMatch = (files || []).join(' ').match(/(\d+(?:\.\d+)*)-/);
if (phaseMatch) {
const phaseNum = phaseMatch[1];
const phaseInfo = findPhaseInternal(cwd, phaseNum);

View File

@@ -1250,6 +1250,41 @@ describe('commit command', () => {
const branch = execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: tmpDir, encoding: 'utf-8' }).trim();
assert.strictEqual(branch, 'gsd/phase-01-setup', 'should be on phase branch');
});
test('decimal phase numbers are captured correctly in branching strategy', () => {
// Configure phase branching strategy
fs.writeFileSync(
path.join(tmpDir, '.planning', 'config.json'),
JSON.stringify({
commit_docs: true,
branching_strategy: 'phase',
phase_branch_template: 'gsd/phase-{phase}-{slug}',
})
);
// Create ROADMAP.md with a decimal phase
fs.mkdirSync(path.join(tmpDir, '.planning', 'phases', '45.14-golden-capture'), { recursive: true });
fs.writeFileSync(
path.join(tmpDir, '.planning', 'ROADMAP.md'),
'# Roadmap\n\n## Phase 45.14: Golden Capture\nGoal: Capture golden standard\n'
);
// Create a context file for phase 45.14
fs.writeFileSync(path.join(tmpDir, '.planning', 'phases', '45.14-golden-capture', '45.14-CONTEXT.md'), '# Context\n');
const result = runGsdTools(
'commit "docs(45.14): add context" --files .planning/phases/45.14-golden-capture/45.14-CONTEXT.md',
tmpDir
);
assert.ok(result.success, `Command failed: ${result.error}`);
const output = JSON.parse(result.output);
assert.strictEqual(output.committed, true, 'should have committed');
// Verify we're on the correct branch (45.14, not 14)
const { execFileSync } = require('child_process');
const branch = execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: tmpDir, encoding: 'utf-8' }).trim();
assert.strictEqual(branch, 'gsd/phase-45.14-golden-capture', 'should be on decimal phase branch, not integer-only');
});
});
// ─────────────────────────────────────────────────────────────────────────────