Skip to content

feat (refactor): Migrate Git sync to use SQLite-backed LocalDataStore with async operations and refactor related controllers and tests. - #18

Merged
Tranthanh98 merged 1 commit into
mainfrom
feature/migrate-to-use-sqlite
Sep 21, 2026
Merged

Tranthanh98 merged 1 commit into
mainfrom
feature/migrate-to-use-sqlite

Conversation

@Tranthanh98

@Tranthanh98 Tranthanh98 commented Sep 21, 2026 •

Copy link
Copy Markdown
Collaborator

Pull request title
Refactor Git‑Flow sync to use a persistent LocalDataStore and async operations


Summary

This branch replaces the in‑memory UserDefaults‑based pending‑upload tracking used by the Git‑Flow sync logic with a robust, file‑backed LocalDataStore backed by SQLite. The sync workflow is now fully asynchronous and serialised per repository to avoid race conditions between downloads and saves.

Key changes

  • GitFlowConfigurationSyncController

    • Introduced dataStore: LocalDataStore for persistence.
    • Added operations map to serialize async tasks per repository URL.
    • Implemented serialized(in:operation:) helper that:
      • Awaits any previous operation on the same repo.
      • Prepares the dataStore before each operation.
    • Reworked reconcile and save to use the new serializer.
    • Replaced pendingUploadsKey/UserDefaults with LocalDataStore:
      • pendingVersion(_:), markPendingUpload(_:), clearPendingUpload(_:version:).
    • Updated logic to use pendingVersion instead of a simple boolean flag.
  • New Services

    • LocalDataStore.swift, LocalDataError.swift, LocalDataTransaction.swift: core abstraction for transactional, file‑based data access.
    • LegacyLocalDataMigration.swift: helper for migrating pre‑existing data.
    • LocalSQLiteDatabase.swift: SQLite implementation of LocalDataStore.
  • Updated Controllers & Views

    • Adjusted import paths and initialisers to accept optional dataStore.
    • Minor view updates to reflect new async behaviour (e.g., LocalDataLoadingView).
  • Tests

    • Added LocalDataMigrationTests.swift and LocalDataStoreTestFixture.swift to verify persistence and transaction semantics.
    • Updated existing unit tests to use the new LocalDataStore and async API.

Impact

  • Persistence: Pending uploads are now stored in a SQLite database, surviving app restarts and providing a single source of truth.
  • Concurrency: Per‑repo serialization prevents interleaving of download and save operations, eliminating potential data races.
  • Async: All sync actions are now asynchronous, aligning with the rest of the codebase’s async style.
  • Test coverage: Additional tests ensure migration paths and transactional integrity.

All changes are confined to the Git‑Flow sync module and its supporting persistence layer. No public API of the application has been altered.

Summary by CodeRabbit

  • New Features
    • Added reliable local data storage with automatic migration from existing app data.
    • Added loading and retry states while local data is prepared.
    • Repository settings, bookmarks, provider accounts, SSH keys, and visibility results now persist consistently across launches.
  • Bug Fixes
    • Improved synchronization safety to prevent newer local changes from being overwritten or lost.
    • Added clearer error handling for storage, account, bookmark, and settings operations.
    • Preserved pending changes during cloud synchronization and account updates.

@coderabbitai

coderabbitai Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

Understand this PR’s impact

Explore downstream dependencies and potential security impact with Blast Radius.

View blast radius →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 49cba490-1539-42db-84fd-ac01530cdc84

📥 Commits

Reviewing files that changed from the base of the PR and between a04e274 and f038930.

📒 Files selected for processing (32)
  • macgit/App/GitFlowConfigurationSyncController.swift
  • macgit/App/GitProviderAccountController.swift
  • macgit/App/RepositoryBookmarkController.swift
  • macgit/App/RepositoryCommitRuleSyncController.swift
  • macgit/App/RepositoryVisibilityController.swift
  • macgit/App/macgitApp.swift
  • macgit/Services/GitProviderAccountPreferenceStore.swift
  • macgit/Services/GitProviderSSHKeyStore.swift
  • macgit/Services/LegacyLocalDataMigration.swift
  • macgit/Services/LocalDataError.swift
  • macgit/Services/LocalDataStore.swift
  • macgit/Services/LocalDataTransaction.swift
  • macgit/Services/LocalGitProviderAccountStore.swift
  • macgit/Services/LocalSQLiteDatabase.swift
  • macgit/Services/RepoSettingsStore.swift
  • macgit/Services/RepositoryVisibilityCache.swift
  • macgit/Views/Common/LocalDataLoadingView.swift
  • macgit/Views/MainWindow/MainWindowView+ProtectedBranchCommit.swift
  • macgit/Views/MainWindow/MainWindowView+ProviderAccountPreferences.swift
  • macgit/Views/MainWindow/MainWindowView+Sheets.swift
  • macgit/Views/MainWindow/MainWindowView.swift
  • macgit/Views/MainWindow/RepoPickerView.swift
  • macgitTests/GitFlowConfigurationSyncTests.swift
  • macgitTests/GitProviderAccountPreferenceStoreTests.swift
  • macgitTests/GitProviderSSHKeyStoreTests.swift
  • macgitTests/LocalDataMigrationTests.swift
  • macgitTests/LocalDataStoreTestFixture.swift
  • macgitTests/LocalGitProviderAccountStoreTests.swift
  • macgitTests/RepoSettingsStoreTests.swift
  • macgitTests/RepositoryBookmarkTests.swift
  • macgitTests/RepositoryCommitRuleSyncControllerTests.swift
  • macgitTests/RepositoryVisibilityControllerTests.swift
💤 Files with no reviewable changes (1)
  • macgit/Views/MainWindow/MainWindowView.swift

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

The change introduces SQLite-backed LocalDataStore persistence, imports legacy UserDefaults data, and updates account, repository, bookmark, visibility, synchronization, and UI flows to use asynchronous transactions and error handling.

Changes

Local persistence migration

Layer / File(s) Summary
SQLite storage and legacy migration
macgit/Services/LocalSQLiteDatabase.swift, macgit/Services/LocalDataStore.swift, macgit/Services/LocalDataTransaction.swift, macgit/Services/LegacyLocalDataMigration.swift, macgit/Services/LocalDataError.swift, macgitTests/LocalDataMigrationTests.swift, macgitTests/LocalDataStoreTestFixture.swift
Added transactional SQLite storage, readiness handling, rollback, legacy-data migration, validation errors, and migration tests.
Account and provider persistence
macgit/Services/LocalGitProviderAccountStore.swift, macgit/Services/GitProviderAccountPreferenceStore.swift, macgit/Services/GitProviderSSHKeyStore.swift, macgit/App/GitProviderAccountController.swift, macgitTests/*Account*, macgitTests/GitProviderSSHKeyStoreTests.swift
Moved accounts, preferences, SSH keys, tombstones, and synced identities to asynchronous local-store transactions.
Repository settings and synchronization
macgit/Services/RepoSettingsStore.swift, macgit/App/RepositoryCommitRuleSyncController.swift, macgit/App/GitFlowConfigurationSyncController.swift, macgit/Views/MainWindow/*, macgitTests/*SyncTests.swift, macgitTests/RepoSettingsStoreTests.swift
Persisted repository settings and pending synchronization state transactionally. Added serialized workflows and version-checked pending acknowledgements.
Bookmark storage and cloud reconciliation
macgit/App/RepositoryBookmarkController.swift, macgit/Views/MainWindow/RepoPickerView.swift, macgitTests/RepositoryBookmarkTests.swift
Moved bookmarks, paths, uploads, and deletes to local transactions. Cloud merges now account for active accounts, pending operations, and record versions.
Visibility cache and application loading
macgit/Services/RepositoryVisibilityCache.swift, macgit/App/RepositoryVisibilityController.swift, macgit/App/macgitApp.swift, macgit/Views/Common/LocalDataLoadingView.swift, macgitTests/RepositoryVisibilityControllerTests.swift
Replaced the visibility cache with an asynchronous SQLite implementation and added loading, retry, and error states around shared local-data preparation.

Priority: ⬇️ Low

Estimated code review effort: 5 (Critical) | ~90 minutes

Change: Refactor

Sequence Diagram(s)

sequenceDiagram
  participant macgitApp
  participant LocalDataLoadingView
  participant LocalDataStore
  participant LocalSQLiteDatabase
  macgitApp->>LocalDataLoadingView: Render application content
  LocalDataLoadingView->>LocalDataStore: prepare()
  LocalDataStore->>LocalSQLiteDatabase: Import legacy data and load records
  LocalSQLiteDatabase-->>LocalDataStore: Return local records or error
  LocalDataStore-->>LocalDataLoadingView: Publish ready or unavailable state
  LocalDataLoadingView-->>macgitApp: Render content or retryable error
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 1.53% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 131 functions across 31 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: migrating Git synchronization to the SQLite-backed LocalDataStore and updating related asynchronous controllers and tests.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Comment @coderabbitai help to get the list of available commands.

@Tranthanh98
Tranthanh98 merged commit 015b60d into main Sep 21, 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