Skip to content

Commit 1107a39

Browse files
committed
Merge branch 'ab/submodule-helper-prep-only'
Preparation to remove git-submodule.sh and replace it with a builtin. * ab/submodule-helper-prep-only: submodule--helper: use OPT_SUBCOMMAND() API submodule--helper: drop "update --prefix <pfx>" for "-C <pfx> update" submodule--helper: remove --prefix from "absorbgitdirs" submodule API & "absorbgitdirs": remove "----recursive" option submodule.c: refactor recursive block out of absorb function submodule tests: test for a "foreach" blind-spot submodule--helper: fix a memory leak in "status" submodule tests: add tests for top-level flag output submodule--helper: move "config" to a test-tool
2 parents a078951 + 69d9446 commit 1107a39

12 files changed

+358
-150
lines changed

builtin/rm.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,7 @@ static void submodules_absorb_gitdir_if_needed(void)
8686
continue;
8787

8888
if (!submodule_uses_gitfile(name))
89-
absorb_git_dir_into_superproject(name,
90-
ABSORB_GITDIR_RECURSE_SUBMODULES);
89+
absorb_git_dir_into_superproject(name);
9190
}
9291
}
9392

builtin/submodule--helper.c

Lines changed: 45 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,9 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
616616
int diff_files_result;
617617
struct strbuf buf = STRBUF_INIT;
618618
const char *git_dir;
619+
struct setup_revision_opt opt = {
620+
.free_removed_argv_elements = 1,
621+
};
619622

620623
if (!submodule_from_path(the_repository, null_oid(), path))
621624
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,
649652

650653
repo_init_revisions(the_repository, &rev, NULL);
651654
rev.abbrev = 0;
652-
diff_files_args.nr = setup_revisions(diff_files_args.nr,
653-
diff_files_args.v,
654-
&rev, NULL);
655+
setup_revisions(diff_files_args.nr, diff_files_args.v, &rev, &opt);
655656
diff_files_result = run_diff_files(&rev, 0);
656657

657658
if (!diff_result_code(&rev.diffopt, diff_files_result)) {
@@ -1378,8 +1379,7 @@ static void deinit_submodule(const char *path, const char *prefix,
13781379
".git file by using absorbgitdirs."),
13791380
displaypath);
13801381

1381-
absorb_git_dir_into_superproject(path,
1382-
ABSORB_GITDIR_RECURSE_SUBMODULES);
1382+
absorb_git_dir_into_superproject(path);
13831383

13841384
}
13851385

@@ -2643,9 +2643,6 @@ static int module_update(int argc, const char **argv, const char *prefix)
26432643
N_("traverse submodules recursively")),
26442644
OPT_BOOL('N', "no-fetch", &opt.nofetch,
26452645
N_("don't fetch new objects from the remote site")),
2646-
OPT_STRING(0, "prefix", &opt.prefix,
2647-
N_("path"),
2648-
N_("path into the working tree")),
26492646
OPT_SET_INT(0, "checkout", &opt.update_default,
26502647
N_("use the 'checkout' update strategy (default)"),
26512648
SM_UPDATE_CHECKOUT),
@@ -2701,6 +2698,7 @@ static int module_update(int argc, const char **argv, const char *prefix)
27012698
}
27022699

27032700
opt.filter_options = &filter_options;
2701+
opt.prefix = prefix;
27042702

27052703
if (opt.update_default)
27062704
opt.update_strategy.type = opt.update_default;
@@ -2830,13 +2828,7 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
28302828
int i;
28312829
struct pathspec pathspec = { 0 };
28322830
struct module_list list = MODULE_LIST_INIT;
2833-
unsigned flags = ABSORB_GITDIR_RECURSE_SUBMODULES;
28342831
struct option embed_gitdir_options[] = {
2835-
OPT_STRING(0, "prefix", &prefix,
2836-
N_("path"),
2837-
N_("path into the working tree")),
2838-
OPT_BIT(0, "--recursive", &flags, N_("recurse into submodules"),
2839-
ABSORB_GITDIR_RECURSE_SUBMODULES),
28402832
OPT_END()
28412833
};
28422834
const char *const git_submodule_helper_usage[] = {
@@ -2852,7 +2844,7 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
28522844
goto cleanup;
28532845

28542846
for (i = 0; i < list.nr; i++)
2855-
absorb_git_dir_into_superproject(list.entries[i]->name, flags);
2847+
absorb_git_dir_into_superproject(list.entries[i]->name);
28562848

28572849
ret = 0;
28582850
cleanup:
@@ -2861,51 +2853,6 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
28612853
return ret;
28622854
}
28632855

2864-
static int module_config(int argc, const char **argv, const char *prefix)
2865-
{
2866-
enum {
2867-
CHECK_WRITEABLE = 1,
2868-
DO_UNSET = 2
2869-
} command = 0;
2870-
struct option module_config_options[] = {
2871-
OPT_CMDMODE(0, "check-writeable", &command,
2872-
N_("check if it is safe to write to the .gitmodules file"),
2873-
CHECK_WRITEABLE),
2874-
OPT_CMDMODE(0, "unset", &command,
2875-
N_("unset the config in the .gitmodules file"),
2876-
DO_UNSET),
2877-
OPT_END()
2878-
};
2879-
const char *const git_submodule_helper_usage[] = {
2880-
N_("git submodule--helper config <name> [<value>]"),
2881-
N_("git submodule--helper config --unset <name>"),
2882-
"git submodule--helper config --check-writeable",
2883-
NULL
2884-
};
2885-
2886-
argc = parse_options(argc, argv, prefix, module_config_options,
2887-
git_submodule_helper_usage, PARSE_OPT_KEEP_ARGV0);
2888-
2889-
if (argc == 1 && command == CHECK_WRITEABLE)
2890-
return is_writing_gitmodules_ok() ? 0 : -1;
2891-
2892-
/* Equivalent to ACTION_GET in builtin/config.c */
2893-
if (argc == 2 && command != DO_UNSET)
2894-
return print_config_from_gitmodules(the_repository, argv[1]);
2895-
2896-
/* Equivalent to ACTION_SET in builtin/config.c */
2897-
if (argc == 3 || (argc == 2 && command == DO_UNSET)) {
2898-
const char *value = (argc == 3) ? argv[2] : NULL;
2899-
2900-
if (!is_writing_gitmodules_ok())
2901-
die(_("please make sure that the .gitmodules file is in the working tree"));
2902-
2903-
return config_set_in_gitmodules_file_gently(argv[1], value);
2904-
}
2905-
2906-
usage_with_options(git_submodule_helper_usage, module_config_options);
2907-
}
2908-
29092856
static int module_set_url(int argc, const char **argv, const char *prefix)
29102857
{
29112858
int quiet = 0;
@@ -3404,48 +3351,45 @@ static int module_add(int argc, const char **argv, const char *prefix)
34043351
return ret;
34053352
}
34063353

3407-
#define SUPPORT_SUPER_PREFIX (1<<0)
3408-
3409-
struct cmd_struct {
3410-
const char *cmd;
3411-
int (*fn)(int, const char **, const char *);
3412-
unsigned option;
3413-
};
3414-
3415-
static struct cmd_struct commands[] = {
3416-
{"clone", module_clone, SUPPORT_SUPER_PREFIX},
3417-
{"add", module_add, 0},
3418-
{"update", module_update, SUPPORT_SUPER_PREFIX},
3419-
{"foreach", module_foreach, SUPPORT_SUPER_PREFIX},
3420-
{"init", module_init, 0},
3421-
{"status", module_status, SUPPORT_SUPER_PREFIX},
3422-
{"sync", module_sync, SUPPORT_SUPER_PREFIX},
3423-
{"deinit", module_deinit, 0},
3424-
{"summary", module_summary, 0},
3425-
{"push-check", push_check, 0},
3426-
{"absorbgitdirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX},
3427-
{"config", module_config, 0},
3428-
{"set-url", module_set_url, 0},
3429-
{"set-branch", module_set_branch, 0},
3430-
{"create-branch", module_create_branch, 0},
3431-
};
3432-
34333354
int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
34343355
{
3435-
int i;
3436-
if (argc < 2 || !strcmp(argv[1], "-h"))
3437-
usage("git submodule--helper <command>");
3438-
3439-
for (i = 0; i < ARRAY_SIZE(commands); i++) {
3440-
if (!strcmp(argv[1], commands[i].cmd)) {
3441-
if (get_super_prefix() &&
3442-
!(commands[i].option & SUPPORT_SUPER_PREFIX))
3443-
die(_("%s doesn't support --super-prefix"),
3444-
commands[i].cmd);
3445-
return commands[i].fn(argc - 1, argv + 1, prefix);
3446-
}
3447-
}
3356+
const char *cmd = argv[0];
3357+
const char *subcmd;
3358+
parse_opt_subcommand_fn *fn = NULL;
3359+
const char *const usage[] = {
3360+
N_("git submodule--helper <command>"),
3361+
NULL
3362+
};
3363+
struct option options[] = {
3364+
OPT_SUBCOMMAND("clone", &fn, module_clone),
3365+
OPT_SUBCOMMAND("add", &fn, module_add),
3366+
OPT_SUBCOMMAND("update", &fn, module_update),
3367+
OPT_SUBCOMMAND("foreach", &fn, module_foreach),
3368+
OPT_SUBCOMMAND("init", &fn, module_init),
3369+
OPT_SUBCOMMAND("status", &fn, module_status),
3370+
OPT_SUBCOMMAND("sync", &fn, module_sync),
3371+
OPT_SUBCOMMAND("deinit", &fn, module_deinit),
3372+
OPT_SUBCOMMAND("summary", &fn, module_summary),
3373+
OPT_SUBCOMMAND("push-check", &fn, push_check),
3374+
OPT_SUBCOMMAND("absorbgitdirs", &fn, absorb_git_dirs),
3375+
OPT_SUBCOMMAND("set-url", &fn, module_set_url),
3376+
OPT_SUBCOMMAND("set-branch", &fn, module_set_branch),
3377+
OPT_SUBCOMMAND("create-branch", &fn, module_create_branch),
3378+
OPT_END()
3379+
};
3380+
argc = parse_options(argc, argv, prefix, options, usage, 0);
3381+
subcmd = argv[0];
3382+
3383+
if (strcmp(subcmd, "clone") && strcmp(subcmd, "update") &&
3384+
strcmp(subcmd, "foreach") && strcmp(subcmd, "status") &&
3385+
strcmp(subcmd, "sync") && strcmp(subcmd, "absorbgitdirs") &&
3386+
get_super_prefix())
3387+
/*
3388+
* xstrfmt() rather than "%s %s" to keep the translated
3389+
* string identical to git.c's.
3390+
*/
3391+
die(_("%s doesn't support --super-prefix"),
3392+
xstrfmt("'%s %s'", cmd, subcmd));
34483393

3449-
die(_("'%s' is not a valid submodule--helper "
3450-
"subcommand"), argv[1]);
3394+
return fn(argc, argv, prefix);
34513395
}

git-submodule.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,6 @@ cmd_update()
343343
${recursive:+--recursive} \
344344
${init:+--init} \
345345
${nofetch:+--no-fetch} \
346-
${wt_prefix:+--prefix "$wt_prefix"} \
347346
${rebase:+--rebase} \
348347
${merge:+--merge} \
349348
${checkout:+--checkout} \
@@ -557,7 +556,7 @@ cmd_sync()
557556

558557
cmd_absorbgitdirs()
559558
{
560-
git submodule--helper absorbgitdirs --prefix "$wt_prefix" "$@"
559+
git ${wt_prefix:+-C "$wt_prefix"} submodule--helper absorbgitdirs "$@"
561560
}
562561

563562
# This loop parses the command line arguments to find the

git.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ static struct cmd_struct commands[] = {
610610
{ "stash", cmd_stash, RUN_SETUP | NEED_WORK_TREE },
611611
{ "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
612612
{ "stripspace", cmd_stripspace },
613-
{ "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX | NO_PARSEOPT },
613+
{ "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX },
614614
{ "switch", cmd_switch, RUN_SETUP | NEED_WORK_TREE },
615615
{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
616616
{ "tag", cmd_tag, RUN_SETUP | DELAY_PAGER_CONFIG },

submodule.c

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2139,8 +2139,7 @@ int submodule_move_head(const char *path,
21392139
if (!(flags & SUBMODULE_MOVE_HEAD_DRY_RUN)) {
21402140
if (old_head) {
21412141
if (!submodule_uses_gitfile(path))
2142-
absorb_git_dir_into_superproject(path,
2143-
ABSORB_GITDIR_RECURSE_SUBMODULES);
2142+
absorb_git_dir_into_superproject(path);
21442143
} else {
21452144
struct strbuf gitdir = STRBUF_INIT;
21462145
submodule_name_to_gitdir(&gitdir, the_repository,
@@ -2310,13 +2309,29 @@ static void relocate_single_git_dir_into_superproject(const char *path)
23102309
strbuf_release(&new_gitdir);
23112310
}
23122311

2312+
static void absorb_git_dir_into_superproject_recurse(const char *path)
2313+
{
2314+
2315+
struct child_process cp = CHILD_PROCESS_INIT;
2316+
2317+
cp.dir = path;
2318+
cp.git_cmd = 1;
2319+
cp.no_stdin = 1;
2320+
strvec_pushf(&cp.args, "--super-prefix=%s%s/",
2321+
get_super_prefix_or_empty(), path);
2322+
strvec_pushl(&cp.args, "submodule--helper",
2323+
"absorbgitdirs", NULL);
2324+
prepare_submodule_repo_env(&cp.env);
2325+
if (run_command(&cp))
2326+
die(_("could not recurse into submodule '%s'"), path);
2327+
}
2328+
23132329
/*
23142330
* Migrate the git directory of the submodule given by path from
23152331
* having its git directory within the working tree to the git dir nested
23162332
* in its superprojects git dir under modules/.
23172333
*/
2318-
void absorb_git_dir_into_superproject(const char *path,
2319-
unsigned flags)
2334+
void absorb_git_dir_into_superproject(const char *path)
23202335
{
23212336
int err_code;
23222337
const char *sub_git_dir;
@@ -2365,23 +2380,7 @@ void absorb_git_dir_into_superproject(const char *path,
23652380
}
23662381
strbuf_release(&gitdir);
23672382

2368-
if (flags & ABSORB_GITDIR_RECURSE_SUBMODULES) {
2369-
struct child_process cp = CHILD_PROCESS_INIT;
2370-
2371-
if (flags & ~ABSORB_GITDIR_RECURSE_SUBMODULES)
2372-
BUG("we don't know how to pass the flags down?");
2373-
2374-
cp.dir = path;
2375-
cp.git_cmd = 1;
2376-
cp.no_stdin = 1;
2377-
strvec_pushf(&cp.args, "--super-prefix=%s%s/",
2378-
get_super_prefix_or_empty(), path);
2379-
strvec_pushl(&cp.args, "submodule--helper",
2380-
"absorbgitdirs", NULL);
2381-
prepare_submodule_repo_env(&cp.env);
2382-
if (run_command(&cp))
2383-
die(_("could not recurse into submodule '%s'"), path);
2384-
}
2383+
absorb_git_dir_into_superproject_recurse(path);
23852384
}
23862385

23872386
int get_superproject_working_tree(struct strbuf *buf)

submodule.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,7 @@ void submodule_unset_core_worktree(const struct submodule *sub);
164164
*/
165165
void prepare_submodule_repo_env(struct strvec *env);
166166

167-
#define ABSORB_GITDIR_RECURSE_SUBMODULES (1<<0)
168-
void absorb_git_dir_into_superproject(const char *path,
169-
unsigned flags);
167+
void absorb_git_dir_into_superproject(const char *path);
170168

171169
/*
172170
* Return the absolute path of the working tree of the superproject, which this

0 commit comments

Comments
 (0)