fix(FN-5345): address second-pass review findings
Follow-up to 8e6740468 addressing six review findings, including one real
regression (combined short flags bypass amend detection).
HIGH
- Combined short flags ('-am', '-vm', '-sm', '-aF', ...) now count as
message-supplying tokens in the prepare-commit-msg empty-commit guard.
Previously, an agent could bypass the guard with
git commit --allow-empty -am 'fix --amend handling'
because '-am' did not match the literal '-m' case, so the token loop
continued past the message text and matched the '--amend' substring inside
it. The new pattern -[!-]*[mF]* matches any short combined flag containing
'm' or 'F' while leaving '--amend' (starts with '--') untouched.
Verified locally with two regression tests for '-am' and '-vm' plus one
positive test confirming legitimate '-am' with a real tracked modification
still succeeds.
MEDIUM
- Early empty-own-diff fast-path cleanup no longer uses 'git worktree remove
--force'. We now run 'git status --porcelain --untracked-files=normal'
first; dirty worktrees (or status-check failures) are left alone for the
self-healing sweep to reconcile later. Prevents silent loss of uncommitted
scratch in the no-op finalize path.
- MergeResult.task is now kept in sync with the DB after early-fast-path
cleanup. After 'store.updateTask(taskId, { worktree: null, branch: null })'
succeeds, the in-memory task.worktree/.branch are also cleared to undefined
so the returned result.task does not advertise a removed path or deleted
branch.
LOW
- Branch deletion in the fast-path cleanup only fires when 'task.branch' was
non-null on entry. If the task did not explicitly own a branch on entry,
we never invoke 'git branch -D'; orphan refs are left for
cleanupOrphanedBranches to handle. Prevents deleting a stray ref that
happened to share the canonical name.
- Inverted the empty 'if (poolBypassRequired) {} else { ... }' block in
reacquireReuseIntegrationWorktree to 'if (directReuseEligible) try { ... }'
with the pool-bypass note above it. No behavior change \u2014 just removes the
awkward empty branch and the one-level-deeper indent on the direct-reuse
logic.
Tests
- Full @fusion/engine suite: 448 files / 5881 tests / 9 skipped, all green
- pnpm lint green, pnpm build green
This commit is contained in:
@@ -45,7 +45,7 @@ describe("prepare-commit-msg empty-commit guard (real git, FN-5345/FN-5377)", ()
|
||||
expect(empty.stderr).toContain("refusing empty commit");
|
||||
expect(empty.stderr).toContain("FN-5345/FN-5377");
|
||||
|
||||
// Review-finding regression: a commit message containing the substring
|
||||
// Review-finding regression #1: a commit message containing the substring
|
||||
// '--amend' must NOT trick the parent-cmd tokenized check into allowing
|
||||
// the empty commit. The original glob pattern (*' --amend'*) would have
|
||||
// matched this; the tokenized check rejects it.
|
||||
@@ -56,6 +56,31 @@ describe("prepare-commit-msg empty-commit guard (real git, FN-5345/FN-5377)", ()
|
||||
expect(sneaky.status).not.toBe(0);
|
||||
expect(sneaky.stderr).toContain("refusing empty commit");
|
||||
|
||||
// Review-finding regression #2: combined short flags like '-am', '-vm',
|
||||
// '-sm' must also count as message-supplying tokens, otherwise the
|
||||
// tokenized scan continues past them and hits '--amend' in user-controlled
|
||||
// message text. The combined-short-flag pattern -[!-]*[mF]* catches these
|
||||
// while leaving '--amend' (starts with --) untouched.
|
||||
const sneakyAm = git(
|
||||
worktreeDir,
|
||||
"git commit --allow-empty -am 'feat(FN-5345): fix --amend handling via -am'",
|
||||
);
|
||||
expect(sneakyAm.status).not.toBe(0);
|
||||
expect(sneakyAm.stderr).toContain("refusing empty commit");
|
||||
const sneakyVm = git(
|
||||
worktreeDir,
|
||||
"git commit --allow-empty -vm 'feat(FN-5345): fix --amend handling via -vm'",
|
||||
);
|
||||
expect(sneakyVm.status).not.toBe(0);
|
||||
expect(sneakyVm.stderr).toContain("refusing empty commit");
|
||||
|
||||
// Legitimate combined short flag with -a and a modified TRACKED file:
|
||||
// should succeed (not blocked by the message-flag detection — -a stages
|
||||
// the tracked modification, the resulting commit is non-empty).
|
||||
writeFileSync(join(worktreeDir, "real.txt"), "real-modified\n");
|
||||
const legitAm = git(worktreeDir, "git commit -am 'feat(FN-5345): legit -am commit'");
|
||||
expect(legitAm.status).toBe(0);
|
||||
|
||||
// --amend --no-edit (no staged changes, amend HEAD) is ALLOWED.
|
||||
const amendNoEdit = git(worktreeDir, "git commit --amend --no-edit");
|
||||
expect(amendNoEdit.status).toBe(0);
|
||||
|
||||
Reference in New Issue
Block a user