Merge branch 'sb/submodule-core-worktree'

"git submodule" did not correctly adjust core.worktree setting that
indicates whether/where a submodule repository has its associated
working tree across various state transitions, which has been
corrected.

* sb/submodule-core-worktree:
  submodule deinit: unset core.worktree
  submodule: ensure core.worktree is set after update
  submodule: unset core.worktree if no working tree is present
This commit is contained in:
Junio C Hamano 2018-07-18 12:20:28 -07:00
Родитель 00624d608c 984cd77ddb
Коммит 7e25437d35
6 изменённых файлов: 55 добавлений и 2 удалений

Просмотреть файл

@ -1124,6 +1124,8 @@ static void deinit_submodule(const char *path, const char *prefix,
if (!(flags & OPT_QUIET)) if (!(flags & OPT_QUIET))
printf(format, displaypath); printf(format, displaypath);
submodule_unset_core_worktree(sub);
strbuf_release(&sb_rm); strbuf_release(&sb_rm);
} }
@ -2004,6 +2006,29 @@ static int check_name(int argc, const char **argv, const char *prefix)
return 0; return 0;
} }
static int connect_gitdir_workingtree(int argc, const char **argv, const char *prefix)
{
struct strbuf sb = STRBUF_INIT;
const char *name, *path;
char *sm_gitdir;
if (argc != 3)
BUG("submodule--helper connect-gitdir-workingtree <name> <path>");
name = argv[1];
path = argv[2];
strbuf_addf(&sb, "%s/modules/%s", get_git_dir(), name);
sm_gitdir = absolute_pathdup(sb.buf);
connect_work_tree_and_git_dir(path, sm_gitdir, 0);
strbuf_release(&sb);
free(sm_gitdir);
return 0;
}
#define SUPPORT_SUPER_PREFIX (1<<0) #define SUPPORT_SUPER_PREFIX (1<<0)
struct cmd_struct { struct cmd_struct {
@ -2017,6 +2042,7 @@ static struct cmd_struct commands[] = {
{"name", module_name, 0}, {"name", module_name, 0},
{"clone", module_clone, 0}, {"clone", module_clone, 0},
{"update-clone", update_clone, 0}, {"update-clone", update_clone, 0},
{"connect-gitdir-workingtree", connect_gitdir_workingtree, 0},
{"relative-path", resolve_relative_path, 0}, {"relative-path", resolve_relative_path, 0},
{"resolve-relative-url", resolve_relative_url, 0}, {"resolve-relative-url", resolve_relative_url, 0},
{"resolve-relative-url-test", resolve_relative_url_test, 0}, {"resolve-relative-url-test", resolve_relative_url_test, 0},

Просмотреть файл

@ -577,6 +577,11 @@ cmd_update()
die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")" die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
fi fi
if ! $(git config -f "$(git rev-parse --git-common-dir)/modules/$name/config" core.worktree) 2>/dev/null
then
git submodule--helper connect-gitdir-workingtree "$name" "$sm_path"
fi
if test "$subsha1" != "$sha1" || test -n "$force" if test "$subsha1" != "$sha1" || test -n "$force"
then then
subforce=$force subforce=$force

Просмотреть файл

@ -1534,6 +1534,18 @@ out:
return ret; return ret;
} }
void submodule_unset_core_worktree(const struct submodule *sub)
{
char *config_path = xstrfmt("%s/modules/%s/config",
get_git_common_dir(), sub->name);
if (git_config_set_in_file_gently(config_path, "core.worktree", NULL))
warning(_("Could not unset core.worktree setting in submodule '%s'"),
sub->path);
free(config_path);
}
static const char *get_super_prefix_or_empty(void) static const char *get_super_prefix_or_empty(void)
{ {
const char *s = get_super_prefix(); const char *s = get_super_prefix();
@ -1699,6 +1711,8 @@ int submodule_move_head(const char *path,
if (is_empty_dir(path)) if (is_empty_dir(path))
rmdir_or_warn(path); rmdir_or_warn(path);
submodule_unset_core_worktree(sub);
} }
} }
out: out:

Просмотреть файл

@ -121,6 +121,8 @@ extern int submodule_move_head(const char *path,
const char *new_head, const char *new_head,
unsigned flags); unsigned flags);
void submodule_unset_core_worktree(const struct submodule *sub);
/* /*
* Prepare the "env_array" parameter of a "struct child_process" for executing * Prepare the "env_array" parameter of a "struct child_process" for executing
* a submodule by clearing any repo-specific environment variables, but * a submodule by clearing any repo-specific environment variables, but

Просмотреть файл

@ -235,7 +235,7 @@ reset_work_tree_to_interested () {
then then
mkdir -p submodule_update/.git/modules/sub1/modules && mkdir -p submodule_update/.git/modules/sub1/modules &&
cp -r submodule_update_repo/.git/modules/sub1/modules/sub2 submodule_update/.git/modules/sub1/modules/sub2 cp -r submodule_update_repo/.git/modules/sub1/modules/sub2 submodule_update/.git/modules/sub1/modules/sub2
GIT_WORK_TREE=. git -C submodule_update/.git/modules/sub1/modules/sub2 config --unset core.worktree # core.worktree is unset for sub2 as it is not checked out
fi && fi &&
# indicate we are interested in the submodule: # indicate we are interested in the submodule:
git -C submodule_update config submodule.sub1.url "bogus" && git -C submodule_update config submodule.sub1.url "bogus" &&
@ -709,7 +709,8 @@ test_submodule_recursing_with_args_common() {
git branch -t remove_sub1 origin/remove_sub1 && git branch -t remove_sub1 origin/remove_sub1 &&
$command remove_sub1 && $command remove_sub1 &&
test_superproject_content origin/remove_sub1 && test_superproject_content origin/remove_sub1 &&
! test -e sub1 ! test -e sub1 &&
test_must_fail git config -f .git/modules/sub1/config core.worktree
) )
' '
# ... absorbing a .git directory along the way. # ... absorbing a .git directory along the way.

Просмотреть файл

@ -993,6 +993,11 @@ test_expect_success 'submodule deinit should remove the whole submodule section
rmdir init rmdir init
' '
test_expect_success 'submodule deinit should unset core.worktree' '
test_path_is_file .git/modules/example/config &&
test_must_fail git config -f .git/modules/example/config core.worktree
'
test_expect_success 'submodule deinit from subdirectory' ' test_expect_success 'submodule deinit from subdirectory' '
git submodule update --init && git submodule update --init &&
git config submodule.example.foo bar && git config submodule.example.foo bar &&