From ec2c4f2a42ddff833274056a6e709e56c98f1b22 Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Sat, 19 Sep 2026 15:18:57 +0800 Subject: [PATCH] test(session): isolate vocabulary fixture Git commands from caller paths The new vocabulary fixture helper set cwd to a private repository but still inherited GIT_DIR, GIT_WORK_TREE and GIT_INDEX_FILE. A negative control with two disposable repositories demonstrated that git add/commit changed the foreign repository's HEAD instead of the intended fixture repository. Remove only those three location variables from the child environment. Leave the caller's environment untouched and retain the existing identity, hook and signing overrides. The regression checks the foreign HEAD and work tree remain unchanged while the intended target commits its private file. This is confined to the test helper; it adds no production Git abstraction or Session-format behavior. --- scripts/verify-v3-event-vocabulary.spec.ts | 26 ++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/scripts/verify-v3-event-vocabulary.spec.ts b/scripts/verify-v3-event-vocabulary.spec.ts index c322a97b1f..fbac2d0439 100644 --- a/scripts/verify-v3-event-vocabulary.spec.ts +++ b/scripts/verify-v3-event-vocabulary.spec.ts @@ -17,11 +17,13 @@ function write(root: string, path: string, content: string): void { writeFileSync(target, content) } -function git(root: string, args: readonly string[]): string { +function git(root: string, args: readonly string[], environment: NodeJS.ProcessEnv = process.env): string { + const env = Object.fromEntries(Object.entries(environment).filter(([key]) => + !['GIT_DIR', 'GIT_WORK_TREE', 'GIT_INDEX_FILE'].includes(key.toUpperCase()))) return execFileSync('git', [ '-c', 'user.name=V3 vocabulary fixture', '-c', 'user.email=v3-fixture@example.invalid', '-c', 'commit.gpgsign=false', '-c', `core.hooksPath=${join(root, 'empty-hooks')}`, ...args, - ], { cwd: root, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim() + ], { cwd: root, env, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim() } function fixture(options: { writer?: string; events?: string } = {}): { root: string; sourceRef: string } { @@ -40,6 +42,26 @@ afterEach(() => { }) describe('explicit V3 source vocabulary verification', () => { + it('keeps fixture writes inside their own repository despite inherited Git location variables', () => { + const target = fixture() + const foreign = fixture() + write(target.root, 'target-only.txt', 'target') + write(foreign.root, 'foreign-only.txt', 'foreign') + const before = git(foreign.root, ['status', '--porcelain']) + const environment = { + ...process.env, + GIT_DIR: join(foreign.root, '.git'), + GIT_WORK_TREE: foreign.root, + GIT_INDEX_FILE: join(foreign.root, '.git', 'foreign-index'), + } + git(target.root, ['add', '--all'], environment) + git(target.root, ['commit', '--quiet', '-m', 'Target fixture update'], environment) + expect(git(foreign.root, ['rev-parse', 'HEAD'])).toBe(foreign.sourceRef) + expect(git(foreign.root, ['status', '--porcelain'])).toBe(before) + expect(git(target.root, ['show', 'HEAD:target-only.txt'])).toBe('target') + expect(environment.GIT_DIR).toBe(join(foreign.root, '.git')) + }) + it('checks a pinned V3 writer independently of later V4 commits', () => { const { root, sourceRef } = fixture() write(root, writerPath, 'export const SESSION_FORMAT_VERSION = 4 as const\n')