Skip to content

fix(sync): retain hash-matched downloads in synced state and ignore bare .git files - #119

Open
markusbrand wants to merge 1 commit into
masterfrom
fix/sync-matching-download-state-retention
Open

markusbrand wants to merge 1 commit into
masterfrom
fix/sync-matching-download-state-retention

Conversation

@markusbrand

Copy link
Copy Markdown
Owner

Summary

This PR fixes two reproducible bugs in the desktop client sync engine (client-tauri/src-tauri/src/sync.rs) tracked by OpenSpec change fix-sync-matching-download-state-retention:

  1. State Retention for Skipped/Matched Downloads (High Severity):
    In commit 0c64e44, to_download_set was excluded from base_synced to avoid recording failed transfers into state.paths. However, when a file planned for download was skipped because it already existed on disk with an identical SHA-256 hash or was previously downloaded in a resumed cycle, completed_downloads.insert(path.clone()) was not called before continue. As a result, the file was dropped from state.paths (sync_state.json), causing it to be resurrected and re-downloaded if later deleted locally.

    • Fix: Added completed_downloads.insert(path.clone()) to both the resume check and the matching local hash check in run_sync.
  2. Ignore Bare .git Files (Medium Severity):
    In is_ignored, checks only matched normalized.contains("/.git/") || normalized.starts_with(".git/"). Bare .git files (such as git submodules or worktree pointers where .git is a regular file) and nested .git files like sub/.git were not ignored, causing sync errors or unintentional file uploads.

    • Fix: Updated is_ignored to check normalized == ".git" and normalized.ends_with("/.git").

OpenSpec Artifacts

  • Proposal: openspec/changes/fix-sync-matching-download-state-retention/proposal.md
  • Specs: openspec/changes/fix-sync-matching-download-state-retention/specs/desktop-client/spec.md
  • Design: openspec/changes/fix-sync-matching-download-state-retention/design.md
  • Tasks: openspec/changes/fix-sync-matching-download-state-retention/tasks.md

Testing & Verification

  • Unit tests added in client-tauri/src-tauri/src/sync.rs:
    • test_is_ignored_bare_git_files
    • test_skipped_download_matching_hash_retained_in_synced_state
    • test_resumed_download_retained_in_synced_state
  • cargo test in client-tauri/src-tauri: 24 passed, 0 failed.
  • .venv/bin/pytest backend: 108 passed, 0 failed.
  • npm run build in client-tauri: built cleanly.

…and ignore bare .git files

- In client-tauri/src-tauri/src/sync.rs, register skipped downloads that already match the server hash or were resumed into completed_downloads so they are retained in state.paths and not resurrected upon subsequent local deletion
- In is_ignored, recognize bare .git files (such as git submodules or worktrees) and sub/.git files
- Add unit tests for hash matching retention, resume retention, and bare .git ignore patterns
- Add OpenSpec change proposal, spec, design, and tasks tracking the fix
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