mirror of
https://github.com/nextcloud/desktop.git
synced 2024-10-27 06:45:49 +03:00
Make it work when renaming a directory and a subdirectory at the same
time
This commit is contained in:
parent
0c874f0c3c
commit
fe756799d2
5 changed files with 59 additions and 59 deletions
|
@ -1451,23 +1451,8 @@ err:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int _csync_propagation_dir_rename(void *obj, void *data) {
|
||||
csync_file_stat_t *st = NULL;
|
||||
CSYNC *ctx = NULL;
|
||||
int ret = 0;
|
||||
|
||||
st = (csync_file_stat_t *) obj;
|
||||
ctx = (CSYNC *) data;
|
||||
|
||||
if (st->type != CSYNC_FTW_TYPE_DIR || st->instruction != CSYNC_INSTRUCTION_RENAME)
|
||||
return 0;
|
||||
|
||||
ret = _csync_rename_file(ctx, st);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
csync_rename_record(ctx, st->path, st->destpath);
|
||||
return ret;
|
||||
int csync_propagate_rename_file(CSYNC *ctx, csync_file_stat_t *st) {
|
||||
return _csync_rename_file(ctx, st);
|
||||
}
|
||||
|
||||
int csync_propagate_files(CSYNC *ctx) {
|
||||
|
@ -1498,29 +1483,5 @@ int csync_propagate_files(CSYNC *ctx) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int csync_propagate_rename_dirs(CSYNC* ctx)
|
||||
{
|
||||
c_rbtree_t *tree = NULL;
|
||||
switch (ctx->current) {
|
||||
case LOCAL_REPLICA:
|
||||
tree = ctx->local.tree;
|
||||
break;
|
||||
case REMOTE_REPLICA:
|
||||
tree = ctx->remote.tree;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* We need to start from scratch the renaming */
|
||||
csync_rename_destroy(ctx);
|
||||
|
||||
if (c_rbtree_walk(tree, (void *) ctx, _csync_propagation_dir_rename) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* vim: set ts=8 sw=2 et cindent: */
|
||||
|
|
|
@ -67,7 +67,7 @@ int csync_propagate_files(CSYNC *ctx);
|
|||
|
||||
|
||||
int csync_correct_id(CSYNC *ctx);
|
||||
int csync_propagate_rename_dirs(CSYNC *ctx);
|
||||
int csync_propagate_rename_file(CSYNC *ctx, csync_file_stat_t *st);
|
||||
|
||||
/**
|
||||
* }@
|
||||
|
|
|
@ -121,20 +121,10 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
|
|||
node = c_rbtree_find(tree, &h);
|
||||
}
|
||||
if(node) {
|
||||
char *adjusted;
|
||||
other = (csync_file_stat_t*)node->data;
|
||||
adjusted = csync_rename_adjust_path(ctx, other->path);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE,"about to move: %s -> %s %d", adjusted, cur->path, cur->type != CSYNC_FTW_TYPE_DIR);
|
||||
if (!c_streq(adjusted, cur->path) || cur->type != CSYNC_FTW_TYPE_DIR) {
|
||||
other->instruction = CSYNC_INSTRUCTION_RENAME;
|
||||
other->destpath = c_strdup( cur->path );
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
} else {
|
||||
/* The parent directory is going to be renamed */
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
other->instruction = CSYNC_INSTRUCTION_IGNORE;
|
||||
}
|
||||
SAFE_FREE(adjusted);
|
||||
}
|
||||
if( ! other ) {
|
||||
cur->instruction = CSYNC_INSTRUCTION_NEW;
|
||||
|
|
|
@ -20,10 +20,13 @@
|
|||
|
||||
extern "C" {
|
||||
#include "csync_private.h"
|
||||
#include "csync_propagate.h"
|
||||
}
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
static std::string _parentDir(const std::string &path) {
|
||||
int len = path.length();
|
||||
|
@ -40,9 +43,30 @@ struct csync_rename_s {
|
|||
return reinterpret_cast<csync_rename_s *>(ctx->rename_info);
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> folder_renamed_to;
|
||||
std::map<std::string, std::string> folder_renamed_to; // map from->to
|
||||
|
||||
struct renameop {
|
||||
//std::string from, to;
|
||||
csync_file_stat_t *st;
|
||||
bool operator<(const renameop &other) const {
|
||||
return strlen(st->destpath) < strlen(other.st->destpath);
|
||||
}
|
||||
};
|
||||
std::vector<renameop> todo; // map to->from
|
||||
};
|
||||
|
||||
static int _csync_rename_dir_record(void *obj, void *data) {
|
||||
CSYNC *ctx = reinterpret_cast<CSYNC*>(data);
|
||||
csync_rename_s* d = csync_rename_s::get(ctx);
|
||||
csync_file_stat_t *st = reinterpret_cast<csync_file_stat_t *>(obj);
|
||||
|
||||
if (st->type != CSYNC_FTW_TYPE_DIR || st->instruction != CSYNC_INSTRUCTION_RENAME)
|
||||
return 0;
|
||||
|
||||
csync_rename_s::renameop op = { st };
|
||||
d->todo.push_back(op);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
void csync_rename_destroy(CSYNC* ctx)
|
||||
|
@ -69,4 +93,30 @@ char* csync_rename_adjust_path(CSYNC* ctx, const char* path)
|
|||
return c_strdup(path);
|
||||
}
|
||||
|
||||
int csync_propagate_rename_dirs(CSYNC* ctx)
|
||||
{
|
||||
csync_rename_s* d = csync_rename_s::get(ctx);
|
||||
d->folder_renamed_to.clear();
|
||||
|
||||
if (c_rbtree_walk(ctx->remote.tree, (void *) ctx, _csync_rename_dir_record) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// we need to procceed in order of the file
|
||||
std::sort(d->todo.begin(), d->todo.end());
|
||||
for (std::vector< csync_rename_s::renameop >::iterator it = d->todo.begin();
|
||||
it != d->todo.end(); ++it) {
|
||||
|
||||
int r = csync_propagate_rename_file(ctx, it->st);
|
||||
if (r < 0)
|
||||
return -1;
|
||||
if (r > 0)
|
||||
continue;
|
||||
d->folder_renamed_to[it->st->path] = it->st->destpath;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -26,11 +26,10 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
//void csync_rename_adjust_tree(CSYNC *ctx);
|
||||
char *csync_rename_adjust_path(CSYNC *ctx, const char *path);
|
||||
void csync_rename_record(CSYNC *ctx, const char *from, const char *to);
|
||||
void csync_rename_destroy(CSYNC *ctx);
|
||||
|
||||
void csync_rename_record(CSYNC *ctx, const char *from, const char *to);
|
||||
int csync_propagate_rename_dirs(CSYNC* ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue