зеркало из https://github.com/nextcloud/desktop.git
Merge branch '1.5'
This commit is contained in:
Коммит
93f31fa9d7
|
@ -114,25 +114,28 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
|||
|
||||
if( tmp ) {
|
||||
if( tmp->path ) {
|
||||
/* Find the temporar file in the other tree. */
|
||||
len = strlen( tmp->path );
|
||||
h = c_jhash64((uint8_t *) tmp->path, len, 0);
|
||||
node = c_rbtree_find(tree, &h);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "PHash of temporary opposite (%s): %" PRIu64 " %s",
|
||||
tmp->path , h, node ? "found": "not found" );
|
||||
if (!node) {
|
||||
/* the renamed file could not be found in the opposite tree. That is because it
|
||||
* is not longer existing there, maybe because it was renamed or deleted.
|
||||
* The journal is cleaned up later after propagation.
|
||||
*/
|
||||
|
||||
/* First, check that the file is NOT in our tree (another file with the same name was added) */
|
||||
node = c_rbtree_find(ctx->current == REMOTE_REPLICA ? ctx->remote.tree : ctx->local.tree, &h);
|
||||
if (node) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Origin found in our tree : %s", tmp->path);
|
||||
} else {
|
||||
/* Find the temporar file in the other tree. */
|
||||
node = c_rbtree_find(tree, &h);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "PHash of temporary opposite (%s): %" PRIu64 " %s",
|
||||
tmp->path , h, node ? "found": "not found" );
|
||||
if (node) {
|
||||
other = (csync_file_stat_t*)node->data;
|
||||
} else {
|
||||
/* the renamed file could not be found in the opposite tree. That is because it
|
||||
* is not longer existing there, maybe because it was renamed or deleted.
|
||||
* The journal is cleaned up later after propagation.
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(node) {
|
||||
other = (csync_file_stat_t*)node->data;
|
||||
}
|
||||
|
||||
if(!other) {
|
||||
cur->instruction = CSYNC_INSTRUCTION_NEW;
|
||||
} else if (other->instruction == CSYNC_INSTRUCTION_NONE
|
||||
|
@ -159,9 +162,7 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
|||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
other->instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
}
|
||||
|
||||
SAFE_FREE(tmp->etag);
|
||||
SAFE_FREE(tmp);
|
||||
csync_file_stat_free(tmp);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -79,6 +79,7 @@ system( "echo \"super new\" >> " . localDir() . 'newdir/myfile.txt' );
|
|||
#Add some files for the next test.
|
||||
system( "echo \"un\" > " . localDir() . '1.txt' );
|
||||
system( "echo \"deux\" > " . localDir() . '2.txt' );
|
||||
system( "echo \"trois\" > " . localDir() . '3.txt' );
|
||||
mkdir( localDir() . 'newdir2' );
|
||||
|
||||
csync();
|
||||
|
@ -105,6 +106,17 @@ my $newdir4Id = remoteFileId( localDir(), 'newdir4' );
|
|||
assert( $newdirId eq $newdir3Id, "newdir was not MOVE'd to newdir3?" );
|
||||
assert( $newdir2Id eq $newdir4Id, "newdir2 was not MOVE'd to newdir4?" );
|
||||
|
||||
printInfo("Move a file and replace it by a new one");
|
||||
|
||||
|
||||
move( localDir() . '1.txt', localDir() . '1_bis.txt' );
|
||||
move( localDir() . '3.txt', localDir() . '3_bis.txt' );
|
||||
system( "echo \"new file un\" > " . localDir() . '1.txt' );
|
||||
system( "echo \"new file trois\" > " . localDir() . '3.txt' );
|
||||
|
||||
csync();
|
||||
assertLocalAndRemoteDir( '', 0);
|
||||
|
||||
|
||||
cleanup();
|
||||
|
||||
|
|
|
@ -100,18 +100,36 @@ void PropagateItemJob::done(SyncFileItem::Status status, const QString &errorStr
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* For delete or remove, check that we are not removing from a shared directory.
|
||||
* If we are, try to restore the file
|
||||
*
|
||||
* Return true if the problem is handled.
|
||||
*/
|
||||
bool PropagateItemJob::checkForProblemsWithShared()
|
||||
{
|
||||
QString errorString = QString::fromUtf8(ne_get_error(_propagator->_session));
|
||||
int httpStatusCode = errorString.mid(0, errorString.indexOf(QChar(' '))).toInt();
|
||||
|
||||
if( httpStatusCode == 403 && _propagator->isInSharedDirectory(_item._file )) {
|
||||
// the file was removed locally from a read only Shared sync
|
||||
// the file is gone locally and it should be recovered.
|
||||
SyncFileItem downloadItem(_item);
|
||||
downloadItem._instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
downloadItem._dir = SyncFileItem::Down;
|
||||
_restoreJob.reset(new PropagateDownloadFile(_propagator, downloadItem));
|
||||
if( _item._type != SyncFileItem::Directory ) {
|
||||
// the file was removed locally from a read only Shared sync
|
||||
// the file is gone locally and it should be recovered.
|
||||
SyncFileItem downloadItem(_item);
|
||||
downloadItem._instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
downloadItem._dir = SyncFileItem::Down;
|
||||
_restoreJob.reset(new PropagateDownloadFile(_propagator, downloadItem));
|
||||
} else {
|
||||
// Directories are harder to recover.
|
||||
// But just re-create the directory, next sync will be able to recover the files
|
||||
SyncFileItem mkdirItem(_item);
|
||||
mkdirItem._instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
mkdirItem._dir = SyncFileItem::Down;
|
||||
_restoreJob.reset(new PropagateLocalMkdir(_propagator, mkdirItem));
|
||||
// Also remove the inodes and fileid from the db so no further renames are tried for
|
||||
// this item.
|
||||
_propagator->_journal->avoidRenamesOnNextSync(_item._file);
|
||||
}
|
||||
connect(_restoreJob.data(), SIGNAL(completed(SyncFileItem)),
|
||||
this, SLOT(slotRestoreJobCompleted(SyncFileItem)));
|
||||
_restoreJob->start();
|
||||
|
|
|
@ -776,6 +776,25 @@ void SyncJournalDb::updateBlacklistEntry( const SyncJournalBlacklistRecord& item
|
|||
|
||||
}
|
||||
|
||||
void SyncJournalDb::avoidRenamesOnNextSync(const QString& path)
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
|
||||
if( !checkConnect() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
QSqlQuery query(_db);
|
||||
query.prepare("UPDATE metadata SET fileid = '', inode = '0' WHERE path LIKE(?||'/%')");
|
||||
query.bindValue(0, path);
|
||||
if( !query.exec() ) {
|
||||
qDebug() << "SQL error in avoidRenamesOnNextSync: "<< query.lastError().text();
|
||||
} else {
|
||||
qDebug() << query.executedQuery() << path;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SyncJournalDb::commit(const QString& context, bool startTrans)
|
||||
{
|
||||
QMutexLocker lock(&_mutex);
|
||||
|
|
|
@ -64,6 +64,7 @@ public:
|
|||
UploadInfo getUploadInfo(const QString &file);
|
||||
void setUploadInfo(const QString &file, const UploadInfo &i);
|
||||
SyncJournalBlacklistRecord blacklistEntry( const QString& );
|
||||
void avoidRenamesOnNextSync(const QString &path);
|
||||
|
||||
bool postSyncCleanup( const QHash<QString, QString>& items );
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче