From ed0148a520ec2ec88f0574c2e107aba0a46936e1 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Thu, 11 Aug 2011 23:20:01 -0600 Subject: [PATCH] merge-recursive: Allow make_room_for_path() to remove D/F entries If there were several files conflicting below a directory corresponding to a D/F conflict, and the file of that D/F conflict is in the way, we want it to be removed. Since files of D/F conflicts are handled last, they can be reinstated later and possibly with a new unique name. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- merge-recursive.c | 26 ++++++++++++++++++++++---- t/t6036-recursive-corner-cases.sh | 2 +- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index a30e5a4449..5d6fc0d047 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -410,7 +410,6 @@ static void record_df_conflict_files(struct merge_options *o, len > last_len && memcmp(path, last_file, last_len) == 0 && path[last_len] == '/') { - output(o, 3, "Removing %s to make room for subdirectory; may re-add later.", last_file); string_list_insert(&o->df_conflict_file_set, last_file); } @@ -650,11 +649,30 @@ static int would_lose_untracked(const char *path) return !was_tracked(path) && file_exists(path); } -static int make_room_for_path(const char *path) +static int make_room_for_path(struct merge_options *o, const char *path) { - int status; + int status, i; const char *msg = "failed to create path '%s'%s"; + /* Unlink any D/F conflict files that are in the way */ + for (i = 0; i < o->df_conflict_file_set.nr; i++) { + const char *df_path = o->df_conflict_file_set.items[i].string; + size_t pathlen = strlen(path); + size_t df_pathlen = strlen(df_path); + if (df_pathlen < pathlen && + path[df_pathlen] == '/' && + strncmp(path, df_path, df_pathlen) == 0) { + output(o, 3, + "Removing %s to make room for subdirectory\n", + df_path); + unlink(df_path); + unsorted_string_list_delete_item(&o->df_conflict_file_set, + i, 0); + break; + } + } + + /* Make sure leading directories are created */ status = safe_create_leading_directories_const(path); if (status) { if (status == -3) { @@ -722,7 +740,7 @@ static void update_file_flags(struct merge_options *o, } } - if (make_room_for_path(path) < 0) { + if (make_room_for_path(o, path) < 0) { update_wd = 0; free(buf); goto update_index; diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6036-recursive-corner-cases.sh index ed6c6f45d6..279f33ca2d 100755 --- a/t/t6036-recursive-corner-cases.sh +++ b/t/t6036-recursive-corner-cases.sh @@ -496,7 +496,7 @@ test_expect_success 'setup differently handled merges of directory/file conflict git tag E2 ' -test_expect_failure 'merge of D & E1 fails but has appropriate contents' ' +test_expect_success 'merge of D & E1 fails but has appropriate contents' ' get_clean_checkout D^0 && test_must_fail git merge -s recursive E1^0 &&