Merge branch 'jc/rev-parse-argh-dashed-multi-words'

Make sure that the help text given to describe the "<param>" part
of the "git cmd --option=<param>" does not contain SP or _,
e.g. "--gpg-sign=<key-id>" option for "git commit" is not spelled
as "--gpg-sign=<key id>".

* jc/rev-parse-argh-dashed-multi-words:
  parse-options: make sure argh string does not have SP or _
  update-index: teach --cacheinfo a new syntax "mode,sha1,path"
  parse-options: multi-word argh should use dash to separate words
This commit is contained in:
Junio C Hamano 2014-04-08 11:59:27 -07:00
commit b5a52fa6c6
17 changed files with 77 additions and 29 deletions

View file

@ -9,7 +9,7 @@ SYNOPSIS
-------- --------
[verse] [verse]
'git cherry-pick' [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] 'git cherry-pick' [--edit] [-n] [-m parent-number] [-s] [-x] [--ff]
[-S[<keyid>]] <commit>... [-S[<key-id>]] <commit>...
'git cherry-pick' --continue 'git cherry-pick' --continue
'git cherry-pick' --quit 'git cherry-pick' --quit
'git cherry-pick' --abort 'git cherry-pick' --abort
@ -101,8 +101,8 @@ effect to your index in a row.
--signoff:: --signoff::
Add Signed-off-by line at the end of the commit message. Add Signed-off-by line at the end of the commit message.
-S[<keyid>]:: -S[<key-id>]::
--gpg-sign[=<keyid>]:: --gpg-sign[=<key-id>]::
GPG-sign commits. GPG-sign commits.
--ff:: --ff::

View file

@ -13,7 +13,7 @@ SYNOPSIS
[-F <file> | -m <msg>] [--reset-author] [--allow-empty] [-F <file> | -m <msg>] [--reset-author] [--allow-empty]
[--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--allow-empty-message] [--no-verify] [-e] [--author=<author>]
[--date=<date>] [--cleanup=<mode>] [--[no-]status] [--date=<date>] [--cleanup=<mode>] [--[no-]status]
[-i | -o] [-S[<keyid>]] [--] [<file>...] [-i | -o] [-S[<key-id>]] [--] [<file>...]
DESCRIPTION DESCRIPTION
----------- -----------

View file

@ -10,7 +10,7 @@ SYNOPSIS
-------- --------
[verse] [verse]
'git merge' [-n] [--stat] [--no-commit] [--squash] [--[no-]edit] 'git merge' [-n] [--stat] [--no-commit] [--squash] [--[no-]edit]
[-s <strategy>] [-X <strategy-option>] [-S[<keyid>]] [-s <strategy>] [-X <strategy-option>] [-S[<key-id>]]
[--[no-]rerere-autoupdate] [-m <msg>] [<commit>...] [--[no-]rerere-autoupdate] [-m <msg>] [<commit>...]
'git merge' <msg> HEAD <commit>... 'git merge' <msg> HEAD <commit>...
'git merge' --abort 'git merge' --abort

View file

@ -14,7 +14,7 @@ SYNOPSIS
'git notes' append [-F <file> | -m <msg> | (-c | -C) <object>] [<object>] 'git notes' append [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
'git notes' edit [<object>] 'git notes' edit [<object>]
'git notes' show [<object>] 'git notes' show [<object>]
'git notes' merge [-v | -q] [-s <strategy> ] <notes_ref> 'git notes' merge [-v | -q] [-s <strategy> ] <notes-ref>
'git notes' merge --commit [-v | -q] 'git notes' merge --commit [-v | -q]
'git notes' merge --abort [-v | -q] 'git notes' merge --abort [-v | -q]
'git notes' remove [--ignore-missing] [--stdin] [<object>...] 'git notes' remove [--ignore-missing] [--stdin] [<object>...]

View file

@ -290,14 +290,14 @@ The lines after the separator describe the options.
Each line of options has this format: Each line of options has this format:
------------ ------------
<opt_spec><flags>*<arg_hint>? SP+ help LF <opt-spec><flags>*<arg-hint>? SP+ help LF
------------ ------------
`<opt_spec>`:: `<opt-spec>`::
its format is the short option character, then the long option name its format is the short option character, then the long option name
separated by a comma. Both parts are not required, though at least one separated by a comma. Both parts are not required, though at least one
is necessary. `h,help`, `dry-run` and `f` are all three correct is necessary. `h,help`, `dry-run` and `f` are all three correct
`<opt_spec>`. `<opt-spec>`.
`<flags>`:: `<flags>`::
`<flags>` are of `*`, `=`, `?` or `!`. `<flags>` are of `*`, `=`, `?` or `!`.
@ -313,11 +313,11 @@ Each line of options has this format:
* Use `!` to not make the corresponding negated long option available. * Use `!` to not make the corresponding negated long option available.
`<arg_hint>`:: `<arg-hint>`::
`<arg_hint>`, if specified, is used as a name of the argument in the `<arg-hint>`, if specified, is used as a name of the argument in the
help output, for options that take arguments. `<arg_hint>` is help output, for options that take arguments. `<arg-hint>` is
terminated by the first whitespace. When you need to use space in the terminated by the first whitespace. It is customary to use a
argument hint use dash instead. dash to separate words in a multi-word argument hint.
The remainder of the line, after stripping the spaces, is used The remainder of the line, after stripping the spaces, is used
as the help associated to the option. as the help associated to the option.

View file

@ -8,7 +8,7 @@ git-revert - Revert some existing commits
SYNOPSIS SYNOPSIS
-------- --------
[verse] [verse]
'git revert' [--[no-]edit] [-n] [-m parent-number] [-s] [-S[<keyid>]] <commit>... 'git revert' [--[no-]edit] [-n] [-m parent-number] [-s] [-S[<key-id>]] <commit>...
'git revert' --continue 'git revert' --continue
'git revert' --quit 'git revert' --quit
'git revert' --abort 'git revert' --abort
@ -80,8 +80,8 @@ more details.
This is useful when reverting more than one commits' This is useful when reverting more than one commits'
effect to your index in a row. effect to your index in a row.
-S[<keyid>]:: -S[<key-id>]::
--gpg-sign[=<keyid>]:: --gpg-sign[=<key-id>]::
GPG-sign commits. GPG-sign commits.
-s:: -s::

View file

@ -12,7 +12,7 @@ SYNOPSIS
'git update-index' 'git update-index'
[--add] [--remove | --force-remove] [--replace] [--add] [--remove | --force-remove] [--replace]
[--refresh] [-q] [--unmerged] [--ignore-missing] [--refresh] [-q] [--unmerged] [--ignore-missing]
[(--cacheinfo <mode> <object> <file>)...] [(--cacheinfo <mode>,<object>,<file>)...]
[--chmod=(+|-)x] [--chmod=(+|-)x]
[--[no-]assume-unchanged] [--[no-]assume-unchanged]
[--[no-]skip-worktree] [--[no-]skip-worktree]
@ -68,8 +68,12 @@ OPTIONS
--ignore-missing:: --ignore-missing::
Ignores missing files during a --refresh Ignores missing files during a --refresh
--cacheinfo <mode>,<object>,<path>::
--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:: --index-info::
Read index information from stdin. Read index information from stdin.

View file

@ -1095,7 +1095,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
OPT_BOOL(0, "detach", &opts.force_detach, N_("detach the HEAD at named commit")), OPT_BOOL(0, "detach", &opts.force_detach, N_("detach the HEAD at named commit")),
OPT_SET_INT('t', "track", &opts.track, N_("set upstream info for new branch"), OPT_SET_INT('t', "track", &opts.track, N_("set upstream info for new branch"),
BRANCH_TRACK_EXPLICIT), BRANCH_TRACK_EXPLICIT),
OPT_STRING(0, "orphan", &opts.new_orphan_branch, N_("new branch"), N_("new unparented branch")), OPT_STRING(0, "orphan", &opts.new_orphan_branch, N_("new-branch"), N_("new unparented branch")),
OPT_SET_INT('2', "ours", &opts.writeout_stage, N_("checkout our version for unmerged files"), OPT_SET_INT('2', "ours", &opts.writeout_stage, N_("checkout our version for unmerged files"),
2), 2),
OPT_SET_INT('3', "theirs", &opts.writeout_stage, N_("checkout their version for unmerged files"), OPT_SET_INT('3', "theirs", &opts.writeout_stage, N_("checkout their version for unmerged files"),

View file

@ -1501,7 +1501,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
OPT_BOOL('e', "edit", &edit_flag, N_("force edit of commit")), OPT_BOOL('e', "edit", &edit_flag, N_("force edit of commit")),
OPT_STRING(0, "cleanup", &cleanup_arg, N_("default"), N_("how to strip spaces and #comments from message")), OPT_STRING(0, "cleanup", &cleanup_arg, N_("default"), N_("how to strip spaces and #comments from message")),
OPT_BOOL(0, "status", &include_status, N_("include status in commit message template")), OPT_BOOL(0, "status", &include_status, N_("include status in commit message template")),
{ OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key id"), { OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key-id"),
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" }, N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
/* end commit message options */ /* end commit message options */

View file

@ -220,7 +220,7 @@ static struct option builtin_merge_options[] = {
OPT_BOOL(0, "abort", &abort_current_merge, OPT_BOOL(0, "abort", &abort_current_merge,
N_("abort the current in-progress merge")), N_("abort the current in-progress merge")),
OPT_SET_INT(0, "progress", &show_progress, N_("force progress reporting"), 1), OPT_SET_INT(0, "progress", &show_progress, N_("force progress reporting"), 1),
{ OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key id"), { OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key-id"),
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" }, N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
OPT_BOOL(0, "overwrite-ignore", &overwrite_ignore, N_("update ignored files (default)")), OPT_BOOL(0, "overwrite-ignore", &overwrite_ignore, N_("update ignored files (default)")),
OPT_END() OPT_END()

View file

@ -939,7 +939,7 @@ int cmd_notes(int argc, const char **argv, const char *prefix)
int result; int result;
const char *override_notes_ref = NULL; const char *override_notes_ref = NULL;
struct option options[] = { struct option options[] = {
OPT_STRING(0, "ref", &override_notes_ref, N_("notes_ref"), OPT_STRING(0, "ref", &override_notes_ref, N_("notes-ref"),
N_("use notes from <notes_ref>")), N_("use notes from <notes_ref>")),
OPT_END() OPT_END()
}; };

View file

@ -89,7 +89,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
OPT_STRING(0, "strategy", &opts->strategy, N_("strategy"), N_("merge strategy")), OPT_STRING(0, "strategy", &opts->strategy, N_("strategy"), N_("merge strategy")),
OPT_CALLBACK('X', "strategy-option", &opts, N_("option"), OPT_CALLBACK('X', "strategy-option", &opts, N_("option"),
N_("option for merge strategy"), option_parse_x), N_("option for merge strategy"), option_parse_x),
{ OPTION_STRING, 'S', "gpg-sign", &opts->gpg_sign, N_("key id"), { OPTION_STRING, 'S', "gpg-sign", &opts->gpg_sign, N_("key-id"),
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" }, N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
OPT_END(), OPT_END(),
OPT_END(), OPT_END(),

View file

@ -513,7 +513,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
OPT_BOOL('s', "sign", &opt.sign, N_("annotated and GPG-signed tag")), OPT_BOOL('s', "sign", &opt.sign, N_("annotated and GPG-signed tag")),
OPT_STRING(0, "cleanup", &cleanup_arg, N_("mode"), OPT_STRING(0, "cleanup", &cleanup_arg, N_("mode"),
N_("how to strip spaces and #comments from message")), N_("how to strip spaces and #comments from message")),
OPT_STRING('u', "local-user", &keyid, N_("key id"), OPT_STRING('u', "local-user", &keyid, N_("key-id"),
N_("use another key to sign the tag")), N_("use another key to sign the tag")),
OPT__FORCE(&force, N_("replace the tag if exists")), OPT__FORCE(&force, N_("replace the tag if exists")),
OPT_COLUMN(0, "column", &colopts, N_("show tag list in columns")), OPT_COLUMN(0, "column", &colopts, N_("show tag list in columns")),

View file

@ -629,14 +629,42 @@ static int resolve_undo_clear_callback(const struct option *opt,
return 0; 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, static int cacheinfo_callback(struct parse_opt_ctx_t *ctx,
const struct option *opt, int unset) const struct option *opt, int unset)
{ {
unsigned char sha1[20]; unsigned char sha1[20];
unsigned int mode; 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) 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) || if (strtoul_ui(*++ctx->argv, 8, &mode) ||
get_sha1_hex(*++ctx->argv, sha1) || get_sha1_hex(*++ctx->argv, sha1) ||
add_cacheinfo(mode, sha1, *++ctx->argv, 0)) 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, PARSE_OPT_NOARG | PARSE_OPT_NONEG,
really_refresh_callback}, really_refresh_callback},
{OPTION_LOWLEVEL_CALLBACK, 0, "cacheinfo", NULL, {OPTION_LOWLEVEL_CALLBACK, 0, "cacheinfo", NULL,
N_("<mode> <object> <path>"), N_("<mode>,<object>,<path>"),
N_("add the specified entry to the index"), 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_NONEG | PARSE_OPT_LITERAL_ARGHELP,
(parse_opt_cb *) cacheinfo_callback}, (parse_opt_cb *) cacheinfo_callback},
{OPTION_CALLBACK, 0, "chmod", &set_executable_bit, N_("(+/-)x"), {OPTION_CALLBACK, 0, "chmod", &set_executable_bit, N_("(+/-)x"),

View file

@ -375,6 +375,9 @@ static void parse_options_check(const struct option *opts)
default: default:
; /* ok. (usually accepts an argument) */ ; /* ok. (usually accepts an argument) */
} }
if (opts->argh &&
strcspn(opts->argh, " _") != strlen(opts->argh))
err |= optbug(opts, "multi-word argh should use dash to separate words");
} }
if (err) if (err)
exit(128); exit(128);

View file

@ -143,7 +143,7 @@ struct option {
{ OPTION_CALLBACK, (s), (l), (v), N_("time"),(h), 0, \ { OPTION_CALLBACK, (s), (l), (v), N_("time"),(h), 0, \
parse_opt_approxidate_cb } parse_opt_approxidate_cb }
#define OPT_EXPIRY_DATE(s, l, v, h) \ #define OPT_EXPIRY_DATE(s, l, v, h) \
{ OPTION_CALLBACK, (s), (l), (v), N_("expiry date"),(h), 0, \ { OPTION_CALLBACK, (s), (l), (v), N_("expiry-date"),(h), 0, \
parse_opt_expiry_date_cb } parse_opt_expiry_date_cb }
#define OPT_CALLBACK(s, l, v, a, h, f) \ #define OPT_CALLBACK(s, l, v, a, h, f) \
{ OPTION_CALLBACK, (s), (l), (v), (a), (h), 0, (f) } { OPTION_CALLBACK, (s), (l), (v), (a), (h), 0, (f) }

View file

@ -48,4 +48,17 @@ test_expect_success '--cacheinfo does not accept gitlink null sha1' '
test_cmp expect actual 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 test_done