From 98b7248df0768942cd57ce99522033049bb8bb8b Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 28 Aug 2014 17:16:17 +0200 Subject: [PATCH] reconcile/update: don't remove directory that contains ignored files --- csync/src/csync_private.h | 1 + csync/src/csync_reconcile.c | 4 ++++ csync/src/csync_update.c | 22 +++++++++++----------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/csync/src/csync_private.h b/csync/src/csync_private.h index d9277a004c..0c6785bd29 100644 --- a/csync/src/csync_private.h +++ b/csync/src/csync_private.h @@ -167,6 +167,7 @@ struct csync_file_stat_s { int type; /* u32 */ int child_modified;/*bool*/ int should_update_etag; /*bool */ + int has_ignored_files; /*bool: specify that a directory, or child directory contains ignored files */ char *destpath; /* for renames */ const char *etag; diff --git a/csync/src/csync_reconcile.c b/csync/src/csync_reconcile.c index fda28aadc6..91b8bf8643 100644 --- a/csync/src/csync_reconcile.c +++ b/csync/src/csync_reconcile.c @@ -134,6 +134,10 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) { break; /* file has been removed on the opposite replica */ case CSYNC_INSTRUCTION_NONE: + if (cur->has_ignored_files) { + /* Do not remove a directory that has ignored files */ + break; + } cur->instruction = CSYNC_INSTRUCTION_REMOVE; break; case CSYNC_INSTRUCTION_EVAL_RENAME: diff --git a/csync/src/csync_update.c b/csync/src/csync_update.c index 0159b9c9b8..88052027ce 100644 --- a/csync/src/csync_update.c +++ b/csync/src/csync_update.c @@ -146,21 +146,15 @@ static int _csync_detect_update(CSYNC *ctx, const char *file, if (excluded != CSYNC_NOT_EXCLUDED) { CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s excluded (%d)", path, excluded); if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE) { - switch (ctx->current) { - case LOCAL_REPLICA: - ctx->local.ignored_cleanup = c_list_append(ctx->local.ignored_cleanup, c_strdup(path)); - break; - case REMOTE_REPLICA: - ctx->remote.ignored_cleanup = c_list_append(ctx->remote.ignored_cleanup, c_strdup(path)); - break; - default: - break; - } - return 0; + return 0; } if (excluded == CSYNC_FILE_SILENTLY_EXCLUDED) { return 0; } + + if (ctx->current_fs) { + ctx->current_fs->has_ignored_files = true; + } } if (ctx->current == REMOTE_REPLICA && ctx->checkBlackListHook) { @@ -185,6 +179,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file, st->instruction = CSYNC_INSTRUCTION_NONE; st->etag = NULL; st->child_modified = 0; + st->has_ignored_files = 0; /* check hardlink count */ if (type == CSYNC_FTW_TYPE_FILE ) { @@ -666,8 +661,13 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn, /* this function may update ctx->current and ctx->read_from_db */ if (ctx->current_fs && previous_fs && ctx->current_fs->child_modified) { + /* If a directory has modified files, put the flag on the parent directory as well */ previous_fs->child_modified = ctx->current_fs->child_modified; } + if (ctx->current_fs && previous_fs && ctx->current_fs->has_ignored_files) { + /* If a directory has ignored files, put the flag on the parent directory as well */ + previous_fs->has_ignored_files = ctx->current_fs->has_ignored_files; + } /* Only for the local replica we have to destroy stat(), for the remote one it is a pointer to dirent */ if (ctx->replica == LOCAL_REPLICA) {