Skip to content

Commit

Permalink
update-index: teach --cacheinfo a new syntax "mode,sha1,path"
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Junio C Hamano committed Mar 24, 2014
1 parent e703d71 commit ec160ae
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 5 deletions.
8 changes: 6 additions & 2 deletions Documentation/git-update-index.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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.
Expand Down
34 changes: 31 additions & 3 deletions builtin/update-index.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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"),
Expand Down
13 changes: 13 additions & 0 deletions t/t2107-update-index-basic.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit ec160ae

Please sign in to comment.