fix(git-sync): review #4404 batch — sanitize-title echo, per-space gate, move-echo, merge-agreement, fence-aware conflict scan, e2e asserts
Addresses reviewer comment #4404 (critical + blocking): - Critical #2: renamePage skips the echo where the incoming title equals sanitizeTitle(current title) — a Docmost title with FS-hostile chars (: / " |, newlines, double-space, >120) was pulled to a sanitized stem then written back, permanently corrupting the real title. (datasource) - Blocking #3: runOnce enforces per-space settings.gitSync.enabled (the event path bypassed opt-in; any edited space would git-init + export). (orchestrator) - Blocking #6: movePage no-ops the position-less same-parent echo that clobbered the user's chosen sibling order. (datasource) - Blocking #9: hasConflictMarkers is fence-aware — '<<<<<<< HEAD' inside a code block (git-tutorial page) no longer trips the all-or-nothing gate that froze the whole space's refs. (push.ts) - Blocking #11: three-way tryMergeRegion short-circuits when live==target (diff3 agreement) instead of logging a false 'same-block conflict resolved to git' — the echo noise that masked real data-loss signals. (three-way-merge) - Blocking #12/#13: e2e-advanced — drop the delete-cap block (no such feature; failed with a scary '(data loss!)'); non-member assert now expects 404 (existence not leaked), not 403. Verified on stand: sanitized-title rename preserves DB title (vault file sanitized); non-enabled space creates no vault; fenced conflict markers ingest without jamming; build clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -125,6 +125,16 @@ function tryMergeRegion(
|
||||
a: string[],
|
||||
b: string[],
|
||||
): LocalPick[] | null {
|
||||
// Agreement short-circuit (review #11). When live (a) and target (b) are
|
||||
// identical, both sides converged on the SAME result — diff3 "agreement", NOT
|
||||
// a conflict. This is the dominant echo case (live == target != base) that
|
||||
// otherwise trips the overlap check below and is logged as a false "N same-block
|
||||
// conflict(s) resolved to the git version", masking REAL data-loss signals.
|
||||
// Emit the region straight from live (which equals target); no conflict.
|
||||
if (a.length === b.length && a.every((v, i) => v === b[i])) {
|
||||
return a.map((_v, i) => ({ src: 'live', local: i }) as LocalPick);
|
||||
}
|
||||
|
||||
const aHunks = buildHunks(o, a);
|
||||
const bHunks = buildHunks(o, b);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user