Commit Graph

2 Commits

Author SHA1 Message Date
gsxdsm
9a83117294 fix(merger): address code-review findings on autostash + observer
P0 — parsePorcelainZ rename/copy handling
  Git's -z porcelain emits `R  <new>\0<old>\0` for renames (and
  C for copies). The naive split-and-slice treated <old> as an
  independent dirty path, which made runObservedDestructiveSyncOp
  warn about phantom "cleared paths" whenever a rename was in
  flight. Now we detect R/C status and skip the trailing entry.

P1 — race-rescue loop unstages between attempts
  `git stash create` snapshots the index without clearing it, so
  iteration 2's `git add -A` would re-stage atop iteration 1's
  leftovers. Tree differences inside the loop then reflected stale
  staging rather than genuine new writes. Added a `git reset` at
  the top of each iteration so every attempt starts from a clean
  index baseline.

P1 — writeActiveMergerStatus is now atomic
  Switched from in-place writeFileSync to temp-file + renameSync.
  POSIX guarantees rename atomicity on the same filesystem, so a
  reader can no longer catch the file mid-flush and return a
  false-negative "no merger active" advisory.

P2 — Step regex em-dash clarity
  `[—\-:]` is functionally fine but obscures intent; switched to
  `(?:—|-|:)` so the em-dash branch is obvious. Added a test case
  for the em-dash separator.

New tests:
- parse-porcelain-z.test.ts (8 cases including renames + copies)
- em-dash case added to derive-subject-summary.test.ts

247/247 merger-suite tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 18:04:19 -07:00
gsxdsm
b81196e3a2 fix(merger): prefer step headline subject + add autostash race-rescue
- deriveDeterministicSubjectSummary now picks the lowest-numbered
  `complete Step N` headline (or the oldest commit) instead of the most
  recent commit, so trailing quality-gate revisions stop hijacking the
  squash-merge subject (FN-3617 landed as "align mailbox modal css..."
  when 4 of 5 commits were the actual Claude OAuth fix).
- AI subject + body system prompts in ai-summarize.ts now weight by
  commit theme rather than file size, so a small token cleanup that
  touches a large CSS file no longer dominates the summary.
- stashUnrelatedRootDirChanges adds a bounded re-snapshot loop after
  the primary stash is persisted but before \`git reset --hard\`. Any
  late-dirty paths (concurrent dev edits during a long merger run,
  parallel merger runs racing on rootDir, late test/build artifacts)
  get captured in labeled \`race-rescue-N\` stashes recoverable from
  \`git stash list\`, instead of being wiped by the destructive reset.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 17:06:46 -07:00