Make it work when renaming a directory and a subdirectory at the same

time
This commit is contained in:
Olivier Goffart 2013-01-06 19:46:30 +01:00
parent 0c874f0c3c
commit fe756799d2
5 changed files with 59 additions and 59 deletions

View file

@ -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: */

View file

@ -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);
/**
* }@

View file

@ -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;

View file

@ -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;
}
};

View file

@ -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
}