From: Prathamesh Chavan <pc44800@gmail.com>
To: git@vger.kernel.org
Cc: sbeller@google.com, christian.couder@gmail.com,
Prathamesh Chavan <pc44800@gmail.com>
Subject: [GSoC][PATCH 4/6] submodule: port submodule subcommand status
Date: Tue, 20 Jun 2017 03:20:23 +0530 [thread overview]
Message-ID: <20170619215025.10086-4-pc44800@gmail.com> (raw)
In-Reply-To: <20170619215025.10086-1-pc44800@gmail.com>
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 <christian.couder@gmail.com>
Mentored-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Prathamesh Chavan <pc44800@gmail.com>
---
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(&name_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(&list_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(&diff_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(&cp.env_array);
+ cp.git_cmd = 1;
+ cp.dir = list_item->name;
+
+ argv_array_pushl(&cp.args, "rev-parse",
+ "--verify", "HEAD", NULL);
+
+ if (capture_command(&cp, &sb, 0))
+ die(_("could not run 'git rev-parse --verify"
+ "HEAD' in submodule %s"),
+ list_item->name);
+
+ strbuf_strip_suffix(&sb, "\n");
+ print_status(info, '+', list_item->name, sb.buf,
+ displaypath);
+ strbuf_release(&sb);
+ } 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(&cpr.env_array);
+
+ argv_array_pushl(&cpr.args, "--super-prefix", displaypath,
+ "submodule--helper", "status", "--recursive",
+ NULL);
+
+ if (info->cached)
+ argv_array_push(&cpr.args, "--cached");
+
+ if (info->quiet)
+ argv_array_push(&cpr.args, "--quiet");
+
+ if (run_command(&cpr))
+ die(_("failed to recurse into submodule '%s'"),
+ list_item->name);
+ }
+
+cleanup:
+ free(displaypath);
+ free(sub_sha1);
+}
+
+static int module_status(int argc, const char **argv, const char *prefix)
+{
+ struct status_cb info = STATUS_CB_INIT;
+ struct pathspec pathspec;
+ struct module_list list = MODULE_LIST_INIT;
+ int quiet = 0;
+ int cached = 0;
+ int recursive = 0;
+
+ struct option module_status_options[] = {
+ OPT__QUIET(&quiet, N_("Suppress submodule status output")),
+ OPT_BOOL(0, "cached", &cached, N_("Use commit stored in the index instead of the one stored in the submodule HEAD")),
+ OPT_BOOL(0, "recursive", &recursive, N_("Recurse into nested submodules")),
+ OPT_END()
+ };
+
+ const char *const git_submodule_helper_usage[] = {
+ N_("git submodule status [--quiet] [--cached] [--recursive] [<path>]"),
+ NULL
+ };
+
+ argc = parse_options(argc, argv, prefix, module_status_options,
+ git_submodule_helper_usage, 0);
+
+ if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0)
+ return 1;
+
+ info.prefix = prefix;
+ info.quiet = !!quiet;
+ info.recursive = !!recursive;
+ info.cached = !!cached;
+
+ gitmodules_config();
+ for_each_submodule_list(list, status_submodule, &info);
+
+ return 0;
+}
+
static int module_name(int argc, const char **argv, const char *prefix)
{
const struct submodule *sub;
@@ -1312,6 +1463,7 @@ static struct cmd_struct commands[] = {
{"resolve-relative-url-test", resolve_relative_url_test, 0},
{"print-name-rev", print_name_rev, 0},
{"init", module_init, SUPPORT_SUPER_PREFIX},
+ {"status", module_status, SUPPORT_SUPER_PREFIX},
{"remote-branch", resolve_remote_submodule_branch, 0},
{"push-check", push_check, 0},
{"absorb-git-dirs", absorb_git_dirs, SUPPORT_SUPER_PREFIX},
diff --git a/git-submodule.sh b/git-submodule.sh
index 091051891..a24b1b91b 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -1004,54 +1004,7 @@ cmd_status()
shift
done
- {
- git submodule--helper list --prefix "$wt_prefix" "$@" ||
- echo "#unmatched" $?
- } |
- while read -r mode sha1 stage sm_path
- do
- die_if_unmatched "$mode" "$sha1"
- name=$(git submodule--helper name "$sm_path") || exit
- displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix")
- if test "$stage" = U
- then
- say "U$sha1 $displaypath"
- continue
- fi
- if ! git submodule--helper is-active "$sm_path" ||
- {
- ! test -d "$sm_path"/.git &&
- ! test -f "$sm_path"/.git
- }
- then
- say "-$sha1 $displaypath"
- continue;
- fi
- if git diff-files --ignore-submodules=dirty --quiet -- "$sm_path"
- then
- revname=$(git submodule--helper print-name-rev "$sm_path" "$sha1")
- say " $sha1 $displaypath$revname"
- else
- if test -z "$cached"
- then
- sha1=$(sanitize_submodule_env; cd "$sm_path" && git rev-parse --verify HEAD)
- fi
- revname=$(git submodule--helper print-name-rev "$sm_path" "$sha1")
- say "+$sha1 $displaypath$revname"
- fi
-
- if test -n "$recursive"
- then
- (
- prefix="$displaypath/"
- sanitize_submodule_env
- wt_prefix=
- cd "$sm_path" &&
- eval cmd_status
- ) ||
- die "$(eval_gettext "Failed to recurse into submodule path '\$sm_path'")"
- fi
- done
+ git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper status ${GIT_QUIET:+--quiet} ${cached:+--cached} ${recursive:+--recursive} "$@"
}
#
# Sync remote urls for submodules
--
2.13.0
next prev parent reply other threads:[~2017-06-19 21:51 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-19 21:41 [GSoC] Update: Week 5 Prathamesh Chavan
2017-06-19 21:50 ` [GSoC][PATCH 1/6] dir: create function count_slashes Prathamesh Chavan
2017-06-19 21:50 ` [GSoC][PATCH 2/6] submodule--helper: introduce get_submodule_displaypath and for_each_submodule_list Prathamesh Chavan
2017-06-20 18:22 ` Brandon Williams
2017-06-22 7:01 ` Christian Couder
2017-06-19 21:50 ` [GSoC][PATCH 3/6] submodule: port set_name_rev from shell to C Prathamesh Chavan
2017-06-19 21:50 ` Prathamesh Chavan [this message]
2017-06-20 18:44 ` [GSoC][PATCH 4/6] submodule: port submodule subcommand status Brandon Williams
2017-06-19 21:50 ` [GSoC][PATCH 5/6] submodule: port submodule subcommand sync from shell to C Prathamesh Chavan
2017-06-20 17:35 ` Stefan Beller
2017-06-22 6:50 ` Christian Couder
2017-06-19 21:50 ` [GSoC][PATCH 6/6] submodule: port submodule subcommand 'deinit' " Prathamesh Chavan
2017-06-20 17:20 ` [GSoC][PATCH 1/6] dir: create function count_slashes Stefan Beller
2017-06-20 0:01 ` [GSoC] Update: Week 5 Andrew Ardill
2017-06-20 0:38 ` Brandon Williams
2017-06-26 23:24 ` Prathamesh Chavan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170619215025.10086-4-pc44800@gmail.com \
--to=pc44800@gmail.com \
--cc=christian.couder@gmail.com \
--cc=git@vger.kernel.org \
--cc=sbeller@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.