Skip to content

fix: conflict merge data loss, attachment link preservation, diff noise, dry-run readability, duplicate ID detection#47

Merged
rgonek merged 7 commits intomainfrom
bugfix/conflict-merge-and-conversion-fixes
Feb 27, 2026
Merged

fix: conflict merge data loss, attachment link preservation, diff noise, dry-run readability, duplicate ID detection#47
rgonek merged 7 commits intomainfrom
bugfix/conflict-merge-and-conversion-fixes

Conversation

@rgonek
Copy link
Owner

@rgonek rgonek commented Feb 27, 2026

Summary

This PR fixes six bugs and adds two quality-of-life improvements discovered during the Confluence sync CLI implementation review.

Changes

Bug Fixes

  • Fix workspace restore before auto pull-merge (4505a67): cmd/push.go was invoking runPull while the push stash was not yet restored and was zeroing stashRef, risking loss of local workspace state during --on-conflict=pull-merge. The stash is now restored before invoking pull.

  • Preserve attachment links through conversion (eeb542b): Local markdown file links to attachments were being rewritten to image syntax (![]()) during conversion prep, causing non-image attachments to be lost or rendered incorrectly. Fixed by using pandoc media-inline spans to preserve file attachment links.

  • Reduce noisy markdown escaping on pull (2114708): The forward converter was over-escaping parentheses in markdown output (e.g. in links), creating unnecessary noise in pulled files.

  • Fix media type inference regression (93afbeb): resolveForwardMediaType in hooks.go defaulted to "file" when MediaType was empty in an ADF node, even for images. Now infers the correct type from file extension (.png, .jpg, .gif, .webp, etc.) when type is absent.

Quality-of-Life Improvements

  • Strip read-only metadata before diffing (524a0dc): conf diff was comparing raw local markdown (including updated_by, updated_at, created_by, created_at frontmatter fields) against remote snapshots that don't carry those fields, producing false diffs for unchanged pages. These fields are now stripped before comparison.

  • Show Markdown preview in dry-run output (77fcc77): CreatePage and UpdatePage in dry_run_remote.go were dumping raw ADF JSON, which is hard to read. Dry-run output now shows a rendered Markdown preview via converter.Forward.

  • Detect duplicate page IDs across files (4ff1533): No cross-file check for duplicate Confluence page IDs existed. Added detectDuplicatePageIDs in the validate flow, called after BuildPageIndexWithPending, to catch duplicate id values before any push.

Testing

  • Added/updated unit and integration tests for all changed invariants.
  • Full test suite passing: go test ./cmd/... ./internal/...
  • go vet ./cmd/... ./internal/... clean.

Note: The pre-existing untracked dumper.go in the repo root (which imports a non-existent package) breaks go vet ./... and go test ./... at the root package level. This is intentionally left untouched as it predates this branch.

Normalize created_by, created_at, updated_by, and updated_at out of
both local and remote diff snapshots so that metadata-only changes
(e.g. a different updater) do not appear as content differences.

Add unit test for normalizeDiffMarkdown and an integration test that
verifies file-mode diff reports no differences when only author
metadata has changed.
Replace the raw ADF JSON dump in dry-run CREATE/UPDATE PAGE output with
a human-readable Markdown preview converted via the forward converter.
Empty bodies are shown as '(empty)' rather than a JSON skeleton.
Falls back to indented ADF JSON only if conversion fails.

Add TestRunPush_DryRunShowsMarkdownPreviewNotRawADF to assert the
new behavior end-to-end.
Add detectDuplicatePageIDs to scan the space-wide PageIndex built
during validate and fail early when two or more files claim the same
Confluence page ID (a common rename-trap / copy-paste mistake).

The check runs before the per-file validation loop so the error is
reported immediately with a list of the conflicting paths.

Add TestRunValidateTarget_BlocksDuplicatePageIDs (integration) and
three unit tests for detectDuplicatePageIDs.
resolveForwardMediaType now falls back to extension-based detection
(png, jpg, gif, svg, etc.) when the ADF media node does not carry an
explicit type attribute. This restores correct ![]() rendering for
images whose mediaType field is absent in the source ADF, fixing the
TestForwardMediaHook and TestForwardMediaHook_FallbackByPageAndFilename
regressions introduced in the Phase 2 attachment-link fix.
@rgonek rgonek merged commit 439ad5d into main Feb 27, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant