Move: Fix move detection in directory move on the other side
authorOlivier Goffart <ogoffart@woboq.com>
Fri, 18 Jan 2019 11:27:46 +0000 (12:27 +0100)
committerKevin Ottens <kevin.ottens@nextcloud.com>
Tue, 15 Dec 2020 09:58:35 +0000 (10:58 +0100)
src/libsync/discovery.cpp
test/testsyncmove.cpp

index 3c74e6a08c378b89871599a96169dd46a724abd6..14d00bc5c45a3cd8e014452926f724b61538e769 100644 (file)
@@ -503,10 +503,12 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
             return;
         }
 
+        QString originalPathAdjusted = _discoveryData->adjustRenamedPath(originalPath, SyncFileItem::Up);
+
         if (!base.isDirectory()) {
             csync_file_stat_t buf;
-            if (csync_vio_local_stat((_discoveryData->_localDir + originalPath).toUtf8(), &buf)) {
-                qCInfo(lcDisco) << "Local file does not exist anymore." << originalPath;
+            if (csync_vio_local_stat((_discoveryData->_localDir + originalPathAdjusted).toUtf8(), &buf)) {
+                qCInfo(lcDisco) << "Local file does not exist anymore." << originalPathAdjusted;
                 return;
             }
             // NOTE: This prohibits some VFS renames from being detected since
@@ -516,8 +518,8 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
                 return;
             }
         } else {
-            if (!QFileInfo(_discoveryData->_localDir + originalPath).isDir()) {
-                qCInfo(lcDisco) << "Local directory does not exist anymore." << originalPath;
+            if (!QFileInfo(_discoveryData->_localDir + originalPathAdjusted).isDir()) {
+                qCInfo(lcDisco) << "Local directory does not exist anymore." << originalPathAdjusted;
                 return;
             }
         }
@@ -856,7 +858,7 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
         } else {
             // We must query the server to know if the etag has not changed
             _pendingAsyncJobs++;
-            QString serverOriginalPath = originalPath;
+            QString serverOriginalPath = _discoveryData->adjustRenamedPath(originalPath, SyncFileItem::Down);
             if (base.isVirtualFile() && isVfsWithSuffix())
                 chopVirtualFileSuffix(serverOriginalPath);
             auto job = new RequestEtagJob(_discoveryData->_account, serverOriginalPath, this);
index d885bfbc14e4bf6fde49742dd038d7e929ca6ad5..7933039e6d4418be2686f4e357fcb2b105c2a984 100644 (file)
@@ -729,7 +729,45 @@ private slots:
         // There was 5 inserts
         QCOMPARE(counter.nGET, local ? 0 : 5);
         QCOMPARE(counter.nPUT, local ? 5 : 0);
+    }
+
+    void renameOnBothSides()
+    {
+        FakeFolder fakeFolder { FileInfo::A12_B12_C12_S12() };
+        OperationCounter counter;
+        fakeFolder.setServerOverride(counter.functor());
 
+        // Test that renaming a file within a directory that was renamed on the other side actually do a rename.
+
+        // 1) move the folder alphabeticaly before
+        fakeFolder.remoteModifier().rename("A/a1", "A/a1m");
+        fakeFolder.localModifier().rename("A", "_A");
+        fakeFolder.localModifier().rename("B/b1", "B/b1m");
+        fakeFolder.remoteModifier().rename("B", "_B");
+
+        QVERIFY(fakeFolder.syncOnce());
+        QCOMPARE(fakeFolder.currentRemoteState(), fakeFolder.currentRemoteState());
+        QVERIFY(fakeFolder.currentRemoteState().find("_A/a1m"));
+        QVERIFY(fakeFolder.currentRemoteState().find("_B/b1m"));
+        QCOMPARE(counter.nDELETE, 0);
+        QCOMPARE(counter.nGET, 0);
+        QCOMPARE(counter.nPUT, 0);
+        QCOMPARE(counter.nMOVE, 2);
+        counter.reset();
+
+        // 2) move alphabetically after
+        fakeFolder.remoteModifier().rename("_A/a2", "_A/a2m");
+        fakeFolder.localModifier().rename("_B/b2", "_B/b2m");
+        fakeFolder.localModifier().rename("_A", "S/A");
+        fakeFolder.remoteModifier().rename("_B", "S/B");
+        QVERIFY(fakeFolder.syncOnce());
+        QCOMPARE(fakeFolder.currentRemoteState(), fakeFolder.currentRemoteState());
+        QVERIFY(fakeFolder.currentRemoteState().find("S/A/a2m"));
+        QVERIFY(fakeFolder.currentRemoteState().find("S/B/b2m"));
+        QCOMPARE(counter.nDELETE, 0);
+        QCOMPARE(counter.nGET, 0);
+        QCOMPARE(counter.nPUT, 0);
+        QCOMPARE(counter.nMOVE, 2);
     }
 };