diff options
Diffstat (limited to 'src/merge.c')
-rw-r--r-- | src/merge.c | 58 |
1 files changed, 42 insertions, 16 deletions
diff --git a/src/merge.c b/src/merge.c index 4c77e43..a6c303d 100644 --- a/src/merge.c +++ b/src/merge.c @@ -149,6 +149,28 @@ static int conflict_phase(DB *ddb, struct syrep_name *name, struct diff_entry *d return 0; } +static int do_copy(const char *a, const char *b) { + int (*copy_proc) (const char *, const char*, int c) = args.always_copy_flag ? copy_file : copy_or_link_file; + + if (!args.always_replace_flag) { + int r, q; + + if ((r = copy_proc(a, b, 0)) >= 0) + return r; + + if (errno != EEXIST) + return r; + + if (!(q = question("Replace existing file?", "ny"))) + return -1; + + if (q != 'y') + return -1; + } + + return copy_proc(a, b, 1); +} + static int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p) { struct cb_info *cb_info = p; struct syrep_name name2; @@ -158,9 +180,6 @@ static int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, v int f; char d[SYREP_DIGESTLENGTH*2+1]; - int (*copy_proc) (const char *, const char*, int c) = args.always_copy_flag ? copy_file : copy_or_link_file; - - assert(ddb && name && de && p); if (de->action != DIFF_COPY && de->action != DIFF_REPLACE) @@ -203,18 +222,21 @@ static int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, v if (makeprefixpath(path, 0777) < 0) return -1; - if (!access(path2, R_OK)) { - if (copy_proc(path2, path, 0) < 0) + if (do_copy(path2, path) < 0) { + if (errno != ENOENT) { + fprintf(stderr, "COPY: Failed to copy file '%s' to '%s': %s\n", path2, path, strerror(errno)); return -1; - } else { - snprintf(path2, sizeof(path2), "%s/%s", cb_info->trash_dir, name2.path); - - if (!access(path2, R_OK)) { - if (copy_proc(path2, path, de->action == DIFF_REPLACE) < 0) - return -1; } else { - fprintf(stderr, "COPY: Local file <%s> vanished. Snapshot not up to date.\n", name2.path); - return -1; + snprintf(path2, sizeof(path2), "%s/%s", cb_info->trash_dir, name2.path); + + if (do_copy(path2, path) < 0) { + if (errno == ENOENT) + fprintf(stderr, "COPY: Local file <%s> vanished. Snapshot not up to date\n", name2.path); + else + fprintf(stderr, "COPY: Failed to copy file '%s' to '%s': %s\n", path2, path, strerror(errno)); + + return -1; + } } } @@ -244,7 +266,7 @@ static int copy_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, v if (makeprefixpath(path, 0777) < 0) return -1; - if (copy_proc(a, path, de->action == DIFF_REPLACE) < 0) + if (do_copy(a, path) < 0) return -1; } else if (args.verbose_flag) @@ -313,8 +335,12 @@ static int delete_phase(DB *ddb, struct syrep_name *name, struct diff_entry *de, if (makeprefixpath(target, 0777) < 0) return -1; - if (move_file(path, target, 1) < 0) - return -1; + if (move_file(path, target, 1) < 0) { + if (errno == ENOENT && !access(target, F_OK)) + fprintf(stderr, "DELETE: File is probably already in trash, continuing\n"); + else + return -1; + } if (args.prune_empty_flag) prune_empty_directories(path, cb_info->root); |