if (entriesIter != entries.end()) {
QString errorMessage;
const auto newFileNameEntry = entriesIter->second;
- if (newFileNameEntry.serverEntry.isValid()) {
+ if (entry.serverEntry.isValid() && newFileNameEntry.serverEntry.isValid()) {
errorMessage = tr("File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server.");
}
- if (newFileNameEntry.localEntry.isValid()) {
+ if (entry.localEntry.isValid() && newFileNameEntry.localEntry.isValid()) {
errorMessage = tr("File contains trailing spaces and could not be renamed, because a file with the same name already exists locally.");
}
item->_instruction = CSYNC_INSTRUCTION_ERROR;
item->_status = SyncFileItem::NormalError;
item->_errorString = errorMessage;
- emit _discoveryData->itemDiscovered(item);
+ processFileFinalize(item, path, false, ParentNotChanged, ParentNotChanged);
return false;
}
}
processFileFinalize(item, path, recurse, recurseQueryLocal, recurseQueryServer);
};
+ auto handleInvalidSpaceRename = [&] (SyncFileItem::Direction direction) {
+ if (_dirItem) {
+ path._target = _dirItem->_file + "/" + localEntry.renameName;
+ } else {
+ path._target = localEntry.renameName;
+ }
+ OCC::SyncJournalFileRecord base;
+ if (!_discoveryData->_statedb->getFileRecordByInode(localEntry.inode, &base)) {
+ dbError();
+ return;
+ }
+ const auto originalPath = base.path();
+ const auto adjustedOriginalPath = _discoveryData->adjustRenamedPath(originalPath, SyncFileItem::Down);
+ _discoveryData->_renamedItemsLocal.insert(originalPath, path._target);
+ item->_renameTarget = path._target;
+ path._server = adjustedOriginalPath;
+ if (_dirItem) {
+ item->_file = _dirItem->_file + "/" + localEntry.name;
+ } else {
+ item->_file = localEntry.name;
+ }
+ path._original = originalPath;
+ item->_originalFile = path._original;
+ item->_modtime = base._modtime;
+ item->_inode = base._inode;
+ item->_instruction = CSYNC_INSTRUCTION_RENAME;
+ item->_direction = direction;
+ item->_fileId = base._fileId;
+ item->_remotePerm = base._remotePerm;
+ item->_etag = base._etag;
+ item->_type = base._type;
+ };
+
if (!localEntry.isValid()) {
if (_queryLocal == ParentNotChanged && dbEntry.isValid()) {
// Not modified locally (ParentNotChanged)
|| _discoveryData->_syncOptions._vfs->needsMetadataUpdate(*item))) {
item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
item->_direction = SyncFileItem::Down;
+ } else if (!localEntry.renameName.isEmpty()) {
+ handleInvalidSpaceRename(SyncFileItem::Up);
}
} else if (!typeChange && isVfsWithSuffix()
&& dbEntry.isVirtualFile() && !localEntry.isVirtualFile
}
if (!localEntry.renameName.isEmpty()) {
- if (_dirItem) {
- path._target = _dirItem->_file + "/" + localEntry.renameName;
- } else {
- path._target = localEntry.renameName;
- }
- OCC::SyncJournalFileRecord base;
- if (!_discoveryData->_statedb->getFileRecordByInode(localEntry.inode, &base)) {
- dbError();
- return;
- }
- const auto originalPath = base.path();
- const auto adjustedOriginalPath = _discoveryData->adjustRenamedPath(originalPath, SyncFileItem::Down);
- _discoveryData->_renamedItemsLocal.insert(originalPath, path._target);
- item->_renameTarget = path._target;
- path._server = adjustedOriginalPath;
- if (_dirItem) {
- item->_file = _dirItem->_file + "/" + localEntry.name;
- } else {
- item->_file = localEntry.name;
- }
- path._original = originalPath;
- item->_originalFile = path._original;
- item->_modtime = base._modtime;
- item->_inode = base._inode;
- item->_instruction = CSYNC_INSTRUCTION_RENAME;
- item->_direction = SyncFileItem::Down;
- item->_fileId = base._fileId;
- item->_remotePerm = base._remotePerm;
- item->_etag = base._etag;
- item->_type = base._type;
-
+ handleInvalidSpaceRename(SyncFileItem::Down);
finalize();
return;
}
auto &vfs = propagator()->syncOptions()._vfs;
auto pinState = vfs->pinState(_item->_originalFile);
- // Delete old db data.
- propagator()->_journal->deleteFileRecord(_item->_originalFile);
- if (!vfs->setPinState(_item->_originalFile, PinState::Inherited)) {
- qCWarning(lcPropagateRemoteMove) << "Could not set pin state of" << _item->_originalFile << "to inherited";
+ const auto targetFile = propagator()->fullLocalPath(_item->_renameTarget);
+
+ if (QFileInfo::exists(targetFile)) {
+ // Delete old db data.
+ propagator()->_journal->deleteFileRecord(_item->_originalFile);
+ if (!vfs->setPinState(_item->_originalFile, PinState::Inherited)) {
+ qCWarning(lcPropagateRemoteMove) << "Could not set pin state of" << _item->_originalFile << "to inherited";
+ }
}
SyncFileItem newItem(*_item);
}
}
- const auto targetFile = propagator()->fullLocalPath(_item->_renameTarget);
if (!QFileInfo::exists(targetFile)) {
propagator()->_journal->commit("Remote Rename");
done(SyncFileItem::Success);
QVERIFY(fakeFolder.currentLocalState().find(fileWithSpaces));
QVERIFY(fakeFolder.currentLocalState().find(fileTrimmed));
}
+
+ void testCreateFileWithTrailingSpaces_localAndRemoteTrimmedExists_renameFile()
+ {
+ FakeFolder fakeFolder{FileInfo{}};
+ QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+ const QString fileWithSpaces1(" foo");
+ const QString fileWithSpaces2(" bar ");
+ const QString fileWithSpaces3("bla ");
+
+ fakeFolder.localModifier().insert(fileWithSpaces1);
+ fakeFolder.localModifier().insert(fileWithSpaces2);
+ fakeFolder.localModifier().insert(fileWithSpaces3);
+ fakeFolder.remoteModifier().insert(fileWithSpaces1);
+ fakeFolder.remoteModifier().insert(fileWithSpaces2);
+ fakeFolder.remoteModifier().insert(fileWithSpaces3);
+
+ QVERIFY(fakeFolder.syncOnce());
+
+ QVERIFY(fakeFolder.syncOnce());
+
+ QVERIFY(fakeFolder.syncOnce());
+
+ auto expectedState = fakeFolder.currentLocalState();
+ qDebug() << expectedState;
+ QCOMPARE(fakeFolder.currentRemoteState(), expectedState);
+ }
};
QTEST_GUILESS_MAIN(TestLocalDiscovery)