Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/rm.c3
-rw-r--r--builtin/submodule--helper.c146
-rwxr-xr-xgit-submodule.sh3
-rw-r--r--git.c2
-rw-r--r--submodule.c41
-rw-r--r--submodule.h4
-rw-r--r--t/helper/test-submodule.c84
-rwxr-xr-xt/t7400-submodule-basic.sh10
-rwxr-xr-xt/t7407-submodule-foreach.sh5
-rwxr-xr-xt/t7411-submodule-config.sh36
-rwxr-xr-xt/t7418-submodule-sparse-gitmodules.sh4
-rwxr-xr-xt/t7422-submodule-output.sh170
12 files changed, 358 insertions, 150 deletions
diff --git a/builtin/rm.c b/builtin/rm.c
index f0d025a4e2..05bfe20a46 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -86,8 +86,7 @@ static void submodules_absorb_gitdir_if_needed(void)
continue;
if (!submodule_uses_gitfile(name))
- absorb_git_dir_into_superproject(name,
- ABSORB_GITDIR_RECURSE_SUBMODULES);
+ absorb_git_dir_into_superproject(name);
}
}
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index a7683d3529..c75e9e86b0 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -616,6 +616,9 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
int diff_files_result;
struct strbuf buf = STRBUF_INIT;
const char *git_dir;
+ struct setup_revision_opt opt = {
+ .free_removed_argv_elements = 1,
+ };
if (!submodule_from_path(the_repository, null_oid(), path))
die(_("no submodule mapping found in .gitmodules for path '%s'"),
@@ -649,9 +652,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
repo_init_revisions(the_repository, &rev, NULL);
rev.abbrev = 0;
- diff_files_args.nr = setup_revisions(diff_files_args.nr,
- diff_files_args.v,
- &rev, NULL);
+ setup_revisions(diff_files_args.nr, diff_files_args.v, &rev, &opt);
diff_files_result = run_diff_files(&rev, 0);
if (!diff_result_code(&rev.diffopt, diff_files_result)) {
@@ -1378,8 +1379,7 @@ static void deinit_submodule(const char *path, const char *prefix,
".git file by using absorbgitdirs."),
displaypath);
- absorb_git_dir_into_superproject(path,
- ABSORB_GITDIR_RECURSE_SUBMODULES);
+ absorb_git_dir_into_superproject(path);
}
@@ -2643,9 +2643,6 @@ static int module_update(int argc, const char **argv, const char *prefix)
N_("traverse submodules recursively")),
OPT_BOOL('N', "no-fetch", &opt.nofetch,
N_("don't fetch new objects from the remote site")),
- OPT_STRING(0, "prefix", &opt.prefix,
- N_("path"),
- N_("path into the working tree")),
OPT_SET_INT(0, "checkout", &opt.update_default,
N_("use the 'checkout' update strategy (default)"),
SM_UPDATE_CHECKOUT),
@@ -2701,6 +2698,7 @@ static int module_update(int argc, const char **argv, const char *prefix)
}
opt.filter_options = &filter_options;
+ opt.prefix = prefix;
if (opt.update_default)
opt.update_strategy.type = opt.update_default;
@@ -2830,13 +2828,7 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
int i;
struct pathspec pathspec = { 0 };
struct module_list list = MODULE_LIST_INIT;
- unsigned flags = ABSORB_GITDIR_RECURSE_SUBMODULES;
struct option embed_gitdir_options[] = {
- OPT_STRING(0, "prefix", &prefix,
- N_("path"),
- N_("path into the working tree")),
- OPT_BIT(0, "--recursive", &flags, N_("recurse into submodules"),
- ABSORB_GITDIR_RECURSE_SUBMODULES),
OPT_END()
};
const char *const git_submodule_helper_usage[] = {
@@ -2852,7 +2844,7 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
goto cleanup;
for (i = 0; i < list.nr; i++)
- absorb_git_dir_into_superproject(list.entries[i]->name, flags);
+ absorb_git_dir_into_superproject(list.entries[i]->name);
ret = 0;
cleanup:
@@ -2861,51 +2853,6 @@ cleanup:
return ret;
}
-static int module_config(int argc, const char **argv, const char *prefix)
-{
- enum {
- CHECK_WRITEABLE = 1,
- DO_UNSET = 2
- } command = 0;
- struct option module_config_options[] = {
- OPT_CMDMODE(0, "check-writeable", &command,
- N_("check if it is safe to write to the .gitmodules file"),
- CHECK_WRITEABLE),
- OPT_CMDMODE(0, "unset", &command,
- N_("unset the config in the .gitmodules file"),
- DO_UNSET),
- OPT_END()
- };
- const char *const git_submodule_helper_usage[] = {
- N_("git submodule--helper config <name> [<value>]"),
- N_("git submodule--helper config --unset <name>"),
- "git submodule--helper config --check-writeable",
- NULL
- };
-
- argc = parse_options(argc, argv, prefix, module_config_options,
- git_submodule_helper_usage, PARSE_OPT_KEEP_ARGV0);
-
- if (argc == 1 && command == CHECK_WRITEABLE)
- return is_writing_gitmodules_ok() ? 0 : -1;
-
- /* Equivalent to ACTION_GET in builtin/config.c */
- if (argc == 2 && command != DO_UNSET)
- return print_config_from_gitmodules(the_repository, argv[1]);
-
- /* Equivalent to ACTION_SET in builtin/config.c */
- if (argc == 3 || (argc == 2 && command == DO_UNSET)) {
- const char *value = (argc == 3) ? argv[2] : NULL;
-
- if (!is_writing_gitmodules_ok())
- die(_("please make sure that the .gitmodules file is in the working tree"));
-
- return config_set_in_gitmodules_file_gently(argv[1], value);
- }
-
- usage_with_options(git_submodule_helper_usage, module_config_options);
-}
-
static int module_set_url(int argc, const char **argv, const char *prefix)
{
int quiet = 0;
@@ -3404,48 +3351,45 @@ cleanup:
return ret;
}
-#define SUPPORT_SUPER_PREFIX (1<<0)
-
-struct cmd_struct {
- const char *cmd;
- int (*fn)(int, const char **, const char *);
- unsigned option;
-};
-
-static struct cmd_struct commands[] = {
- {"clone", module_clone, SUPPORT_SUPER_PREFIX},
- {"add", module_add, 0},
- {"update", module_update, SUPPORT_SUPER_PREFIX},
- {"foreach", module_foreach, SUPPORT_SUPER_PREFIX},
- {"init", module_init, 0},
- {"status", module_status, SUPPORT_SUPER_PREFIX},
- {"sync", module_sync, SUPPORT_SUPER_PREFIX},
- {"deinit", module_deinit, 0},
- {"summary", module_summary, 0},
- {"push-check", push_check, 0},
- {"absorbgitdirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX},
- {"config", module_config, 0},
- {"set-url", module_set_url, 0},
- {"set-branch", module_set_branch, 0},
- {"create-branch", module_create_branch, 0},
-};
-
int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
{
- int i;
- if (argc < 2 || !strcmp(argv[1], "-h"))
- usage("git submodule--helper <command>");
-
- for (i = 0; i < ARRAY_SIZE(commands); i++) {
- if (!strcmp(argv[1], commands[i].cmd)) {
- if (get_super_prefix() &&
- !(commands[i].option & SUPPORT_SUPER_PREFIX))
- die(_("%s doesn't support --super-prefix"),
- commands[i].cmd);
- return commands[i].fn(argc - 1, argv + 1, prefix);
- }
- }
+ const char *cmd = argv[0];
+ const char *subcmd;
+ parse_opt_subcommand_fn *fn = NULL;
+ const char *const usage[] = {
+ N_("git submodule--helper <command>"),
+ NULL
+ };
+ struct option options[] = {
+ OPT_SUBCOMMAND("clone", &fn, module_clone),
+ OPT_SUBCOMMAND("add", &fn, module_add),
+ OPT_SUBCOMMAND("update", &fn, module_update),
+ OPT_SUBCOMMAND("foreach", &fn, module_foreach),
+ OPT_SUBCOMMAND("init", &fn, module_init),
+ OPT_SUBCOMMAND("status", &fn, module_status),
+ OPT_SUBCOMMAND("sync", &fn, module_sync),
+ OPT_SUBCOMMAND("deinit", &fn, module_deinit),
+ OPT_SUBCOMMAND("summary", &fn, module_summary),
+ OPT_SUBCOMMAND("push-check", &fn, push_check),
+ OPT_SUBCOMMAND("absorbgitdirs", &fn, absorb_git_dirs),
+ OPT_SUBCOMMAND("set-url", &fn, module_set_url),
+ OPT_SUBCOMMAND("set-branch", &fn, module_set_branch),
+ OPT_SUBCOMMAND("create-branch", &fn, module_create_branch),
+ OPT_END()
+ };
+ argc = parse_options(argc, argv, prefix, options, usage, 0);
+ subcmd = argv[0];
+
+ if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
+ strcmp(subcmd, "foreach") && strcmp(subcmd, "status") &&
+ strcmp(subcmd, "sync") && strcmp(subcmd, "absorbgitdirs") &&
+ get_super_prefix())
+ /*
+ * xstrfmt() rather than "%s %s" to keep the translated
+ * string identical to git.c's.
+ */
+ die(_("%s doesn't support --super-prefix"),
+ xstrfmt("'%s %s'", cmd, subcmd));
- die(_("'%s' is not a valid submodule--helper "
- "subcommand"), argv[1]);
+ return fn(argc, argv, prefix);
}
diff --git a/git-submodule.sh b/git-submodule.sh
index 5e5d21c010..9a50f2e912 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -343,7 +343,6 @@ cmd_update()
${recursive:+--recursive} \
${init:+--init} \
${nofetch:+--no-fetch} \
- ${wt_prefix:+--prefix "$wt_prefix"} \
${rebase:+--rebase} \
${merge:+--merge} \
${checkout:+--checkout} \
@@ -557,7 +556,7 @@ cmd_sync()
cmd_absorbgitdirs()
{
- git submodule--helper absorbgitdirs --prefix "$wt_prefix" "$@"
+ git ${wt_prefix:+-C "$wt_prefix"} submodule--helper absorbgitdirs "$@"
}
# This loop parses the command line arguments to find the
diff --git a/git.c b/git.c
index 6662548986..10202a7f12 100644
--- a/git.c
+++ b/git.c
@@ -610,7 +610,7 @@ static struct cmd_struct commands[] = {
{ "stash", cmd_stash, RUN_SETUP | NEED_WORK_TREE },
{ "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
{ "stripspace", cmd_stripspace },
- { "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX | NO_PARSEOPT },
+ { "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX },
{ "switch", cmd_switch, RUN_SETUP | NEED_WORK_TREE },
{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
{ "tag", cmd_tag, RUN_SETUP | DELAY_PAGER_CONFIG },
diff --git a/submodule.c b/submodule.c
index b958162d28..8fa2ad457b 100644
--- a/submodule.c
+++ b/submodule.c
@@ -2139,8 +2139,7 @@ int submodule_move_head(const char *path,
if (!(flags & SUBMODULE_MOVE_HEAD_DRY_RUN)) {
if (old_head) {
if (!submodule_uses_gitfile(path))
- absorb_git_dir_into_superproject(path,
- ABSORB_GITDIR_RECURSE_SUBMODULES);
+ absorb_git_dir_into_superproject(path);
} else {
struct strbuf gitdir = STRBUF_INIT;
submodule_name_to_gitdir(&gitdir, the_repository,
@@ -2310,13 +2309,29 @@ static void relocate_single_git_dir_into_superproject(const char *path)
strbuf_release(&new_gitdir);
}
+static void absorb_git_dir_into_superproject_recurse(const char *path)
+{
+
+ struct child_process cp = CHILD_PROCESS_INIT;
+
+ cp.dir = path;
+ cp.git_cmd = 1;
+ cp.no_stdin = 1;
+ strvec_pushf(&cp.args, "--super-prefix=%s%s/",
+ get_super_prefix_or_empty(), path);
+ strvec_pushl(&cp.args, "submodule--helper",
+ "absorbgitdirs", NULL);
+ prepare_submodule_repo_env(&cp.env);
+ if (run_command(&cp))
+ die(_("could not recurse into submodule '%s'"), path);
+}
+
/*
* Migrate the git directory of the submodule given by path from
* having its git directory within the working tree to the git dir nested
* in its superprojects git dir under modules/.
*/
-void absorb_git_dir_into_superproject(const char *path,
- unsigned flags)
+void absorb_git_dir_into_superproject(const char *path)
{
int err_code;
const char *sub_git_dir;
@@ -2365,23 +2380,7 @@ void absorb_git_dir_into_superproject(const char *path,
}
strbuf_release(&gitdir);
- if (flags & ABSORB_GITDIR_RECURSE_SUBMODULES) {
- struct child_process cp = CHILD_PROCESS_INIT;
-
- if (flags & ~ABSORB_GITDIR_RECURSE_SUBMODULES)
- BUG("we don't know how to pass the flags down?");
-
- cp.dir = path;
- cp.git_cmd = 1;
- cp.no_stdin = 1;
- strvec_pushf(&cp.args, "--super-prefix=%s%s/",
- get_super_prefix_or_empty(), path);
- strvec_pushl(&cp.args, "submodule--helper",
- "absorbgitdirs", NULL);
- prepare_submodule_repo_env(&cp.env);
- if (run_command(&cp))
- die(_("could not recurse into submodule '%s'"), path);
- }
+ absorb_git_dir_into_superproject_recurse(path);
}
int get_superproject_working_tree(struct strbuf *buf)
diff --git a/submodule.h b/submodule.h
index 6a9fec6de1..b52a4ff1e7 100644
--- a/submodule.h
+++ b/submodule.h
@@ -164,9 +164,7 @@ void submodule_unset_core_worktree(const struct submodule *sub);
*/
void prepare_submodule_repo_env(struct strvec *env);
-#define ABSORB_GITDIR_RECURSE_SUBMODULES (1<<0)
-void absorb_git_dir_into_superproject(const char *path,
- unsigned flags);
+void absorb_git_dir_into_superproject(const char *path);
/*
* Return the absolute path of the working tree of the superproject, which this
diff --git a/t/helper/test-submodule.c b/t/helper/test-submodule.c
index b7d117cd55..e060cc6226 100644
--- a/t/helper/test-submodule.c
+++ b/t/helper/test-submodule.c
@@ -111,10 +111,94 @@ static int cmd__submodule_resolve_relative_url(int argc, const char **argv)
return 0;
}
+static int cmd__submodule_config_list(int argc, const char **argv)
+{
+ struct option options[] = {
+ OPT_END()
+ };
+ const char *const usage[] = {
+ "test-tool submodule config-list <key>",
+ NULL
+ };
+ argc = parse_options(argc, argv, "test-tools", options, usage,
+ PARSE_OPT_KEEP_ARGV0);
+
+ setup_git_directory();
+
+ if (argc == 2)
+ return print_config_from_gitmodules(the_repository, argv[1]);
+ usage_with_options(usage, options);
+}
+
+static int cmd__submodule_config_set(int argc, const char **argv)
+{
+ struct option options[] = {
+ OPT_END()
+ };
+ const char *const usage[] = {
+ "test-tool submodule config-set <key> <value>",
+ NULL
+ };
+ argc = parse_options(argc, argv, "test-tools", options, usage,
+ PARSE_OPT_KEEP_ARGV0);
+
+ setup_git_directory();
+
+ /* Equivalent to ACTION_SET in builtin/config.c */
+ if (argc == 3) {
+ if (!is_writing_gitmodules_ok())
+ die("please make sure that the .gitmodules file is in the working tree");
+
+ return config_set_in_gitmodules_file_gently(argv[1], argv[2]);
+ }
+ usage_with_options(usage, options);
+}
+
+static int cmd__submodule_config_unset(int argc, const char **argv)
+{
+ struct option options[] = {
+ OPT_END()
+ };
+ const char *const usage[] = {
+ "test-tool submodule config-unset <key>",
+ NULL
+ };
+
+ setup_git_directory();
+
+ if (argc == 2) {
+ if (!is_writing_gitmodules_ok())
+ die("please make sure that the .gitmodules file is in the working tree");
+ return config_set_in_gitmodules_file_gently(argv[1], NULL);
+ }
+ usage_with_options(usage, options);
+}
+
+static int cmd__submodule_config_writeable(int argc, const char **argv)
+{
+ struct option options[] = {
+ OPT_END()
+ };
+ const char *const usage[] = {
+ "test-tool submodule config-writeable",
+ NULL
+ };
+ setup_git_directory();
+
+ if (argc == 1)
+ return is_writing_gitmodules_ok() ? 0 : -1;
+
+ usage_with_options(usage, options);
+}
+
static struct test_cmd cmds[] = {
{ "check-name", cmd__submodule_check_name },
{ "is-active", cmd__submodule_is_active },
{ "resolve-relative-url", cmd__submodule_resolve_relative_url},
+ { "config-list", cmd__submodule_config_list },
+ { "config-set", cmd__submodule_config_set },
+ { "config-unset", cmd__submodule_config_unset },
+ { "config-writeable", cmd__submodule_config_writeable },
};
int cmd__submodule(int argc, const char **argv)
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index a989aafaf5..eae6a46ef3 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -579,6 +579,16 @@ test_expect_success 'status should be "modified" after submodule commit' '
grep "^+$rev2" list
'
+test_expect_success '"submodule --cached" command forms should be identical' '
+ git submodule status --cached >expect &&
+
+ git submodule --cached >actual &&
+ test_cmp expect actual &&
+
+ git submodule --cached status >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'the --cached sha1 should be rev1' '
git submodule --cached status >list &&
grep "^+$rev1" list
diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh
index 59bd150166..8d7b234beb 100755
--- a/t/t7407-submodule-foreach.sh
+++ b/t/t7407-submodule-foreach.sh
@@ -154,6 +154,11 @@ test_expect_success 'use "submodule foreach" to checkout 2nd level submodule' '
)
'
+test_expect_success 'usage: foreach -- --not-an-option' '
+ test_expect_code 1 git submodule foreach -- --not-an-option &&
+ test_expect_code 1 git -C clone2 submodule foreach -- --not-an-option
+'
+
test_expect_success 'use "foreach --recursive" to checkout all submodules' '
(
cd clone2 &&
diff --git a/t/t7411-submodule-config.sh b/t/t7411-submodule-config.sh
index c583c4e373..c0167944ab 100755
--- a/t/t7411-submodule-config.sh
+++ b/t/t7411-submodule-config.sh
@@ -137,44 +137,44 @@ test_expect_success 'error in history in fetchrecursesubmodule lets continue' '
)
'
-test_expect_success 'reading submodules config from the working tree with "submodule--helper config"' '
+test_expect_success 'reading submodules config from the working tree' '
(cd super &&
echo "../submodule" >expect &&
- git submodule--helper config submodule.submodule.url >actual &&
+ test-tool submodule config-list submodule.submodule.url >actual &&
test_cmp expect actual
)
'
-test_expect_success 'unsetting submodules config from the working tree with "submodule--helper config --unset"' '
+test_expect_success 'unsetting submodules config from the working tree' '
(cd super &&
- git submodule--helper config --unset submodule.submodule.url &&
- git submodule--helper config submodule.submodule.url >actual &&
+ test-tool submodule config-unset submodule.submodule.url &&
+ test-tool submodule config-list submodule.submodule.url >actual &&
test_must_be_empty actual
)
'
-test_expect_success 'writing submodules config with "submodule--helper config"' '
+test_expect_success 'writing submodules config' '
(cd super &&
echo "new_url" >expect &&
- git submodule--helper config submodule.submodule.url "new_url" &&
- git submodule--helper config submodule.submodule.url >actual &&
+ test-tool submodule config-set submodule.submodule.url "new_url" &&
+ test-tool submodule config-list submodule.submodule.url >actual &&
test_cmp expect actual
)
'
-test_expect_success 'overwriting unstaged submodules config with "submodule--helper config"' '
+test_expect_success 'overwriting unstaged submodules config' '
test_when_finished "git -C super checkout .gitmodules" &&
(cd super &&
echo "newer_url" >expect &&
- git submodule--helper config submodule.submodule.url "newer_url" &&
- git submodule--helper config submodule.submodule.url >actual &&
+ test-tool submodule config-set submodule.submodule.url "newer_url" &&
+ test-tool submodule config-list submodule.submodule.url >actual &&
test_cmp expect actual
)
'
test_expect_success 'writeable .gitmodules when it is in the working tree' '
- git -C super submodule--helper config --check-writeable
+ test-tool -C super submodule config-writeable
'
test_expect_success 'writeable .gitmodules when it is nowhere in the repository' '
@@ -183,7 +183,7 @@ test_expect_success 'writeable .gitmodules when it is nowhere in the repository'
(cd super &&
git rm .gitmodules &&
git commit -m "remove .gitmodules from the current branch" &&
- git submodule--helper config --check-writeable
+ test-tool submodule config-writeable
)
'
@@ -191,7 +191,7 @@ test_expect_success 'non-writeable .gitmodules when it is in the index but not i
test_when_finished "git -C super checkout .gitmodules" &&
(cd super &&
rm -f .gitmodules &&
- test_must_fail git submodule--helper config --check-writeable
+ test_must_fail test-tool submodule config-writeable
)
'
@@ -200,7 +200,7 @@ test_expect_success 'non-writeable .gitmodules when it is in the current branch
test_when_finished "git -C super reset --hard $ORIG" &&
(cd super &&
git rm .gitmodules &&
- test_must_fail git submodule--helper config --check-writeable
+ test_must_fail test-tool submodule config-writeable
)
'
@@ -208,11 +208,11 @@ test_expect_success 'reading submodules config from the index when .gitmodules i
ORIG=$(git -C super rev-parse HEAD) &&
test_when_finished "git -C super reset --hard $ORIG" &&
(cd super &&
- git submodule--helper config submodule.submodule.url "staged_url" &&
+ test-tool submodule config-set submodule.submodule.url "staged_url" &&
git add .gitmodules &&
rm -f .gitmodules &&
echo "staged_url" >expect &&
- git submodule--helper config submodule.submodule.url >actual &&
+ test-tool submodule config-list submodule.submodule.url >actual &&
test_cmp expect actual
)
'
@@ -223,7 +223,7 @@ test_expect_success 'reading submodules config from the current branch when .git
(cd super &&
git rm .gitmodules &&
echo "../submodule" >expect &&
- git submodule--helper config submodule.submodule.url >actual &&
+ test-tool submodule config-list submodule.submodule.url >actual &&
test_cmp expect actual
)
'
diff --git a/t/t7418-submodule-sparse-gitmodules.sh b/t/t7418-submodule-sparse-gitmodules.sh
index d5874200fd..dde11ecce8 100755
--- a/t/t7418-submodule-sparse-gitmodules.sh
+++ b/t/t7418-submodule-sparse-gitmodules.sh
@@ -50,12 +50,12 @@ test_expect_success 'sparse checkout setup which hides .gitmodules' '
test_expect_success 'reading gitmodules config file when it is not checked out' '
echo "../submodule" >expect &&
- git -C super submodule--helper config submodule.submodule.url >actual &&
+ test-tool -C super submodule config-list submodule.submodule.url >actual &&
test_cmp expect actual
'
test_expect_success 'not writing gitmodules config file when it is not checked out' '
- test_must_fail git -C super submodule--helper config submodule.submodule.url newurl &&
+ test_must_fail test-tool -C super submodule config-set submodule.submodule.url newurl &&
test_path_is_missing super/.gitmodules
'
diff --git a/t/t7422-submodule-output.sh b/t/t7422-submodule-output.sh
new file mode 100755
index 0000000000..ab946ec940
--- /dev/null
+++ b/t/t7422-submodule-output.sh
@@ -0,0 +1,170 @@
+#!/bin/sh
+
+test_description='submodule --cached, --quiet etc. output'
+
+TEST_PASSES_SANITIZE_LEAK=true
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-t3100.sh
+
+setup_sub () {
+ local d="$1" &&
+ shift &&
+ git $@ clone . "$d" &&
+ git $@ submodule add ./"$d"
+}
+
+normalize_status () {
+ sed -e 's/-g[0-9a-f]*/-gHASH/'
+}
+
+test_expect_success 'setup' '
+ test_commit A &&
+ test_commit B &&
+ setup_sub S &&
+ setup_sub S.D &&
+ setup_sub S.C &&
+ setup_sub S.C.D &&
+ setup_sub X &&
+ git add S* &&
+ test_commit C &&
+
+ # recursive in X/
+ git -C X pull &&
+ GIT_ALLOW_PROTOCOL=file git -C X submodule update --init &&
+
+ # dirty
+ for d in S.D X/S.D
+ do
+ echo dirty >"$d"/A.t || return 1
+ done &&
+
+ # commit (for --cached)
+ for d in S.C* X/S.C*
+ do
+ git -C "$d" reset --hard A || return 1
+ done &&
+
+ # dirty
+ for d in S*.D X/S*.D
+ do
+ echo dirty >"$d/C2.t" || return 1
+ done &&
+
+ for ref in A B C
+ do
+ # Not different with SHA-1 and SHA-256, just (ab)using
+ # test_oid_cache as a variable bag to avoid using
+ # $(git rev-parse ...).
+ oid=$(git rev-parse $ref) &&
+ test_oid_cache <<-EOF || return 1
+ $ref sha1:$oid
+ $ref sha256:$oid
+ EOF
+ done
+'
+
+for opts in "" "status"
+do
+ test_expect_success "git submodule $opts" '
+ sed -e "s/^>//" >expect <<-EOF &&
+ > $(test_oid B) S (B)
+ >+$(test_oid A) S.C (A)
+ >+$(test_oid A) S.C.D (A)
+ > $(test_oid B) S.D (B)
+ >+$(test_oid C) X (C)
+ EOF
+ git submodule $opts >actual.raw &&
+ normalize_status <actual.raw >actual &&
+ test_cmp expect actual
+ '
+done
+
+for opts in \
+ "status --recursive"
+do
+ test_expect_success "git submodule $opts" '
+ sed -e "s/^>//" >expect <<-EOF &&
+ > $(test_oid B) S (B)
+ >+$(test_oid A) S.C (A)
+ >+$(test_oid A) S.C.D (A)
+ > $(test_oid B) S.D (B)
+ >+$(test_oid C) X (C)
+ > $(test_oid B) X/S (B)
+ >+$(test_oid A) X/S.C (A)
+ >+$(test_oid A) X/S.C.D (A)
+ > $(test_oid B) X/S.D (B)
+ > $(test_oid B) X/X (B)
+ EOF
+ git submodule $opts >actual.raw &&
+ normalize_status <actual.raw >actual &&
+ test_cmp expect actual
+ '
+done
+
+for opts in \
+ "--quiet" \
+ "--quiet status" \
+ "status --quiet"
+do
+ test_expect_success "git submodule $opts" '
+ git submodule $opts >out &&
+ test_must_be_empty out
+ '
+done
+
+for opts in \
+ "--cached" \
+ "--cached status" \
+ "status --cached"
+do
+ test_expect_success "git submodule $opts" '
+ sed -e "s/^>//" >expect <<-EOF &&
+ > $(test_oid B) S (B)
+ >+$(test_oid B) S.C (B)
+ >+$(test_oid B) S.C.D (B)
+ > $(test_oid B) S.D (B)
+ >+$(test_oid B) X (B)
+ EOF
+ git submodule $opts >actual.raw &&
+ normalize_status <actual.raw >actual &&
+ test_cmp expect actual
+ '
+done
+
+for opts in \
+ "--cached --quiet" \
+ "--cached --quiet status" \
+ "--cached status --quiet" \
+ "--quiet status --cached" \
+ "status --cached --quiet"
+do
+ test_expect_success "git submodule $opts" '
+ git submodule $opts >out &&
+ test_must_be_empty out
+ '
+done
+
+for opts in \
+ "status --cached --recursive" \
+ "--cached status --recursive"
+do
+ test_expect_success "git submodule $opts" '
+ sed -e "s/^>//" >expect <<-EOF &&
+ > $(test_oid B) S (B)
+ >+$(test_oid B) S.C (B)
+ >+$(test_oid B) S.C.D (B)
+ > $(test_oid B) S.D (B)
+ >+$(test_oid B) X (B)
+ > $(test_oid B) X/S (B)
+ >+$(test_oid B) X/S.C (B)
+ >+$(test_oid B) X/S.C.D (B)
+ > $(test_oid B) X/S.D (B)
+ > $(test_oid B) X/X (B)
+ EOF
+ git submodule $opts >actual.raw &&
+ normalize_status <actual.raw >actual &&
+ test_cmp expect actual
+ '
+done
+
+test_done