/// <summary> /// Executes a single change on the file system and updates the cache. /// Does not commit or persist in any other way. /// </summary> /// <param name="change">The change to execute on the file system.</param> private void Execute(AbstractChange change) { // Execute changes DisableFileSystemEvents(); change.ExecuteChanges(FileSystemAdaptee); EnableFileSystemEvents(); // Update cache if (change is FileModifiedChange) { var mod = (FileModifiedChange)change; _cache.Update(mod.AssociatedPath); } else if (change is ItemsCreatedChange) { var created = (ItemsCreatedChange)change; foreach (var creation in created.Items) { _cache.Update(creation.GetAssociatedPath()); } } else if (change is ItemsDeletedChange) { var deleted = (ItemsDeletedChange)change; foreach (var deletion in deleted.Items) { _cache.Delete(deletion); } } }
/// <summary> /// Attempts to version the given change in this file- and version control system. If a /// conflict occurs we return it to be handled by the caller. /// </summary> /// <param name="change">The change to persist.</param> /// <returns>A conflict if the merge failed, null otherwise.</returns> public Conflict? Save(AbstractChange change) { try { // Execute the change on the file system Execute(change); // Commit the change var version = new List<AbstractChange> { change }; PersistVersion(version); // Push to server var conflicts = PushToServer(); if (conflicts.Count > 1) throw new InvalidOperationException("Too many conflicts. Aborting."); else if (conflicts.Count == 1) return conflicts[0]; else return null; } catch (Exception) { // If we hit an exception when pushing to server we simply ignore it // and avoid incrementing the version - the changes will be pushed once // the server is back on track return null; } }