Most of the submodule operations work on a set of submodules. Calculating and using this set is usually done via: module_list "$@" | { while read mode sha1 stage sm_path do # the actual operation done } Currently the function `module_list` is implemented in the git-submodule.sh as a shell script wrapping a perl script. The rewrite is in C, such that it is faster and can later be easily adapted when other functions are rewritten in C. Signed-off-by: Stefan Beller <sbeller@xxxxxxxxxx> --- Makefile | 1 + builtin.h | 1 + builtin/submodule--helper.c | 99 +++++++++++++++++++++++++++++++++++++++++++++ git.c | 1 + 4 files changed, 102 insertions(+) create mode 100644 builtin/submodule--helper.c diff --git a/Makefile b/Makefile index 8c3c724..6fb7484 100644 --- a/Makefile +++ b/Makefile @@ -898,6 +898,7 @@ BUILTIN_OBJS += builtin/shortlog.o BUILTIN_OBJS += builtin/show-branch.o BUILTIN_OBJS += builtin/show-ref.o BUILTIN_OBJS += builtin/stripspace.o +BUILTIN_OBJS += builtin/submodule--helper.o BUILTIN_OBJS += builtin/symbolic-ref.o BUILTIN_OBJS += builtin/tag.o BUILTIN_OBJS += builtin/unpack-file.o diff --git a/builtin.h b/builtin.h index 9e04f97..7bf9597 100644 --- a/builtin.h +++ b/builtin.h @@ -118,6 +118,7 @@ extern int cmd_show(int argc, const char **argv, const char *prefix); extern int cmd_show_branch(int argc, const char **argv, const char *prefix); extern int cmd_status(int argc, const char **argv, const char *prefix); extern int cmd_stripspace(int argc, const char **argv, const char *prefix); +extern int cmd_submodule__helper(int argc, const char **argv, const char *prefix); extern int cmd_symbolic_ref(int argc, const char **argv, const char *prefix); extern int cmd_tag(int argc, const char **argv, const char *prefix); extern int cmd_tar_tree(int argc, const char **argv, const char *prefix); diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c new file mode 100644 index 0000000..2e24fdc --- /dev/null +++ b/builtin/submodule--helper.c @@ -0,0 +1,99 @@ +#include "builtin.h" +#include "cache.h" +#include "parse-options.h" +#include "quote.h" +#include "pathspec.h" +#include "dir.h" + +static const char * const git_submodule_helper_usage[] = { + N_("git submodule--helper --module_list [<path>...]"), + NULL +}; + +int module_list(int argc, const char **argv, const char *prefix) +{ + int i; + static struct pathspec pathspec; + const struct cache_entry **ce_entries = NULL; + int alloc = 0, used = 0; + char *ps_matched = NULL; + char *max_prefix; + int max_prefix_len; + struct string_list already_printed = STRING_LIST_INIT_NODUP; + + parse_pathspec(&pathspec, 0, + PATHSPEC_PREFER_FULL, + prefix, argv); + + /* Find common prefix for all pathspec's */ + max_prefix = common_prefix(&pathspec); + max_prefix_len = max_prefix ? strlen(max_prefix) : 0; + + if (pathspec.nr) + ps_matched = xcalloc(1, pathspec.nr); + + if (read_cache() < 0) + die("index file corrupt"); + + for (i = 0; i < active_nr; i++) { + const struct cache_entry *ce = active_cache[i]; + + if (!match_pathspec(&pathspec, ce->name, ce_namelen(ce), + max_prefix_len, ps_matched, + S_ISGITLINK(ce->ce_mode) | S_ISDIR(ce->ce_mode))) + continue; + + if (S_ISGITLINK(ce->ce_mode)) { + ALLOC_GROW(ce_entries, used + 1, alloc); + ce_entries[used++] = ce; + } + } + + if (ps_matched && report_path_error(ps_matched, &pathspec, prefix)) { + printf("#unmatched\n"); + return 1; + } + + for (i = 0; i < used; i++) { + const struct cache_entry *ce = ce_entries[i]; + + if (string_list_has_string(&already_printed, ce->name)) + continue; + + if (ce_stage(ce)) { + printf("%06o %s U\t", ce->ce_mode, sha1_to_hex(null_sha1)); + } else { + printf("%06o %s %d\t", ce->ce_mode, sha1_to_hex(ce->sha1), ce_stage(ce)); + } + write_name_quoted(ce->name, stdout, '\n'); + string_list_insert(&already_printed, ce->name); + } + return 0; +} + +int cmd_submodule__helper(int argc, const char **argv, const char *prefix) +{ + enum { + MODE_UNSPECIFIED = 0, + MODE_MODULE_LIST, + } cmdmode = MODE_UNSPECIFIED; + + struct option options[] = { + OPT_CMDMODE(0, "module_list", &cmdmode, + N_("Get the submodule list"), MODE_MODULE_LIST), + OPT_END() + }; + + argc = parse_options(argc, argv, prefix, options, + git_submodule_helper_usage, 0); + + switch (cmdmode) { + case MODE_MODULE_LIST: + return module_list(argc, argv, prefix); + break; + case MODE_UNSPECIFIED: + usage_with_options(git_submodule_helper_usage, options); + break; + } + return 0; +} diff --git a/git.c b/git.c index fe94066..721995e 100644 --- a/git.c +++ b/git.c @@ -468,6 +468,7 @@ static struct cmd_struct commands[] = { { "stage", cmd_add, RUN_SETUP | NEED_WORK_TREE }, { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE }, { "stripspace", cmd_stripspace }, + { "submodule--helper", cmd_submodule__helper, RUN_SETUP }, { "symbolic-ref", cmd_symbolic_ref, RUN_SETUP }, { "tag", cmd_tag, RUN_SETUP }, { "unpack-file", cmd_unpack_file, RUN_SETUP }, -- 2.5.0.5.gf4cd9ae.dirty -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html