Conflicts: Detect and show in issues tab

Incidentally fixes a potential issue where conflicts were silently-
ignored and thus deleted if the parent folder was deleted.
This commit is contained in:
Christian Kamm 2017-07-12 10:57:41 +02:00
parent 7adcb76f68
commit 2cdf5517cb
10 changed files with 37 additions and 16 deletions

View 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;

View 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;
}

View 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;

View 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;
}
}
}

View 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);

View 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();

View 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;

View 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

View 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) {

View 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;
};
}