diff options
author | Matthieu Gallien <matthieu.gallien@nextcloud.com> | 2022-02-01 21:15:37 +0300 |
---|---|---|
committer | Matthieu Gallien (Rebase PR Action) <matthieu_gallien@yahoo.fr> | 2022-02-08 00:32:05 +0300 |
commit | e89268bdd7b656939f2ddd070ab93bd52f751ae8 (patch) | |
tree | a98061a61a61f0620d0c02b80b14a550098c4701 /src/libsync | |
parent | 9116589513e12a9adeacd19630eb123da1a9a436 (diff) |
ensure we emit a rename command for renamed files
Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
Diffstat (limited to 'src/libsync')
-rw-r--r-- | src/libsync/discovery.cpp | 74 | ||||
-rw-r--r-- | src/libsync/discoveryphase.h | 1 | ||||
-rw-r--r-- | src/libsync/propagateremotemove.cpp | 11 | ||||
-rw-r--r-- | src/libsync/propagateupload.cpp | 20 |
4 files changed, 73 insertions, 33 deletions
diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index 01cd608cd..ded16cc98 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -41,7 +41,7 @@ Q_LOGGING_CATEGORY(lcDisco, "sync.discovery", QtInfoMsg) bool ProcessDirectoryJob::checkForInvalidFileName(const PathTuple &path, const std::map<QString, Entries> &entries, Entries &entry) { - const auto originalFileName = entry.localEntry.name; + const auto originalFileName = entry.localEntry.isValid() ? entry.localEntry.name : entry.serverEntry.name; const auto newFileName = originalFileName.trimmed(); if (originalFileName == newFileName) { @@ -61,7 +61,7 @@ bool ProcessDirectoryJob::checkForInvalidFileName(const PathTuple &path, if (!errorMessage.isEmpty()) { auto item = SyncFileItemPtr::create(); - if (entry.localEntry.isDirectory) { + if ((entry.localEntry.isValid() && entry.localEntry.isDirectory) || (entry.serverEntry.isValid() && entry.serverEntry.isDirectory)) { item->_type = CSyncEnums::ItemTypeDirectory; } else { item->_type = CSyncEnums::ItemTypeFile; @@ -76,7 +76,11 @@ bool ProcessDirectoryJob::checkForInvalidFileName(const PathTuple &path, } } - entry.localEntry.renameName = newFileName; + if (entry.localEntry.isValid()) { + entry.localEntry.renameName = newFileName; + } else { + entry.serverEntry.renameName = newFileName; + } return true; } @@ -389,13 +393,6 @@ void ProcessDirectoryJob::processFile(PathTuple path, item->_originalFile = path._original; item->_previousSize = dbEntry._fileSize; item->_previousModtime = dbEntry._modtime; - if (!localEntry.renameName.isEmpty()) { - if (_dirItem) { - item->_renameTarget = _dirItem->_file + "/" + localEntry.renameName; - } else { - item->_renameTarget = localEntry.renameName; - } - } if (dbEntry._modtime == localEntry.modtime && dbEntry._type == ItemTypeVirtualFile && localEntry.type == ItemTypeFile) { item->_type = ItemTypeFile; @@ -602,6 +599,22 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo( // Unknown in db: new file on the server Q_ASSERT(!dbEntry.isValid()); + if (!serverEntry.renameName.isEmpty()) { + item->_renameTarget = _dirItem ? _dirItem->_file + "/" + serverEntry.renameName : serverEntry.renameName; + item->_originalFile = path._original; + item->_modtime = serverEntry.modtime; + item->_size = serverEntry.size; + item->_instruction = CSYNC_INSTRUCTION_RENAME; + item->_direction = SyncFileItem::Up; + item->_fileId = serverEntry.fileId; + item->_remotePerm = serverEntry.remotePerm; + item->_etag = serverEntry.etag; + item->_type = serverEntry.isDirectory ? CSyncEnums::ItemTypeDirectory : CSyncEnums::ItemTypeFile; + + processFileAnalyzeLocalInfo(item, path, localEntry, serverEntry, dbEntry, _queryServer); + return; + } + item->_instruction = CSYNC_INSTRUCTION_NEW; item->_direction = SyncFileItem::Down; item->_modtime = serverEntry.modtime; @@ -1005,6 +1018,42 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo( return; } + 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; + + finalize(); + return; + } + // New local file or rename item->_instruction = CSYNC_INSTRUCTION_NEW; item->_direction = SyncFileItem::Up; @@ -1341,10 +1390,11 @@ void ProcessDirectoryJob::processFileFinalize( if (isVfsWithSuffix()) { if (item->_type == ItemTypeVirtualFile) { addVirtualFileSuffix(path._target); - if (item->_instruction == CSYNC_INSTRUCTION_RENAME) + if (item->_instruction == CSYNC_INSTRUCTION_RENAME) { addVirtualFileSuffix(item->_renameTarget); - else + } else { addVirtualFileSuffix(item->_file); + } } if (item->_type == ItemTypeVirtualFileDehydration && item->_instruction == CSYNC_INSTRUCTION_SYNC) { diff --git a/src/libsync/discoveryphase.h b/src/libsync/discoveryphase.h index c894cfc2a..f5950e8dc 100644 --- a/src/libsync/discoveryphase.h +++ b/src/libsync/discoveryphase.h @@ -49,6 +49,7 @@ struct RemoteInfo { /** FileName of the entry (this does not contains any directory or path, just the plain name */ QString name; + QString renameName; QByteArray etag; QByteArray fileId; QByteArray checksumHeader; diff --git a/src/libsync/propagateremotemove.cpp b/src/libsync/propagateremotemove.cpp index edd29306c..5f5cdd06e 100644 --- a/src/libsync/propagateremotemove.cpp +++ b/src/libsync/propagateremotemove.cpp @@ -19,6 +19,7 @@ #include "common/syncjournalfilerecord.h" #include "filesystem.h" #include "common/asserts.h" +#include <QFileInfo> #include <QFile> #include <QStringList> #include <QDir> @@ -79,7 +80,7 @@ void PropagateRemoteMove::start() return; QString origin = propagator()->adjustRenamedPath(_item->_file); - qCDebug(lcPropagateRemoteMove) << origin << _item->_renameTarget; + qCInfo(lcPropagateRemoteMove) << origin << _item->_renameTarget; QString targetFile(propagator()->fullLocalPath(_item->_renameTarget)); @@ -254,6 +255,14 @@ void PropagateRemoteMove::finalize() newItem._size = oldRecord._fileSize; } } + + const auto targetFile = propagator()->fullLocalPath(_item->_renameTarget); + if (!QFileInfo::exists(targetFile)) { + propagator()->_journal->commit("Remote Rename"); + done(SyncFileItem::Success); + return; + } + const auto result = propagator()->updateMetadata(newItem); if (!result) { done(SyncFileItem::FatalError, tr("Error updating metadata: %1").arg(result.error())); diff --git a/src/libsync/propagateupload.cpp b/src/libsync/propagateupload.cpp index cf4e4fc7c..7a6a124ed 100644 --- a/src/libsync/propagateupload.cpp +++ b/src/libsync/propagateupload.cpp @@ -198,26 +198,6 @@ void PropagateUploadFileCommon::start() const auto slashPosition = path.lastIndexOf('/'); const auto parentPath = slashPosition >= 0 ? path.left(slashPosition) : QString(); - - if (!_item->_renameTarget.isEmpty() && _item->_file != _item->_renameTarget) { - // Try to rename the file - const auto originalFilePathAbsolute = propagator()->fullLocalPath(_item->_file); - const auto newFilePathAbsolute = propagator()->fullLocalPath(_item->_renameTarget); - const auto renameSuccess = QFile::rename(originalFilePathAbsolute, newFilePathAbsolute); - if (!renameSuccess) { - done(SyncFileItem::NormalError, "File contains trailing spaces and couldn't be renamed"); - return; - } - _item->_file = _item->_renameTarget; - _item->_modtime = FileSystem::getModTime(newFilePathAbsolute); - Q_ASSERT(_item->_modtime > 0); - if (_item->_modtime <= 0) { - qCWarning(lcPropagateUpload()) << "invalid modified time" << _item->_file << _item->_modtime; - slotOnErrorStartFolderUnlock(SyncFileItem::NormalError, tr("File %1 has invalid modified time. Do not upload to the server.").arg(QDir::toNativeSeparators(_item->_file))); - return; - } - } - SyncJournalFileRecord parentRec; bool ok = propagator()->_journal->getFileRecord(parentPath, &parentRec); if (!ok) { |