diff options
-rw-r--r-- | merge-recursive.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/merge-recursive.c b/merge-recursive.c index 532a1da2b0..398a734f3f 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -601,25 +601,36 @@ static int remove_file(struct merge_options *o, int clean, return 0; } +/* add a string to a strbuf, but converting "/" to "_" */ +static void add_flattened_path(struct strbuf *out, const char *s) +{ + size_t i = out->len; + strbuf_addstr(out, s); + for (; i < out->len; i++) + if (out->buf[i] == '/') + out->buf[i] = '_'; +} + static char *unique_path(struct merge_options *o, const char *path, const char *branch) { - char *newpath = xmalloc(strlen(path) + 1 + strlen(branch) + 8 + 1); + struct strbuf newpath = STRBUF_INIT; int suffix = 0; struct stat st; - char *p = newpath + strlen(path); - strcpy(newpath, path); - *(p++) = '~'; - strcpy(p, branch); - for (; *p; ++p) - if ('/' == *p) - *p = '_'; - while (string_list_has_string(&o->current_file_set, newpath) || - string_list_has_string(&o->current_directory_set, newpath) || - lstat(newpath, &st) == 0) - sprintf(p, "_%d", suffix++); - - string_list_insert(&o->current_file_set, newpath); - return newpath; + size_t base_len; + + strbuf_addf(&newpath, "%s~", path); + add_flattened_path(&newpath, branch); + + base_len = newpath.len; + while (string_list_has_string(&o->current_file_set, newpath.buf) || + string_list_has_string(&o->current_directory_set, newpath.buf) || + lstat(newpath.buf, &st) == 0) { + strbuf_setlen(&newpath, base_len); + strbuf_addf(&newpath, "_%d", suffix++); + } + + string_list_insert(&o->current_file_set, newpath.buf); + return strbuf_detach(&newpath, NULL); } static int dir_in_way(const char *path, int check_working_copy) |