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 <sbel...@google.com>
---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to