submodule: rewrite `module_name` shell function in C

This implements the helper `name` in C instead of shell, yielding a nice performance boost. Before this patch, I measured a time (best out of three): $ time ./t7400-submodule-basic.sh >/dev/null real 0m11.066s user 0m3.348s sys 0m8.534s With this patch applied I measured (also best out of three) $ time ./t7400-submodule-basic.sh >/dev/null real 0m10.063s user 0m3.044s sys 0m7.487s Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Stefan Beller committed Sep 2, 2015 at 14:42 UTC 0ea306ef1701d6f42e74d3c33addfcd630248904
2 files changed +29 -25
builtin/submodule--helper.c
+22
@@ -5,6 +5,9 @@
5 #include "pathspec.h"
6 #include "dir.h"
7 #include "utf8.h"
8 +#include "submodule.h"
9 +#include "submodule-config.h"
10 +#include "string-list.h"
11
12 struct module_list {
13 const struct cache_entry **entries;
@@ -102,6 +105,24 @@ static int module_list(int argc, const char **argv, const char *prefix)
105 return 0;
106 }
107
108 +static int module_name(int argc, const char **argv, const char *prefix)
109 +{
110 + const struct submodule *sub;
111 +
112 + if (argc != 2)
113 + usage(_("git submodule--helper name <path>"));
114 +
115 + gitmodules_config();
116 + sub = submodule_from_path(null_sha1, argv[1]);
117 +
118 + if (!sub)
119 + die(_("no submodule mapping found in .gitmodules for path '%s'"),
120 + argv[1]);
121 +
122 + printf("%s\n", sub->name);
123 +
124 + return 0;
125 +}
126
127 struct cmd_struct {
128 const char *cmd;
@@ -110,6 +131,7 @@ struct cmd_struct {
131
132 static struct cmd_struct commands[] = {
133 {"list", module_list},
134 + {"name", module_name},
135 };
136
137 int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
git-submodule.sh
+7 -25
@@ -178,24 +178,6 @@ get_submodule_config () {
178 printf '%s' "${value:-$default}"
179 }
180
181 -
182 -#
183 -# Map submodule path to submodule name
184 -#
185 -# $1 = path
186 -#
187 -module_name()
188 -{
189 - # Do we have "submodule.<something>.path = $1" defined in .gitmodules file?
190 - sm_path="$1"
191 - re=$(printf '%s\n' "$1" | sed -e 's/[].[^$\\*]/\\&/g')
192 - name=$( git config -f .gitmodules --get-regexp '^submodule\..*\.path$' |
193 - sed -n -e 's|^submodule\.\(.*\)\.path '"$re"'$|\1|p' )
194 - test -z "$name" &&
195 - die "$(eval_gettext "No submodule mapping found in .gitmodules for path '\$sm_path'")"
196 - printf '%s\n' "$name"
197 -}
198 -
181 #
182 # Clone a submodule
183 #
@@ -498,7 +480,7 @@ cmd_foreach()
480 then
481 displaypath=$(relative_path "$sm_path")
482 say "$(eval_gettext "Entering '\$prefix\$displaypath'")"
501 - name=$(module_name "$sm_path")
483 + name=$(git submodule--helper name "$sm_path")
484 (
485 prefix="$prefix$sm_path/"
486 clear_local_git_env
@@ -554,7 +536,7 @@ cmd_init()
536 while read mode sha1 stage sm_path
537 do
538 die_if_unmatched "$mode"
557 - name=$(module_name "$sm_path") || exit
539 + name=$(git submodule--helper name "$sm_path") || exit
540
541 displaypath=$(relative_path "$sm_path")
542
@@ -636,7 +618,7 @@ cmd_deinit()
618 while read mode sha1 stage sm_path
619 do
620 die_if_unmatched "$mode"
639 - name=$(module_name "$sm_path") || exit
621 + name=$(git submodule--helper name "$sm_path") || exit
622
623 displaypath=$(relative_path "$sm_path")
624
@@ -758,7 +740,7 @@ cmd_update()
740 echo >&2 "Skipping unmerged submodule $prefix$sm_path"
741 continue
742 fi
761 - name=$(module_name "$sm_path") || exit
743 + name=$(git submodule--helper name "$sm_path") || exit
744 url=$(git config submodule."$name".url)
745 branch=$(get_submodule_config "$name" branch master)
746 if ! test -z "$update"
@@ -1022,7 +1004,7 @@ cmd_summary() {
1004 # Respect the ignore setting for --for-status.
1005 if test -n "$for_status"
1006 then
1025 - name=$(module_name "$sm_path")
1007 + name=$(git submodule--helper name "$sm_path")
1008 ignore_config=$(get_submodule_config "$name" ignore none)
1009 test $status != A && test $ignore_config = all && continue
1010 fi
@@ -1184,7 +1166,7 @@ cmd_status()
1166 while read mode sha1 stage sm_path
1167 do
1168 die_if_unmatched "$mode"
1187 - name=$(module_name "$sm_path") || exit
1169 + name=$(git submodule--helper name "$sm_path") || exit
1170 url=$(git config submodule."$name".url)
1171 displaypath=$(relative_path "$prefix$sm_path")
1172 if test "$stage" = U
@@ -1261,7 +1243,7 @@ cmd_sync()
1243 while read mode sha1 stage sm_path
1244 do
1245 die_if_unmatched "$mode"
1264 - name=$(module_name "$sm_path")
1246 + name=$(git submodule--helper name "$sm_path")
1247 url=$(git config -f .gitmodules --get submodule."$name".url)
1248
1249 # Possibly a url relative to parent