git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] submodule operations: tighten pathspec errors

From
Stefan Beller <sbeller@google.com>
Date
May 21, 2016, 01:21 UTC
Message-ID
<1463793689-19496-1-git-send-email-sbeller@google.com>

when the pathspec did not match any path, error out. Add the `--error-unmatch` switch to use the old behavior.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
This was taken from the Left Over Bits:
   git submodule $cmd $pathspec may want to error out when the $pathspec does
   not match any submodules. There must be an --unmatch-ok option to override
   this safety, though. Cf. $gmane/289535
   
It's a first initial version with no tests (and probably conflicting with
some topics in flight), but I was curious how involved this issue actually is,
so I took a stab at implementing it.

I was debating if inside git-submodules.sh we want to pass around a variable or instead export an environment variable GIT_SUBMODULE_UNMATCH, such that we do not give it as an argument to the submodule--helper builtin.

(This version is developed on top of the sb/submodule-deinit-all)
   
 Documentation/git-submodule.txt | 15 ++++++++++-----
 builtin/submodule--helper.c     | 19 +++++++++++--------
 git-submodule.sh                | 41 ++++++++++++++++++++++++++++++-----------
 3 files changed, 51 insertions(+), 24 deletions(-)
diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index ad85183..ceacc02 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -11,16 +11,16 @@ SYNOPSIS
 [verse]
 'git submodule' [--quiet] add [-b <branch>] [-f|--force] [--name <name>]
 	      [--reference <repository>] [--depth <depth>] [--] <repository> [<path>]
-'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...]
-'git submodule' [--quiet] init [--] [<path>...]
-'git submodule' [--quiet] deinit [-f|--force] (--all|[--] <path>...)
-'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch]
+'git submodule' [--quiet] status [--error-unmatch] [--cached] [--recursive] [--] [<path>...]
+'git submodule' [--quiet] init [--error-unmatch] [--] [<path>...]
+'git submodule' [--quiet] deinit [--error-unmatch] [-f|--force] (--all|[--] <path>...)
+'git submodule' [--quiet] update [--error-unmatch] [--init] [--remote] [-N|--no-fetch]
 	      [-f|--force] [--rebase|--merge] [--reference <repository>]
 	      [--depth <depth>] [--recursive] [--] [<path>...]
 'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>]
 	      [commit] [--] [<path>...]
 'git submodule' [--quiet] foreach [--recursive] <command>
-'git submodule' [--quiet] sync [--recursive] [--] [<path>...]
+'git submodule' [--quiet] sync [--error-unmatch] [--recursive] [--] [<path>...]
 
 
 DESCRIPTION
@@ -260,6 +260,11 @@ OPTIONS
 	The name of the branch is recorded as `submodule.<name>.branch` in
 	`.gitmodules` for `update --remote`.
 
+--error-unmatch::
+	If the pathspec included a specification that did not match,
+	the usual operation is to error out. This switch suppresses
+	error reporting and continues the operation.
+
 -f::
 --force::
 	This option is only valid for add, deinit and update commands.
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 5295b72..91c49ec 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -19,7 +19,8 @@ struct module_list {
 static int module_list_compute(int argc, const char **argv,
 			       const char *prefix,
 			       struct pathspec *pathspec,
-			       struct module_list *list)
+			       struct module_list *list,
+			       int unmatch)
 {
 	int i, result = 0;
 	char *ps_matched = NULL;
@@ -36,10 +37,9 @@ static int module_list_compute(int argc, const char **argv,
 
 	for (i = 0; i < active_nr; i++) {
 		const struct cache_entry *ce = active_cache[i];
-
-		if (!match_pathspec(pathspec, ce->name, ce_namelen(ce),
-				    0, ps_matched, 1) ||
-		    !S_ISGITLINK(ce->ce_mode))
+		if (!S_ISGITLINK(ce->ce_mode) ||
+		    !match_pathspec(pathspec, ce->name, ce_namelen(ce),
+				    0, ps_matched, 1))
 			continue;
 
 		ALLOC_GROW(list->entries, list->nr + 1, list->alloc);
@@ -53,7 +53,9 @@ static int module_list_compute(int argc, const char **argv,
 			i++;
 	}
 
-	if (ps_matched && report_path_error(ps_matched, pathspec, prefix))
+	if (!unmatch &&
+	    ps_matched &&
+	    report_path_error(ps_matched, pathspec, prefix))
 		result = -1;
 
 	free(ps_matched);
@@ -63,11 +65,12 @@ static int module_list_compute(int argc, const char **argv,
 
 static int module_list(int argc, const char **argv, const char *prefix)
 {
-	int i;
+	int i, unmatch = 0;
 	struct pathspec pathspec;
 	struct module_list list = MODULE_LIST_INIT;
 
 	struct option module_list_options[] = {
+		OPT_BOOL(0, "unmatch", &unmatch, N_("Do not report error if no matches are found")),
 		OPT_STRING(0, "prefix", &prefix,
 			   N_("path"),
 			   N_("alternative anchor for relative paths")),
@@ -82,7 +85,7 @@ static int module_list(int argc, const char **argv, const char *prefix)
 	argc = parse_options(argc, argv, prefix, module_list_options,
 			     git_submodule_helper_usage, 0);
 
-	if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0) {
+	if (module_list_compute(argc, argv, prefix, &pathspec, &list, unmatch) < 0) {
 		printf("#unmatched\n");
 		return 1;
 	}
diff --git a/git-submodule.sh b/git-submodule.sh
index fb68f1f..f10e10a 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -6,13 +6,13 @@
 
 dashless=$(basename "$0" | sed -e 's/-/ /')
 USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>]
-   or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
-   or: $dashless [--quiet] init [--] [<path>...]
-   or: $dashless [--quiet] deinit [-f|--force] (--all| [--] <path>...)
-   or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--reference <repository>] [--recursive] [--] [<path>...]
+   or: $dashless [--quiet] status [--error-unmatch] [--cached] [--recursive] [--] [<path>...]
+   or: $dashless [--quiet] init [--error-unmatch] [--] [<path>...]
+   or: $dashless [--quiet] deinit [--error-unmatch] [-f|--force] (--all| [--] <path>...)
+   or: $dashless [--quiet] update [--error-unmatch] [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--reference <repository>] [--recursive] [--] [<path>...]
    or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
    or: $dashless [--quiet] foreach [--recursive] <command>
-   or: $dashless [--quiet] sync [--recursive] [--] [<path>...]"
+   or: $dashless [--quiet] sync [--error-unmatch] [--recursive] [--] [<path>...]"
 OPTIONS_SPEC=
 SUBDIRECTORY_OK=Yes
 . git-sh-setup
@@ -391,6 +391,9 @@ cmd_foreach()
 		--recursive)
 			recursive=1
 			;;
+		--error-unmatch)
+			unmatch=1
+			;;
 		-*)
 			usage
 			;;
@@ -407,7 +410,7 @@ cmd_foreach()
 	# command in the subshell (and a recursive call to this function)
 	exec 3<&0
 
-	git submodule--helper list --prefix "$wt_prefix"|
+	git submodule--helper list ${unmatch:+--unmatch} --prefix "$wt_prefix"|
 	while read mode sha1 stage sm_path
 	do
 		die_if_unmatched "$mode"
@@ -453,6 +456,9 @@ cmd_init()
 		-q|--quiet)
 			GIT_QUIET=1
 			;;
+		--error-unmatch)
+			unmatch=1
+			;;
 		--)
 			shift
 			break
@@ -467,7 +473,7 @@ cmd_init()
 		shift
 	done
 
-	git submodule--helper list --prefix "$wt_prefix" "$@" |
+	git submodule--helper list ${unmatch:+--unmatch} --prefix "$wt_prefix" "$@" |
 	while read mode sha1 stage sm_path
 	do
 		die_if_unmatched "$mode"
@@ -534,6 +540,9 @@ cmd_deinit()
 		--all)
 			deinit_all=t
 			;;
+		--error-unmatch)
+			unmatch=1
+			;;
 		--)
 			shift
 			break
@@ -558,7 +567,7 @@ cmd_deinit()
 		die "$(eval_gettext "Use '--all' if you really want to deinitialize all submodules")"
 	fi
 
-	git submodule--helper list --prefix "$wt_prefix" "$@" |
+	git submodule--helper list ${unmatch:+--unmatch} --prefix "$wt_prefix" "$@" |
 	while read mode sha1 stage sm_path
 	do
 		die_if_unmatched "$mode"
@@ -661,6 +670,9 @@ cmd_update()
 		--recursive)
 			recursive=1
 			;;
+		--error-unmatch)
+			unmatch=1
+			;;
 		--checkout)
 			update="checkout"
 			;;
@@ -692,7 +704,7 @@ cmd_update()
 	fi
 
 	cloned_modules=
-	git submodule--helper list --prefix "$wt_prefix" "$@" | {
+	git submodule--helper list ${unmatch:+--unmatch} --prefix "$wt_prefix" "$@" | {
 	err=
 	while read mode sha1 stage sm_path
 	do
@@ -1115,6 +1127,9 @@ cmd_status()
 		--recursive)
 			recursive=1
 			;;
+		--error-unmatch)
+			unmatch=1
+			;;
 		--)
 			shift
 			break
@@ -1129,7 +1144,7 @@ cmd_status()
 		shift
 	done
 
-	git submodule--helper list --prefix "$wt_prefix" "$@" |
+	git submodule--helper list ${unmatch:+--unmatch} --prefix "$wt_prefix" "$@" |
 	while read mode sha1 stage sm_path
 	do
 		die_if_unmatched "$mode"
@@ -1193,6 +1208,10 @@ cmd_sync()
 			recursive=1
 			shift
 			;;
+		--error-unmatch)
+			unmatch=1
+			shift
+			;;
 		--)
 			shift
 			break
@@ -1206,7 +1225,7 @@ cmd_sync()
 		esac
 	done
 	cd_to_toplevel
-	git submodule--helper list --prefix "$wt_prefix" "$@" |
+	git submodule--helper list ${unmatch:+--unmatch} --prefix "$wt_prefix" "$@" |
 	while read mode sha1 stage sm_path
 	do
 		die_if_unmatched "$mode"
-- 
2.8.0.2.gaa9b48a.dirty
Next: Junio C Hamano
Message 1 of 6 in “submodule operations: tighten pathspec errors”
  1. submodule operations: tighten pathspec errorsStefan Beller, May 21, 2016
  2. Junio C HamanoMay 26, 2016
  3. Stefan BellerJun 1, 2016
  4. Junio C HamanoJun 1, 2016
  5. Junio C HamanoJun 1, 2016
  6. Stefan BellerJun 6, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.