diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index 1e276ad68957..dfcb37d29001 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -1085,14 +1085,6 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo( qCWarning(lcDisco) << "Failed to delete a file record from the local DB" << path._original; } return; - } else if (dbEntry._type == ItemTypeVirtualFile && isVfsWithSuffix()) { - // If the virtual file is removed, recreate it. - // This is a precaution since the suffix files don't look like the real ones - // and we don't want users to accidentally delete server data because they - // might not expect that deleting the placeholder will have a remote effect. - item->_instruction = CSYNC_INSTRUCTION_NEW; - item->_direction = SyncFileItem::Down; - item->_type = ItemTypeVirtualFile; } else if (!serverModified) { // Removed locally: also remove on the server. if (!dbEntry._serverHasIgnoredFiles) { diff --git a/src/libsync/propagateremotedelete.cpp b/src/libsync/propagateremotedelete.cpp index 306ed4b1d73b..7bc5be952888 100644 --- a/src/libsync/propagateremotedelete.cpp +++ b/src/libsync/propagateremotedelete.cpp @@ -58,12 +58,19 @@ void PropagateRemoteDelete::start() void PropagateRemoteDelete::createDeleteJob(const QString &filename) { - qCInfo(lcPropagateRemoteDelete) << "Deleting file, local" << _item->_file << "remote" << filename; + Q_ASSERT(propagator()); + auto remoteFilename = filename; + if (_item->_type == ItemType::ItemTypeVirtualFile) { + if (const auto vfs = propagator()->syncOptions()._vfs; vfs->mode() == Vfs::Mode::WithSuffix) { + // These are compile-time constants so no need to recreate each time + static constexpr auto suffixSize = std::string_view(APPLICATION_DOTVIRTUALFILE_SUFFIX).size(); + remoteFilename.chop(suffixSize); + } + } - _job = new DeleteJob(propagator()->account(), - propagator()->fullRemotePath(filename), - this); + qCInfo(lcPropagateRemoteDelete) << "Deleting file, local" << _item->_file << "remote" << remoteFilename; + _job = new DeleteJob(propagator()->account(), propagator()->fullRemotePath(remoteFilename), this); connect(_job.data(), &DeleteJob::finishedSignal, this, &PropagateRemoteDelete::slotDeleteJobFinished); propagator()->_activeJobList.append(this); _job->start(); diff --git a/test/testsyncvirtualfiles.cpp b/test/testsyncvirtualfiles.cpp index 44759da6ad5d..c90a55e322f6 100644 --- a/test/testsyncvirtualfiles.cpp +++ b/test/testsyncvirtualfiles.cpp @@ -175,17 +175,27 @@ private slots: QCOMPARE(dbRecord(fakeFolder, "A/a1" DVSUFFIX)._fileSize, 65); cleanup(); - // If the local virtual file file is removed, it'll just be recreated + // If the local virtual file is removed, it should be gone remotely too if (!doLocalDiscovery) fakeFolder.syncEngine().setLocalDiscoveryOptions(LocalDiscoveryStyle::DatabaseAndFilesystem, { "A" }); fakeFolder.localModifier().remove("A/a1" DVSUFFIX); QVERIFY(fakeFolder.syncOnce()); QVERIFY(!fakeFolder.currentLocalState().find("A/a1")); + QVERIFY(!fakeFolder.currentLocalState().find("A/a1" DVSUFFIX)); + QVERIFY(!fakeFolder.remoteModifier().find("A/a1")); + cleanup(); + + // Restore the state prior to next test + // Essentially repeating creation of virtual file + fakeFolder.remoteModifier().insert("A/a1", 64); + fakeFolder.remoteModifier().setModTime("A/a1", someDate); + QVERIFY(fakeFolder.syncOnce()); + QVERIFY(!fakeFolder.currentLocalState().find("A/a1")); QVERIFY(fakeFolder.currentLocalState().find("A/a1" DVSUFFIX)); + QCOMPARE(QFileInfo(fakeFolder.localPath() + "A/a1" DVSUFFIX).lastModified(), someDate); QVERIFY(fakeFolder.currentRemoteState().find("A/a1")); QVERIFY(itemInstruction(completeSpy, "A/a1" DVSUFFIX, CSYNC_INSTRUCTION_NEW)); QCOMPARE(dbRecord(fakeFolder, "A/a1" DVSUFFIX)._type, ItemTypeVirtualFile); - QCOMPARE(dbRecord(fakeFolder, "A/a1" DVSUFFIX)._fileSize, 65); cleanup(); // Remote rename is propagated