From a6c19572a226980e04bec093512e6ae9d033a8c9 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Tue, 29 May 2018 13:16:58 +0200 Subject: [PATCH] Virtual files: Only remove virtual file once on download With thanks to @ogoffart for spotting the problem. --- src/csync/csync_reconcile.cpp | 19 +++++++++++++++++++ test/testsyncvirtualfiles.cpp | 8 ++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/csync/csync_reconcile.cpp b/src/csync/csync_reconcile.cpp index 4c884083a..54a4ac271 100644 --- a/src/csync/csync_reconcile.cpp +++ b/src/csync/csync_reconcile.cpp @@ -185,6 +185,25 @@ static void _csync_merge_algorithm_visitor(csync_file_stat_t *cur, CSYNC * ctx) cur->instruction = CSYNC_INSTRUCTION_NEW; break; } + + /* If a virtual file is supposed to be downloaded, the local tree + * will see "foo.owncloud" NONE while the remote might see "foo". + * In the common case of remote NEW we don't want to trigger the REMOVE + * that would normally be done for foo.owncloud since the download for + * "foo" will take care of it. + * If it was removed remotely, or moved remotely, the REMOVE is what we want. + */ + if (cur->type == ItemTypeVirtualFileDownload + && ctx->current == LOCAL_REPLICA + && cur->path.endsWith(ctx->virtual_file_suffix)) { + auto actualOther = other_tree->findFile(cur->path.left(cur->path.size() - ctx->virtual_file_suffix.size())); + if (actualOther + && (actualOther->instruction == CSYNC_INSTRUCTION_NEW + || actualOther->instruction == CSYNC_INSTRUCTION_CONFLICT)) { + cur->instruction = CSYNC_INSTRUCTION_NONE; + break; + } + } cur->instruction = CSYNC_INSTRUCTION_REMOVE; break; case CSYNC_INSTRUCTION_EVAL_RENAME: { diff --git a/test/testsyncvirtualfiles.cpp b/test/testsyncvirtualfiles.cpp index 8ec09a6f8..ba162836f 100644 --- a/test/testsyncvirtualfiles.cpp +++ b/test/testsyncvirtualfiles.cpp @@ -330,14 +330,14 @@ private slots: fakeFolder.localModifier().remove("A/a6.owncloud"); QVERIFY(fakeFolder.syncOnce()); QVERIFY(itemInstruction(completeSpy, "A/a1", CSYNC_INSTRUCTION_NEW)); - QVERIFY(itemInstruction(completeSpy, "A/a1.owncloud", CSYNC_INSTRUCTION_REMOVE)); + QVERIFY(itemInstruction(completeSpy, "A/a1.owncloud", CSYNC_INSTRUCTION_NONE)); QVERIFY(itemInstruction(completeSpy, "A/a2", CSYNC_INSTRUCTION_NEW)); - QVERIFY(itemInstruction(completeSpy, "A/a2.owncloud", CSYNC_INSTRUCTION_REMOVE)); + QVERIFY(itemInstruction(completeSpy, "A/a2.owncloud", CSYNC_INSTRUCTION_NONE)); QVERIFY(itemInstruction(completeSpy, "A/a3.owncloud", CSYNC_INSTRUCTION_REMOVE)); - QVERIFY(itemInstruction(completeSpy, "A/a4.owncloud", CSYNC_INSTRUCTION_REMOVE)); QVERIFY(itemInstruction(completeSpy, "A/a4m", CSYNC_INSTRUCTION_NEW)); + QVERIFY(itemInstruction(completeSpy, "A/a4.owncloud", CSYNC_INSTRUCTION_REMOVE)); QVERIFY(itemInstruction(completeSpy, "A/a5", CSYNC_INSTRUCTION_CONFLICT)); - QVERIFY(itemInstruction(completeSpy, "A/a5.owncloud", CSYNC_INSTRUCTION_REMOVE)); + QVERIFY(itemInstruction(completeSpy, "A/a5.owncloud", CSYNC_INSTRUCTION_NONE)); QVERIFY(itemInstruction(completeSpy, "A/a6", CSYNC_INSTRUCTION_CONFLICT)); QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); QCOMPARE(dbRecord(fakeFolder, "A/a1")._type, ItemTypeFile); -- 2.30.2