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 <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
86d4b528d8
commit
ed0148a520
@ -410,7 +410,6 @@ static void record_df_conflict_files(struct merge_options *o,
|
|||||||
len > last_len &&
|
len > last_len &&
|
||||||
memcmp(path, last_file, last_len) == 0 &&
|
memcmp(path, last_file, last_len) == 0 &&
|
||||||
path[last_len] == '/') {
|
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);
|
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);
|
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";
|
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);
|
status = safe_create_leading_directories_const(path);
|
||||||
if (status) {
|
if (status) {
|
||||||
if (status == -3) {
|
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;
|
update_wd = 0;
|
||||||
free(buf);
|
free(buf);
|
||||||
goto update_index;
|
goto update_index;
|
||||||
|
@ -496,7 +496,7 @@ test_expect_success 'setup differently handled merges of directory/file conflict
|
|||||||
git tag E2
|
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 &&
|
get_clean_checkout D^0 &&
|
||||||
|
|
||||||
test_must_fail git merge -s recursive E1^0 &&
|
test_must_fail git merge -s recursive E1^0 &&
|
||||||
|
Loading…
Reference in New Issue
Block a user