Description
Split off from #675, which fixed one route to the same data loss.
The remaining route
A no-op "Update to latest" short-circuits on the unchanged content fingerprint and returns Preserved = 0. GitHubSyncService.ReimportAtCommit reads that number to decide whether to advance the sync baseline — so it records last-sync and advances the conflict horizon past pending uncommitted server changes, although it verified nothing.
Measured pre-#675 probe:
update2 outcome=Skipped LastSyncedAt …30.8564380 → …30.8765430
The git-diff scope skip has the same shape for a server-edited node whose repo file didn't change.
Why it matters
The horizon (LastSyncedAt) is what two-way sync uses to decide a node is server-newer and must be protected (node.LastModified > LastSyncedAt). Advancing it without importing disarms that protection, so a later push prunes the server-side addition — the exact data-loss shape #675 fixed via the Preserved count. #675 closes the "imported but preserved" route; this one is still open.
Suggested fix, and why it wasn't bundled
Split the two fields:
LastSyncCommitSha— safe to advance on a no-op (it records "we have seen this commit").LastSyncedAt— the conflict horizon; must only advance when an import actually reconciled the nodes.
This changes the meaning of a persisted field and affects the "are we up to date?" display: a repo commit touching no node files would otherwise leave the space permanently "behind". That is a product decision, not a flake fix, which is why #675 deliberately left it alone.
Related
Also worth doing while in here (from the same investigation): record per-node import write-times in the manifest so "server-newer" means "changed since the import wrote this node" rather than "changed since a global timestamp". That removes the false-conflict #675 makes more reachable — where the import itself re-stamps LastModified past the frozen horizon, so an untouched node looks server-newer and a later repo edit is preserved instead of applied.
Activity
GitSync: no-op sync never advances the conflict horizon; bidirectiona…
Merge pull request #895 from Systemorph/fix/677-604-gitsync-horizon