mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-25 06:25:56 +03:00
Merge pull request #5188 from nextcloud/bugfix/properlyUpdateMetadata
check that we update local file mtime on changes from server
This commit is contained in:
commit
6d5db8fd95
7 changed files with 62 additions and 12 deletions
|
@ -1871,7 +1871,7 @@ bool ProcessDirectoryJob::isVfsWithSuffix() const
|
||||||
void ProcessDirectoryJob::computePinState(PinState parentState)
|
void ProcessDirectoryJob::computePinState(PinState parentState)
|
||||||
{
|
{
|
||||||
_pinState = parentState;
|
_pinState = parentState;
|
||||||
if (_queryLocal != ParentDontExist) {
|
if (_queryLocal != ParentDontExist && QFileInfo::exists(_discoveryData->_localDir + _currentFolder._local)) {
|
||||||
if (auto state = _discoveryData->_syncOptions._vfs->pinState(_currentFolder._local)) // ouch! pin local or original?
|
if (auto state = _discoveryData->_syncOptions._vfs->pinState(_currentFolder._local)) // ouch! pin local or original?
|
||||||
_pinState = *state;
|
_pinState = *state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -251,7 +251,7 @@ void PropagateRemoteMove::finalize()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto &vfs = propagator()->syncOptions()._vfs;
|
auto &vfs = propagator()->syncOptions()._vfs;
|
||||||
auto pinState = vfs->pinState(_item->_originalFile);
|
auto pinState = vfs->pinState(_item->_renameTarget);
|
||||||
|
|
||||||
const auto targetFile = propagator()->fullLocalPath(_item->_renameTarget);
|
const auto targetFile = propagator()->fullLocalPath(_item->_renameTarget);
|
||||||
|
|
||||||
|
|
|
@ -222,11 +222,19 @@ void PropagateLocalRename::start()
|
||||||
if (propagator()->_abortRequested)
|
if (propagator()->_abortRequested)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
auto &vfs = propagator()->syncOptions()._vfs;
|
||||||
const auto previousNameInDb = propagator()->adjustRenamedPath(_item->_file);
|
const auto previousNameInDb = propagator()->adjustRenamedPath(_item->_file);
|
||||||
const auto existingFile = propagator()->fullLocalPath(propagator()->adjustRenamedPath(_item->_file));
|
const auto existingFile = propagator()->fullLocalPath(propagator()->adjustRenamedPath(_item->_file));
|
||||||
const auto targetFile = propagator()->fullLocalPath(_item->_renameTarget);
|
const auto targetFile = propagator()->fullLocalPath(_item->_renameTarget);
|
||||||
|
|
||||||
const auto fileAlreadyMoved = !QFileInfo::exists(propagator()->fullLocalPath(_item->_originalFile));
|
const auto fileAlreadyMoved = !QFileInfo::exists(propagator()->fullLocalPath(_item->_originalFile));
|
||||||
|
auto pinState = OCC::PinState::Unspecified;
|
||||||
|
if (!fileAlreadyMoved) {
|
||||||
|
auto pinStateResult = vfs->pinState(propagator()->adjustRenamedPath(_item->_file));
|
||||||
|
if (pinStateResult) {
|
||||||
|
pinState = pinStateResult.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if the file is a file underneath a moved dir, the _item->file is equal
|
// if the file is a file underneath a moved dir, the _item->file is equal
|
||||||
// to _item->renameTarget and the file is not moved as a result.
|
// to _item->renameTarget and the file is not moved as a result.
|
||||||
|
@ -269,10 +277,10 @@ void PropagateLocalRename::start()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &vfs = propagator()->syncOptions()._vfs;
|
if (pinState != OCC::PinState::Unspecified && !vfs->setPinState(_item->_renameTarget, pinState)) {
|
||||||
auto pinState = vfs->pinState(_item->_originalFile);
|
qCWarning(lcPropagateLocalRename) << "Could not set pin state of" << _item->_renameTarget << "to old value" << pinState;
|
||||||
if (!vfs->setPinState(_item->_originalFile, PinState::Inherited)) {
|
done(SyncFileItem::NormalError, tr("Error setting pin state"));
|
||||||
qCWarning(lcPropagateLocalRename) << "Could not set pin state of" << _item->_originalFile << "to inherited";
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto oldFile = _item->_file;
|
const auto oldFile = _item->_file;
|
||||||
|
@ -331,11 +339,6 @@ void PropagateLocalRename::start()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pinState && *pinState != PinState::Inherited
|
|
||||||
&& !vfs->setPinState(_item->_renameTarget, *pinState)) {
|
|
||||||
done(SyncFileItem::NormalError, tr("Error setting pin state"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
propagator()->_journal->commit("localRename");
|
propagator()->_journal->commit("localRename");
|
||||||
|
|
||||||
|
|
|
@ -377,6 +377,13 @@ void OCC::SyncEngine::slotItemDiscovered(const OCC::SyncFileItemPtr &item)
|
||||||
emit itemCompleted(item);
|
emit itemCompleted(item);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (!FileSystem::setModTime(filePath, item->_modtime)) {
|
||||||
|
item->_instruction = CSYNC_INSTRUCTION_ERROR;
|
||||||
|
item->_errorString = tr("Could not update file metadata: %1").arg(filePath);
|
||||||
|
emit itemCompleted(item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updating the db happens on success
|
// Updating the db happens on success
|
||||||
|
|
|
@ -1209,7 +1209,7 @@ void FakeFolder::fromDisk(QDir &dir, FileInfo &templateFi)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
char contentChar = content.at(0);
|
char contentChar = content.at(0);
|
||||||
templateFi.children.insert(diskChild.fileName(), FileInfo { diskChild.fileName(), diskChild.size(), contentChar });
|
templateFi.children.insert(diskChild.fileName(), FileInfo{diskChild.fileName(), diskChild.size(), contentChar, diskChild.lastModified()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,6 +117,7 @@ public:
|
||||||
FileInfo(const QString &name) : name{name} { }
|
FileInfo(const QString &name) : name{name} { }
|
||||||
FileInfo(const QString &name, qint64 size) : name{name}, isDir{false}, size{size} { }
|
FileInfo(const QString &name, qint64 size) : name{name}, isDir{false}, size{size} { }
|
||||||
FileInfo(const QString &name, qint64 size, char contentChar) : name{name}, isDir{false}, size{size}, contentChar{contentChar} { }
|
FileInfo(const QString &name, qint64 size, char contentChar) : name{name}, isDir{false}, size{size}, contentChar{contentChar} { }
|
||||||
|
FileInfo(const QString &name, qint64 size, char contentChar, QDateTime mtime) : name{name}, isDir{false}, lastModified(mtime), size{size}, contentChar{contentChar} { }
|
||||||
FileInfo(const QString &name, const std::initializer_list<FileInfo> &children);
|
FileInfo(const QString &name, const std::initializer_list<FileInfo> &children);
|
||||||
|
|
||||||
void addChild(const FileInfo &info);
|
void addChild(const FileInfo &info);
|
||||||
|
|
|
@ -1243,6 +1243,45 @@ private slots:
|
||||||
auto expectedState = fakeFolder.currentLocalState();
|
auto expectedState = fakeFolder.currentLocalState();
|
||||||
QCOMPARE(fakeFolder.currentRemoteState(), expectedState);
|
QCOMPARE(fakeFolder.currentRemoteState(), expectedState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void testServerUpdatingMTimeShouldNotCreateConflicts()
|
||||||
|
{
|
||||||
|
constexpr auto testFile = "test.txt";
|
||||||
|
constexpr auto CURRENT_MTIME = 1646057277;
|
||||||
|
|
||||||
|
FakeFolder fakeFolder{ FileInfo{} };
|
||||||
|
|
||||||
|
fakeFolder.remoteModifier().insert(testFile);
|
||||||
|
fakeFolder.remoteModifier().setModTimeKeepEtag(testFile, QDateTime::fromSecsSinceEpoch(CURRENT_MTIME - 2));
|
||||||
|
|
||||||
|
fakeFolder.syncEngine().setLocalDiscoveryOptions(OCC::LocalDiscoveryStyle::DatabaseAndFilesystem);
|
||||||
|
QVERIFY(fakeFolder.syncOnce());
|
||||||
|
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
|
||||||
|
QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(fakeFolder.currentRemoteState()));
|
||||||
|
const auto fileFirstSync = fakeFolder.currentLocalState().find(testFile);
|
||||||
|
QVERIFY(fileFirstSync);
|
||||||
|
QCOMPARE(fileFirstSync->lastModified.toSecsSinceEpoch(), CURRENT_MTIME - 2);
|
||||||
|
|
||||||
|
fakeFolder.remoteModifier().setModTimeKeepEtag(testFile, QDateTime::fromSecsSinceEpoch(CURRENT_MTIME - 1));
|
||||||
|
|
||||||
|
fakeFolder.syncEngine().setLocalDiscoveryOptions(OCC::LocalDiscoveryStyle::FilesystemOnly);
|
||||||
|
QVERIFY(fakeFolder.syncOnce());
|
||||||
|
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
|
||||||
|
QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(fakeFolder.currentRemoteState()));
|
||||||
|
const auto fileSecondSync = fakeFolder.currentLocalState().find(testFile);
|
||||||
|
QVERIFY(fileSecondSync);
|
||||||
|
QCOMPARE(fileSecondSync->lastModified.toSecsSinceEpoch(), CURRENT_MTIME - 1);
|
||||||
|
|
||||||
|
fakeFolder.remoteModifier().setModTime(testFile, QDateTime::fromSecsSinceEpoch(CURRENT_MTIME));
|
||||||
|
|
||||||
|
fakeFolder.syncEngine().setLocalDiscoveryOptions(OCC::LocalDiscoveryStyle::FilesystemOnly);
|
||||||
|
QVERIFY(fakeFolder.syncOnce());
|
||||||
|
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
|
||||||
|
QCOMPARE(printDbData(fakeFolder.dbState()), printDbData(fakeFolder.currentRemoteState()));
|
||||||
|
const auto fileThirdSync = fakeFolder.currentLocalState().find(testFile);
|
||||||
|
QVERIFY(fileThirdSync);
|
||||||
|
QCOMPARE(fileThirdSync->lastModified.toSecsSinceEpoch(), CURRENT_MTIME);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestSyncEngine)
|
QTEST_GUILESS_MAIN(TestSyncEngine)
|
||||||
|
|
Loading…
Reference in a new issue