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

[PATCH 2/3] update-index: teach --cacheinfo a new syntax "mode,sha1,path"

From
Junio C Hamano <gitster@pobox.com>
Date
Mar 24, 2014, 17:52 UTC
Message-ID
<1395683525-2868-3-git-send-email-gitster@pobox.com>
In-Reply-To
<1395683525-2868-1-git-send-email-gitster@pobox.com>

The "--cacheinfo" option is unusual in that it takes three option parameters. An option with an optional parameter is bad enough. An option with multiple parameters is simply insane.

Introduce a new syntax that takes these three things concatenated together with a comma, which makes the command line syntax more uniform across subcommands, while retaining the traditional syntax for backward compatiblity.

If we were designing the "update-index" subcommand from scratch today, it may probably have made sense to make this option (and possibly others) a command mode option that does not take any option parameter (hence no need for arg-help). But we do not live in such an ideal world, and as far as I can tell, the command still supports (and must support) mixed command modes in a single invocation, e.g.

    $ git update-index path1 --add path2 \
        --cacheinfo 100644 $(git hash-object --stdin -w <path3) path3 \
	path4

must make sure path1 is already in the index and update all of these four paths. So this is probably as far as we can go to fix this issue without risking to break people's existing scripts.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/git-update-index.txt |  8 ++++++--
 builtin/update-index.c             | 34 +++++++++++++++++++++++++++++++---
 t/t2107-update-index-basic.sh      | 13 +++++++++++++
 3 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index e0a8702..d6de4a0 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -12,7 +12,7 @@ SYNOPSIS
 'git update-index'
 	     [--add] [--remove | --force-remove] [--replace]
 	     [--refresh] [-q] [--unmerged] [--ignore-missing]
-	     [(--cacheinfo <mode> <object> <file>)...]
+	     [(--cacheinfo <mode>,<object>,<file>)...]
 	     [--chmod=(+|-)x]
 	     [--[no-]assume-unchanged]
 	     [--[no-]skip-worktree]
@@ -68,8 +68,12 @@ OPTIONS
 --ignore-missing::
 	Ignores missing files during a --refresh
 
+--cacheinfo <mode>,<object>,<path>::
 --cacheinfo <mode> <object> <path>::
-	Directly insert the specified info into the index.
+	Directly insert the specified info into the index.  For
+	backward compatibility, you can also give these three
+	arguments as three separate parameters, but new users are
+	encouraged to use a single-parameter form.
 
 --index-info::
         Read index information from stdin.
diff --git a/builtin/update-index.c b/builtin/update-index.c
index d12ad95..ba54e19 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -629,14 +629,42 @@ static int resolve_undo_clear_callback(const struct option *opt,
 	return 0;
 }
 
+static int parse_new_style_cacheinfo(const char *arg,
+				     unsigned int *mode,
+				     unsigned char sha1[],
+				     const char **path)
+{
+	unsigned long ul;
+	char *endp;
+
+	errno = 0;
+	ul = strtoul(arg, &endp, 8);
+	if (errno || endp == arg || *endp != ',' || (unsigned int) ul != ul)
+		return -1; /* not a new-style cacheinfo */
+	*mode = ul;
+	endp++;
+	if (get_sha1_hex(endp, sha1) || endp[40] != ',')
+		return -1;
+	*path = endp + 41;
+	return 0;
+}
+
 static int cacheinfo_callback(struct parse_opt_ctx_t *ctx,
 				const struct option *opt, int unset)
 {
 	unsigned char sha1[20];
 	unsigned int mode;
+	const char *path;
 
+	if (!parse_new_style_cacheinfo(ctx->argv[1], &mode, sha1, &path)) {
+		if (add_cacheinfo(mode, sha1, path, 0))
+			die("git update-index: --cacheinfo cannot add %s", path);
+		ctx->argv++;
+		ctx->argc--;
+		return 0;
+	}
 	if (ctx->argc <= 3)
-		return error("option 'cacheinfo' expects three arguments");
+		return error("option 'cacheinfo' expects <mode>,<sha1>,<path>");
 	if (strtoul_ui(*++ctx->argv, 8, &mode) ||
 	    get_sha1_hex(*++ctx->argv, sha1) ||
 	    add_cacheinfo(mode, sha1, *++ctx->argv, 0))
@@ -740,9 +768,9 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
 			PARSE_OPT_NOARG | PARSE_OPT_NONEG,
 			really_refresh_callback},
 		{OPTION_LOWLEVEL_CALLBACK, 0, "cacheinfo", NULL,
-			N_("<mode> <object> <path>"),
+			N_("<mode>,<object>,<path>"),
 			N_("add the specified entry to the index"),
-			PARSE_OPT_NOARG |	/* disallow --cacheinfo=<mode> form */
+			PARSE_OPT_NOARG | /* disallow --cacheinfo=<mode> form */
 			PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP,
 			(parse_opt_cb *) cacheinfo_callback},
 		{OPTION_CALLBACK, 0, "chmod", &set_executable_bit, N_("(+/-)x"),
diff --git a/t/t2107-update-index-basic.sh b/t/t2107-update-index-basic.sh
index a6405d3..fe2fb17 100755
--- a/t/t2107-update-index-basic.sh
+++ b/t/t2107-update-index-basic.sh
@@ -48,4 +48,17 @@ test_expect_success '--cacheinfo does not accept gitlink null sha1' '
 	test_cmp expect actual
 '
 
+test_expect_success '--cacheinfo mode,sha1,path (new syntax)' '
+	echo content >file &&
+	git hash-object -w --stdin <file >expect &&
+
+	git update-index --add --cacheinfo 100644 "$(cat expect)" file &&
+	git rev-parse :file >actual &&
+	test_cmp expect actual &&
+
+	git update-index --add --cacheinfo "100644,$(cat expect),elif" &&
+	git rev-parse :elif >actual &&
+	test_cmp expect actual
+'
+
 test_done
-- 
1.9.1-471-gcccbd8b
Previous: Junio C HamanoNext: Junio C Hamano
Message 20 of 23 in “rev-parse --parseopt: option argument name hints”
  1. rev-parse --parseopt: option argument name hintsIlya Bobyr, Mar 3, 2014
  2. Junio C HamanoMar 4, 2014
  3. Ilya BobyrMar 10, 2014
  4. rev-parse --parseopt: option argument name hintsIlya Bobyr, Mar 10, 2014
  5. Junio C HamanoMar 10, 2014
  6. Junio C HamanoMar 11, 2014
  7. Ilya BobyrMar 12, 2014
  8. Junio C HamanoMar 12, 2014
  9. Ilya BobyrMar 19, 2014
  10. Junio C HamanoMar 19, 2014
  11. Ilya BobyrMar 20, 2014
  12. rev-parse --parseopt: option argument name hintsIlya Bobyr, Mar 20, 2014
  13. Junio C HamanoMar 20, 2014
  14. Ilya BobyrMar 20, 2014
  15. Ilya BobyrMar 21, 2014
  16. Junio C HamanoMar 21, 2014
  17. rev-parse --parseopt: option argument name hintsIlya Bobyr, Mar 22, 2014
  18. 0/3 Parse-options: spell multi-word placeholders with dashesJunio C Hamano, Mar 24, 2014
  19. 1/3 parse-options: multi-word argh should use dash to separate wordsJunio C Hamano, Mar 24, 2014
  20. 2/3 update-index: teach --cacheinfo a new syntax "mode,sha1,path"Junio C Hamano, Mar 24, 2014
  21. 3/3 parse-options: make sure argh string does not have SP or _Junio C Hamano, Mar 24, 2014
  22. Eric SunshineMar 20, 2014
  23. Ilya BobyrMar 21, 2014

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.