fix(state-matrix): detect reads the native diff, ignoring diff.external and textconv (review #3235 P1-4)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-17 01:22:58 +00:00
1 parent ea49e49d74
commit efccf00778
2 files changed
+11 -1

No files matched your search

+1 -1
View File
@@ -43,7 +43,7 @@ function detect(rest: string[]): number {
const repoRoot = root.out.trim();
const base = resolveBaseBranch(repoRoot, flag(rest, '--base'));
const mb = flag(rest, '--diff-base') ?? git(['merge-base', `origin/${base}`, 'HEAD'], repoRoot).out.trim();
const diff = mb ? git(['diff', '--unified=0', '--no-color', mb], repoRoot) : { ok: false, out: '' };
const diff = mb ? git(['-c', 'core.quotePath=false', 'diff', '--no-ext-diff', '--no-textconv', '--unified=0', '--no-color', mb], repoRoot) : { ok: false, out: '' };
if (!diff.ok) { process.stdout.write(`SCOPE_STATE_MACHINE=false\n# no merge base with origin/${base}; run: git fetch origin ${base}\n`); return EXIT.usage; }
const { detected, hits } = detectStateMachine(addedLines(diff.out));
const lines = [`SCOPE_STATE_MACHINE=${detected}`, ...hits.slice(0, 12).map(h => `# state-machine: ${h.file}:${h.line} ${[...h.subject, ...h.action].join(',')}`)];
+10
View File
@@ -47,6 +47,16 @@ describe('gstack-state-matrix detect', () => {
expect(d.out.trim().split('\n').every(l => /^SCOPE_STATE_MACHINE=(true|false)$/.test(l) || l.startsWith('# '))).toBe(true);
});
test('review #3235 P1-4: diff.external and a textconv driver cannot hide the state machine from detect', () => {
const r = repo();
r.git('config', 'diff.external', '/bin/true');
expect(run(r.work, ['detect', '--base', 'main']).out.split('\n')[0]).toBe('SCOPE_STATE_MACHINE=true');
r.git('config', '--unset', 'diff.external');
fs.writeFileSync(path.join(r.work, '.git', 'info', 'attributes'), '*.ts diff=blank\n');
r.git('config', 'diff.blank.textconv', 'true');
expect(run(r.work, ['detect', '--base', 'main']).out.split('\n')[0]).toBe('SCOPE_STATE_MACHINE=true');
});
test('negative controls: a test-only change and words that merely contain "hold" or "accept" do not dispatch', () => {
const r = repo();
r.git('checkout', '-q', '-b', 'unrelated', 'origin/main');