All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
1.0.1 - 2026-03-26
- Race condition in
ThreadSafeSyncResultwhere parallel sync threads could overwrite each other's counter values, causingTotalFilesProcessedto undercount. Counter values are now flushed once after all parallel phases complete.
- Updated
docker-compose.test.ymlfor LocalStack's new authentication requirement (community image sunset). Removed deprecatedSERVICES,DEBUG, andEDGE_PORTenvironment variables.
1.0.0 - 2026-02-15
A pure .NET 8.0 file synchronization library. SharpSync provides a modular, interface-based architecture for synchronizing files between various storage backends.
- Local filesystem (
LocalFileStorage) with symlink detection, timestamp and permission preservation - WebDAV (
WebDavStorage) with OAuth2 authentication, Nextcloud chunking v2, and OCIS TUS 1.0.0 resumable uploads - SFTP (
SftpStorage) with password and private key authentication, symlink detection, and timestamp/permission preservation - FTP/FTPS (
FtpStorage) with explicit and implicit TLS, and timestamp preservation - Amazon S3 (
S3Storage) and S3-compatible storage (MinIO, LocalStack) with multipart uploads
- Bidirectional synchronization with three-phase optimization (directories/small files, large files, deletes/conflicts)
- Incremental sync with change detection (timestamp, checksum-only, or size-only modes)
- Configurable parallel processing for large file sets
- Sync plan preview via
GetSyncPlanAsync()before executing changes - Smart conflict resolution with rich
ConflictAnalysisdata for UI integration - Pattern-based file filtering with ReDoS-safe regex (
SyncFilter)
SyncFolderAsync()to sync a specific folder without full scanSyncFilesAsync()to sync specific files on demandNotifyLocalChangeAsync()/NotifyLocalChangeBatchAsync()for FileSystemWatcher integrationNotifyLocalRenameAsync()for proper rename trackingNotifyRemoteChangeAsync()/NotifyRemoteChangeBatchAsync()/NotifyRemoteRenameAsync()for remote change detectionGetPendingOperationsAsync()to inspect the sync queueClearPendingLocalChanges()/ClearPendingRemoteChanges()to discard pending notifications- Per-sync exclusion patterns via
SyncOptions.ExcludePatterns
PauseAsync()/ResumeAsync()for gracefully pausing and resuming long-running syncsSyncEngineStateenum (Idle, Running, Paused) andIsPausedproperty- Thread-safe state properties and change notification methods (safe to call while sync runs)
ProgressChangedevent for item-level sync progressFileProgressChangedevent for per-file byte-level transfer progressConflictDetectedevent for interactive conflict resolutionGetRecentOperationsAsync()for activity history with time filteringClearOperationHistoryAsync()for cleaning up old operation records
SyncOptions.MaxBytesPerSecondfor bandwidth throttlingSyncOptions.VirtualFileCallbackhook for Windows Cloud Files API placeholder integrationSyncOptions.PreserveTimestamps/PreservePermissionsfor metadata preservationSyncOptions.FollowSymlinksfor symlink handling policyISyncStorage.SetLastModifiedAsync()/SetPermissionsAsync()default interface methodsISyncStorage.GetRemoteChangesAsync()for storage-level remote change detection
SqliteSyncDatabasewith optimized indexes and transaction support- Implements both
IDisposableandIAsyncDisposable - Operation history persistence for activity feeds
- Structured logging via
Microsoft.Extensions.Loggingwith source-generated[LoggerMessage]attributes - Deterministic builds with embedded debug symbols and SourceLink
- Multi-platform CI/CD (Ubuntu, Windows, macOS) with integration tests on Ubuntu via Docker
- Console sample application with OAuth2 example