The mechanism used for porting submodule subcommand 'status'
is similar to that used for subcommand 'foreach'.
The function cmd_status from git-submodule is ported to three
functions in the builtin submodule--helper namely: module_status,
for_each_submodule_list and status_submodule.
print_status is also introduced for handling the output of
the subcommand and also to reduce the code size.
Mentored-by: Christian Couder
Mentored-by: Stefan Beller
Signed-off-by: Prathamesh Chavan
---
builtin/submodule--helper.c | 152
git-submodule.sh| 49 +-
2 files changed, 153 insertions(+), 48 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 6fd861e42..78b21ab22 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -566,6 +566,157 @@ static int module_init(int argc, const char **argv, const
char *prefix)
return 0;
}
+struct status_cb {
+ const char *prefix;
+ unsigned int quiet: 1;
+ unsigned int recursive: 1;
+ unsigned int cached: 1;
+};
+#define STATUS_CB_INIT { NULL, 0, 0, 0 }
+
+static void print_status(struct status_cb *info, char state, const char *path,
+char *sub_sha1, char *displaypath)
+{
+ if (info->quiet)
+ return;
+
+ printf("%c%s %s", state, sub_sha1, displaypath);
+
+ if (state == ' ' || state == '+') {
+ struct argv_array name_rev_args = ARGV_ARRAY_INIT;
+
+ argv_array_pushl(_rev_args, "print-name-rev",
+path, sub_sha1, NULL);
+ print_name_rev(name_rev_args.argc, name_rev_args.argv,
+ info->prefix);
+ } else {
+ printf("\n");
+ }
+}
+
+static void status_submodule(const struct cache_entry *list_item, void
*cb_data)
+{
+ struct status_cb *info = cb_data;
+ char *sub_sha1 = xstrdup(oid_to_hex(_item->oid));
+ char *displaypath;
+ struct argv_array diff_files_args = ARGV_ARRAY_INIT;
+
+ if (!submodule_from_path(null_sha1, list_item->name))
+ die(_("no submodule mapping found in .gitmodules for path
'%s'"),
+ list_item->name);
+
+ displaypath = get_submodule_displaypath(list_item->name, info->prefix);
+
+ if (list_item->ce_flags) {
+ print_status(info, 'U', list_item->name,
+sha1_to_hex(null_sha1), displaypath);
+ goto cleanup;
+ }
+
+ if (!is_submodule_initialized(list_item->name)) {
+ print_status(info, '-', list_item->name, sub_sha1, displaypath);
+ goto cleanup;
+ }
+
+ argv_array_pushl(_files_args, "diff-files",
+"--ignore-submodules=dirty", "--quiet", "--",
+list_item->name, NULL);
+
+ if (!cmd_diff_files(diff_files_args.argc, diff_files_args.argv,
+ info->prefix)) {
+ print_status(info, ' ', list_item->name, sub_sha1, displaypath);
+ } else {
+ if (!info->cached) {
+ struct child_process cp = CHILD_PROCESS_INIT;
+ struct strbuf sb = STRBUF_INIT;
+
+ prepare_submodule_repo_env(_array);
+ cp.git_cmd = 1;
+ cp.dir = list_item->name;
+
+ argv_array_pushl(, "rev-parse",
+"--verify", "HEAD", NULL);
+
+ if (capture_command(, , 0))
+ die(_("could not run 'git rev-parse --verify"
+ "HEAD' in submodule %s"),
+ list_item->name);
+
+ strbuf_strip_suffix(, "\n");
+ print_status(info, '+', list_item->name, sb.buf,
+displaypath);
+ strbuf_release();
+ } else {
+ print_status(info, '+', list_item->name, sub_sha1,
+displaypath);
+ }
+ }
+
+ if (info->recursive) {
+ struct child_process cpr = CHILD_PROCESS_INIT;
+
+ cpr.git_cmd = 1;
+ cpr.dir = list_item->name;
+ prepare_submodule_repo_env(_array);
+
+ argv_array_pushl(, "--super-prefix", displaypath,
+"submodule--helper", "status", "--recursive",
+NULL);
+
+ if (info->cached)
+ argv_array_push(, "--cached");
+
+ if (info->quiet)
+ argv_array_push(, "--quiet");
+
+ if (run_command())
+ die(_("failed to recurse into submodule