Conflicts: Detect and show in issues tab
authorChristian Kamm <mail@ckamm.de>
Wed, 12 Jul 2017 08:57:41 +0000 (10:57 +0200)
committerChristian Kamm <mail@ckamm.de>
Thu, 13 Jul 2017 09:48:10 +0000 (11:48 +0200)
Incidentally fixes a potential issue where conflicts were silently-
ignored and thus deleted if the parent folder was deleted.

csync/src/csync.h
csync/src/csync_exclude.c
csync/src/csync_exclude.h
csync/src/csync_update.c
src/gui/folder.cpp
src/gui/issueswidget.cpp
src/libsync/syncengine.cpp
src/libsync/syncfileitem.h
src/libsync/syncresult.cpp
src/libsync/syncresult.h

index b35d4601c17b21983ebab0d3b50e4cc0b94ddc67..daf778c24746ed5b65246fb874edd4fb07105ee1 100644 (file)
@@ -100,7 +100,8 @@ enum csync_status_codes_e {
     CSYNC_STATUS_INVALID_CHARACTERS,
     CSYNC_STATUS_INDIVIDUAL_STAT_FAILED,
     CSYNC_STATUS_FORBIDDEN,
-    CSYNC_STATUS_INDIVIDUAL_TOO_DEEP
+    CSYNC_STATUS_INDIVIDUAL_TOO_DEEP,
+    CSYNC_STATUS_INDIVIDUAL_IS_CONFLICT_FILE
 };
 
 typedef enum csync_status_codes_e CSYNC_STATUS;
index 88dd61e750183af7dfc9c6555789017a1fc9f34b..873a12d885de37abfbbf026a95ad08409b7715b7 100644 (file)
@@ -302,7 +302,7 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
     /* Always ignore conflict files, not only via the exclude list */
     rc = csync_fnmatch("*_conflict-*", bname, 0);
     if (rc == 0) {
-        match = CSYNC_FILE_SILENTLY_EXCLUDED;
+        match = CSYNC_FILE_EXCLUDE_CONFLICT;
         goto out;
     }
 
@@ -313,7 +313,7 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
         }
         rc = csync_fnmatch(conflict, path, 0);
         if (rc == 0) {
-            match = CSYNC_FILE_SILENTLY_EXCLUDED;
+            match = CSYNC_FILE_EXCLUDE_CONFLICT;
             SAFE_FREE(conflict);
             goto out;
         }
index ae49bbd8d1730cb11e14f06400f8c64c48446c3a..722d27cace71ccf3cdbbed3f69e706fb0f8e0a41 100644 (file)
@@ -32,7 +32,8 @@ enum csync_exclude_type_e {
   CSYNC_FILE_EXCLUDE_TRAILING_SPACE,
   CSYNC_FILE_EXCLUDE_LONG_FILENAME,
   CSYNC_FILE_EXCLUDE_HIDDEN,
-  CSYNC_FILE_EXCLUDE_STAT_FAILED
+  CSYNC_FILE_EXCLUDE_STAT_FAILED,
+  CSYNC_FILE_EXCLUDE_CONFLICT
 };
 typedef enum csync_exclude_type_e CSYNC_EXCLUDE_TYPE;
 
index d7587765c3b1457238d89dfd22c709686063fd49..1a069442e78c36946735aa91f720f99d166bfcb6 100644 (file)
@@ -469,6 +469,8 @@ out:
               st->error_status = CSYNC_STATUS_INDIVIDUAL_EXCLUDE_HIDDEN;
           } else if (excluded == CSYNC_FILE_EXCLUDE_STAT_FAILED) {
               st->error_status = CSYNC_STATUS_INDIVIDUAL_STAT_FAILED;
+          } else if (excluded == CSYNC_FILE_EXCLUDE_CONFLICT) {
+              st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_CONFLICT_FILE;
           }
       }
   }
index 7282e431f659819de2631de5a124768312a329cf..d4b652ba6dd153c8c58e280abc24a32407de983d 100644 (file)
@@ -341,8 +341,8 @@ void Folder::showSyncResultPopup()
             _syncResult.numRenamedItems(), _syncResult.firstItemRenamed()->_renameTarget);
     }
 
-    if (_syncResult.firstConflictItem()) {
-        createGuiLog(_syncResult.firstConflictItem()->_file, LogStatusConflict, _syncResult.numConflictItems());
+    if (_syncResult.firstNewConflictItem()) {
+        createGuiLog(_syncResult.firstNewConflictItem()->_file, LogStatusConflict, _syncResult.numNewConflictItems());
     }
     if (int errorCount = _syncResult.numErrorItems()) {
         createGuiLog(_syncResult.firstItemError()->_file, LogStatusError, errorCount);
index 9356710ae57fde05b274dc6c7a130c2c25497bd8..4803f17a4fae99c15e651cca49d23f7c3b2452f2 100644 (file)
@@ -247,7 +247,6 @@ bool IssuesWidget::shouldBeVisible(QTreeWidgetItem *item, AccountState *filterAc
     visible &= (_ui->showIgnores->isChecked() || status != SyncFileItem::FileIgnored);
     visible &= (_ui->showWarnings->isChecked()
         || (status != SyncFileItem::SoftError
-               && status != SyncFileItem::Conflict
                && status != SyncFileItem::Restoration));
 
     auto folderalias = item->data(2, Qt::UserRole).toString();
index 5dc4ec07b3b05b763dc7f9387cbc8e7fb3d67d86..8fa6eb7b726152476257ef7c9b8cb2f083dcec12 100644 (file)
@@ -495,6 +495,10 @@ int SyncEngine::treewalkFile(TREE_WALK_FILE *file, bool remote)
     case CSYNC_STATUS_INDIVIDUAL_TOO_DEEP:
         item->_errorString = tr("Folder hierarchy is too deep");
         break;
+    case CSYNC_STATUS_INDIVIDUAL_IS_CONFLICT_FILE:
+        item->_status = SyncFileItem::Conflict;
+        item->_errorString = tr("Conflict: Server version downloaded, local copy renamed and not uploaded.");
+        break;
     case CYSNC_STATUS_FILE_LOCKED_OR_OPEN:
         item->_errorString = QLatin1String("File locked"); // don't translate, internal use!
         break;
index b84c9ae33a5cd87985c8539bd269f504c32b12f2..baa8a75102c7e2917fe7bc2e53402898cc7c34ce 100644 (file)
@@ -61,7 +61,14 @@ public:
         SoftError, ///< More like an information
 
         Success, ///< The file was properly synced
-        Conflict, ///< The file was properly synced, but a conflict was created
+
+        /** Marks a conflict, old or new.
+         *
+         * With instruction:IGNORE: detected an old unresolved old conflict
+         * With instruction:CONFLICT: a new conflict this sync run
+         */
+        Conflict,
+
         FileIgnored, ///< The file is in the ignored list (or blacklisted with no retries left)
         Restoration, ///< The file was restored because what should have been done was not allowed
 
index de5c81c54b6a2056676044748122e1eaa120f7c5..88e78320b07146936b6efd35462edf208cb6856b 100644 (file)
@@ -25,7 +25,8 @@ SyncResult::SyncResult()
     , _numRemovedItems(0)
     , _numUpdatedItems(0)
     , _numRenamedItems(0)
-    , _numConflictItems(0)
+    , _numNewConflictItems(0)
+    , _numOldConflictItems(0)
     , _numErrorItems(0)
 
 {
@@ -147,9 +148,13 @@ void SyncResult::processCompletedItem(const SyncFileItemPtr &item)
             _firstItemError = item;
         }
     } else if (item->_status == SyncFileItem::Conflict) {
-        _numConflictItems++;
-        if (!_firstConflictItem) {
-            _firstConflictItem = item;
+        if (item->_instruction == CSYNC_INSTRUCTION_CONFLICT) {
+            _numNewConflictItems++;
+            if (!_firstNewConflictItem) {
+                _firstNewConflictItem = item;
+            }
+        } else {
+            _numOldConflictItems++;
         }
     } else {
         if (!item->hasErrorStatus() && item->_status != SyncFileItem::FileIgnored && item->_direction == SyncFileItem::Down) {
index 7c5e501aa62a0bce2ecc90d5e6ed8ebde2b5112c..ab53c8dba08c9ed7382df77a9f9fef5b94b0f4ee 100644 (file)
@@ -66,14 +66,15 @@ public:
     int numRemovedItems() const { return _numRemovedItems; }
     int numUpdatedItems() const { return _numUpdatedItems; }
     int numRenamedItems() const { return _numRenamedItems; }
-    int numConflictItems() const { return _numConflictItems; }
+    int numNewConflictItems() const { return _numNewConflictItems; }
+    int numOldConflictItems() const { return _numOldConflictItems; }
     int numErrorItems() const { return _numErrorItems; }
 
     const SyncFileItemPtr &firstItemNew() const { return _firstItemNew; }
     const SyncFileItemPtr &firstItemDeleted() const { return _firstItemDeleted; }
     const SyncFileItemPtr &firstItemUpdated() const { return _firstItemUpdated; }
     const SyncFileItemPtr &firstItemRenamed() const { return _firstItemRenamed; }
-    const SyncFileItemPtr &firstConflictItem() const { return _firstConflictItem; }
+    const SyncFileItemPtr &firstNewConflictItem() const { return _firstNewConflictItem; }
     const SyncFileItemPtr &firstItemError() const { return _firstItemError; }
 
     void processCompletedItem(const SyncFileItemPtr &item);
@@ -95,14 +96,15 @@ private:
     int _numRemovedItems;
     int _numUpdatedItems;
     int _numRenamedItems;
-    int _numConflictItems;
+    int _numNewConflictItems;
+    int _numOldConflictItems;
     int _numErrorItems;
 
     SyncFileItemPtr _firstItemNew;
     SyncFileItemPtr _firstItemDeleted;
     SyncFileItemPtr _firstItemUpdated;
     SyncFileItemPtr _firstItemRenamed;
-    SyncFileItemPtr _firstConflictItem;
+    SyncFileItemPtr _firstNewConflictItem;
     SyncFileItemPtr _firstItemError;
 };
 }