Skip to content

Commit ec160ae

Browse files
committed
update-index: teach --cacheinfo a new syntax "mode,sha1,path"
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 <[email protected]>
1 parent e703d71 commit ec160ae

File tree

3 files changed

+50
-5
lines changed

3 files changed

+50
-5
lines changed

Documentation/git-update-index.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ SYNOPSIS
1212
'git update-index'
1313
[--add] [--remove | --force-remove] [--replace]
1414
[--refresh] [-q] [--unmerged] [--ignore-missing]
15-
[(--cacheinfo <mode> <object> <file>)...]
15+
[(--cacheinfo <mode>,<object>,<file>)...]
1616
[--chmod=(+|-)x]
1717
[--[no-]assume-unchanged]
1818
[--[no-]skip-worktree]
@@ -68,8 +68,12 @@ OPTIONS
6868
--ignore-missing::
6969
Ignores missing files during a --refresh
7070

71+
--cacheinfo <mode>,<object>,<path>::
7172
--cacheinfo <mode> <object> <path>::
72-
Directly insert the specified info into the index.
73+
Directly insert the specified info into the index. For
74+
backward compatibility, you can also give these three
75+
arguments as three separate parameters, but new users are
76+
encouraged to use a single-parameter form.
7377

7478
--index-info::
7579
Read index information from stdin.

builtin/update-index.c

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -629,14 +629,42 @@ static int resolve_undo_clear_callback(const struct option *opt,
629629
return 0;
630630
}
631631

632+
static int parse_new_style_cacheinfo(const char *arg,
633+
unsigned int *mode,
634+
unsigned char sha1[],
635+
const char **path)
636+
{
637+
unsigned long ul;
638+
char *endp;
639+
640+
errno = 0;
641+
ul = strtoul(arg, &endp, 8);
642+
if (errno || endp == arg || *endp != ',' || (unsigned int) ul != ul)
643+
return -1; /* not a new-style cacheinfo */
644+
*mode = ul;
645+
endp++;
646+
if (get_sha1_hex(endp, sha1) || endp[40] != ',')
647+
return -1;
648+
*path = endp + 41;
649+
return 0;
650+
}
651+
632652
static int cacheinfo_callback(struct parse_opt_ctx_t *ctx,
633653
const struct option *opt, int unset)
634654
{
635655
unsigned char sha1[20];
636656
unsigned int mode;
657+
const char *path;
637658

659+
if (!parse_new_style_cacheinfo(ctx->argv[1], &mode, sha1, &path)) {
660+
if (add_cacheinfo(mode, sha1, path, 0))
661+
die("git update-index: --cacheinfo cannot add %s", path);
662+
ctx->argv++;
663+
ctx->argc--;
664+
return 0;
665+
}
638666
if (ctx->argc <= 3)
639-
return error("option 'cacheinfo' expects three arguments");
667+
return error("option 'cacheinfo' expects <mode>,<sha1>,<path>");
640668
if (strtoul_ui(*++ctx->argv, 8, &mode) ||
641669
get_sha1_hex(*++ctx->argv, sha1) ||
642670
add_cacheinfo(mode, sha1, *++ctx->argv, 0))
@@ -740,9 +768,9 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
740768
PARSE_OPT_NOARG | PARSE_OPT_NONEG,
741769
really_refresh_callback},
742770
{OPTION_LOWLEVEL_CALLBACK, 0, "cacheinfo", NULL,
743-
N_("<mode> <object> <path>"),
771+
N_("<mode>,<object>,<path>"),
744772
N_("add the specified entry to the index"),
745-
PARSE_OPT_NOARG | /* disallow --cacheinfo=<mode> form */
773+
PARSE_OPT_NOARG | /* disallow --cacheinfo=<mode> form */
746774
PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP,
747775
(parse_opt_cb *) cacheinfo_callback},
748776
{OPTION_CALLBACK, 0, "chmod", &set_executable_bit, N_("(+/-)x"),

t/t2107-update-index-basic.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,17 @@ test_expect_success '--cacheinfo does not accept gitlink null sha1' '
4848
test_cmp expect actual
4949
'
5050

51+
test_expect_success '--cacheinfo mode,sha1,path (new syntax)' '
52+
echo content >file &&
53+
git hash-object -w --stdin <file >expect &&
54+
55+
git update-index --add --cacheinfo 100644 "$(cat expect)" file &&
56+
git rev-parse :file >actual &&
57+
test_cmp expect actual &&
58+
59+
git update-index --add --cacheinfo "100644,$(cat expect),elif" &&
60+
git rev-parse :elif >actual &&
61+
test_cmp expect actual
62+
'
63+
5164
test_done

0 commit comments

Comments
 (0)