Commit 0f47d3d7 authored by Junio C Hamano's avatar Junio C Hamano

Merge branch 'dt/empty-submodule-in-merge' into maint

An empty directory in a working tree that can simply be nuked used
to interfere while merging or cherry-picking a change to create a
submodule directory there, which has been fixed..

* dt/empty-submodule-in-merge:
  submodules: allow empty working-tree dirs in merge/cherry-pick
parents 7b0490f8 5423d2e7
......@@ -664,7 +664,13 @@ static char *unique_path(struct merge_options *o, const char *path, const char *
return strbuf_detach(&newpath, NULL);
}
static int dir_in_way(const char *path, int check_working_copy)
/**
* Check whether a directory in the index is in the way of an incoming
* file. Return 1 if so. If check_working_copy is non-zero, also
* check the working directory. If empty_ok is non-zero, also return
* 0 in the case where the working-tree dir exists but is empty.
*/
static int dir_in_way(const char *path, int check_working_copy, int empty_ok)
{
int pos;
struct strbuf dirpath = STRBUF_INIT;
......@@ -684,7 +690,8 @@ static int dir_in_way(const char *path, int check_working_copy)
}
strbuf_release(&dirpath);
return check_working_copy && !lstat(path, &st) && S_ISDIR(st.st_mode);
return check_working_copy && !lstat(path, &st) && S_ISDIR(st.st_mode) &&
!(empty_ok && is_empty_dir(path));
}
static int was_tracked(const char *path)
......@@ -1062,7 +1069,7 @@ static int handle_change_delete(struct merge_options *o,
{
char *renamed = NULL;
int ret = 0;
if (dir_in_way(path, !o->call_depth)) {
if (dir_in_way(path, !o->call_depth, 0)) {
renamed = unique_path(o, path, a_oid ? o->branch1 : o->branch2);
}
......@@ -1195,7 +1202,7 @@ static int handle_file(struct merge_options *o,
remove_file(o, 0, rename->path, 0);
dst_name = unique_path(o, rename->path, cur_branch);
} else {
if (dir_in_way(rename->path, !o->call_depth)) {
if (dir_in_way(rename->path, !o->call_depth, 0)) {
dst_name = unique_path(o, rename->path, cur_branch);
output(o, 1, _("%s is a directory in %s adding as %s instead"),
rename->path, other_branch, dst_name);
......@@ -1704,7 +1711,8 @@ static int merge_content(struct merge_options *o,
o->branch2 == rename_conflict_info->branch1) ?
pair1->two->path : pair1->one->path;
if (dir_in_way(path, !o->call_depth))
if (dir_in_way(path, !o->call_depth,
S_ISGITLINK(pair1->two->mode)))
df_conflict_remains = 1;
}
if (merge_file_special_markers(o, &one, &a, &b,
......@@ -1862,7 +1870,8 @@ static int process_entry(struct merge_options *o,
oid = b_oid;
conf = _("directory/file");
}
if (dir_in_way(path, !o->call_depth)) {
if (dir_in_way(path, !o->call_depth,
S_ISGITLINK(a_mode))) {
char *new_path = unique_path(o, path, add_branch);
clean_merge = 0;
output(o, 1, _("CONFLICT (%s): There is a directory with name %s in %s. "
......
......@@ -575,13 +575,13 @@ test_expect_success 'merge removes empty directories' '
test_must_fail test -d d
'
test_expect_failure 'merge-recursive simple w/submodule' '
test_expect_success 'merge-recursive simple w/submodule' '
git checkout submod &&
git merge remove
'
test_expect_failure 'merge-recursive simple w/submodule result' '
test_expect_success 'merge-recursive simple w/submodule result' '
git ls-files -s >actual &&
(
......
......@@ -38,9 +38,6 @@ git_rebase_interactive () {
git rebase -i "$1"
}
KNOWN_FAILURE_NOFF_MERGE_DOESNT_CREATE_EMPTY_SUBMODULE_DIR=1
# The real reason "replace directory with submodule" fails is because a
# directory "sub1" exists, but we reuse the suppression added for merge here
test_submodule_switch "git_rebase_interactive"
test_done
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment