(uint64_t) fs->size, (uint64_t) tmp->size, fs->remotePerm, tmp->remotePerm, tmp->has_ignored_files );
if (ctx->current == REMOTE_REPLICA && !c_streq(fs->etag, tmp->etag)) {
st->instruction = CSYNC_INSTRUCTION_EVAL;
+
+ // Preserve the EVAL flag later on if the type has changed.
+ if (tmp->type != fs->type)
+ st->child_modified = 1;
+
goto out;
}
if (ctx->current == LOCAL_REPLICA &&
case CSYNC_INSTRUCTION_SYNC:
case CSYNC_INSTRUCTION_CONFLICT:
if (item->_isDirectory) {
+ // Did a file turn into a directory?
+ if (QFileInfo(getFilePath(item->_file)).isFile()) {
+ auto job = new PropagateLocalMkdir(this, item);
+ job->setDeleteExistingFile(true);
+ return job;
+ }
// Should we set the mtime?
return 0;
}
if (_propagator->_abortRequested.fetchAndAddRelaxed(0))
return;
- QDir newDir(_propagator->_localDir + _item->_file);
+ QDir newDir(_propagator->getFilePath(_item->_file));
QString newDirStr = QDir::toNativeSeparators(newDir.path());
+
+ // When turning something that used to be a file into a directory
+ // we need to delete the file first.
+ QFileInfo fi(newDirStr);
+ if (_deleteExistingFile && fi.exists() && fi.isFile()) {
+#ifdef Q_OS_WIN
+ // On Windows, write only files cannot be deleted.
+ if (!fi.isWritable()) {
+ FileSystem::setFileReadOnlyWeak(newDirStr, false);
+ }
+#endif
+
+ QFile f(newDirStr);
+ if (!f.remove()) {
+ done( SyncFileItem::NormalError,
+ tr("could not delete file %1, error: %2")
+ .arg(newDirStr, f.errorString()));
+ return;
+ }
+ }
+
if( Utility::fsCasePreserving() && _propagator->localFileNameClash(_item->_file ) ) {
qDebug() << "WARN: new folder to create locally already exists!";
done( SyncFileItem::NormalError, tr("Attention, possible case sensitivity clash with %1").arg(newDirStr) );
done(SyncFileItem::Success);
}
+void PropagateLocalMkdir::setDeleteExistingFile(bool enabled)
+{
+ _deleteExistingFile = enabled;
+}
+
void PropagateLocalRename::start()
{
if (_propagator->_abortRequested.fetchAndAddRelaxed(0))
class PropagateLocalMkdir : public PropagateItemJob {
Q_OBJECT
public:
- PropagateLocalMkdir (OwncloudPropagator* propagator,const SyncFileItemPtr& item) : PropagateItemJob(propagator, item) {}
+ PropagateLocalMkdir (OwncloudPropagator* propagator,const SyncFileItemPtr& item)
+ : PropagateItemJob(propagator, item), _deleteExistingFile(false) {}
void start() Q_DECL_OVERRIDE;
+ /**
+ * Whether an existing file with the same name may be deleted before
+ * creating the directory.
+ *
+ * Default: false.
+ */
+ void setDeleteExistingFile(bool enabled);
+
+private:
+ bool _deleteExistingFile;
};
/**