Skip to content

Commit 95919e8

Browse files
committed
fast-import: use parse_options() for command line options
Previous commits have started to use the parse-options API to display output from `git fast-import -h` and `git fast-import --help-all` and to prepare for parsing the command line options using this API. Let's now actually use the API to parse command line options. This brings a number of changes that are mostly beneficial: - The `--alias`, `--get-mark`, `--cat-blob`, `--ls` and `--notes` options are no longer accepted on the command line. They were previously accepted as no-ops because parse_argv() fell through to parse_one_feature(). They are not documented in the OPTIONS section and are only meaningful as in-stream feature assertions, so accepting them on the command line was an accident of code sharing dating back to 9c8398f (fast-import: add option command, 2009-12-04). - Abbreviated options like `--dep=5` now work since parse_options() allows unambiguous prefixes. - As `--cat-blob` is an abbreviation of `--cat-blob-fd`, using the former on the command line will fail with "option `cat-blob-fd' requires a value" unlike the other four options that are not accepted anymore on the command line (see above). - Value-taking options now also accept the space-separated `--opt value` form, like `--depth 5`, in addition to the `--opt=value` form. - A bare or trailing `--` is now accepted and the stream is read normally, while it used to be a usage error. - The error messages for some options might differ a bit. - The code is shorter and more standard. Note that parse_one_feature() is now always called with its `from_stream` argument set to 1, but the code simplifications that can be made are left for a following clean-up commit. Signed-off-by: Christian Couder <christian.couder@gmail.com>
1 parent d109b8c commit 95919e8

3 files changed

Lines changed: 28 additions & 29 deletions

File tree

Documentation/git-fast-import.adoc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ Only enable this option if you trust the program generating the
6565
fast-import stream! This option is enabled automatically for
6666
remote-helpers that use the `import` capability, as they are
6767
already trusted to run their own code.
68+
+
69+
Note that this option has to be spelled in full, and has to appear
70+
before any option whose value is separated from it by a space, for
71+
the unsafe `feature` commands in the stream to be allowed. So
72+
`--allow-unsafe` or `--depth 5 --allow-unsafe-features` still refuse
73+
them, while `--allow-unsafe-features --depth 5` and
74+
`--depth=5 --allow-unsafe-features` allow them.
6875

6976
`--signed-tags=<mode>`::
7077
Specify how to handle signed tags. Behaves in the same way as

builtin/fast-import.c

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3975,31 +3975,11 @@ static const char *const fast_import_usage[] = {
39753975

39763976
static void parse_argv(struct fast_import_state *state)
39773977
{
3978-
unsigned int i;
3979-
3980-
for (i = 1; i < state->argc; i++) {
3981-
const char *a = state->argv[i];
3982-
3983-
if (*a != '-' || !strcmp(a, "--"))
3984-
break;
3985-
3986-
if (!skip_prefix(a, "--", &a))
3987-
die(_("unknown option %s"), a);
3988-
3989-
if (parse_one_option(state, a))
3990-
continue;
3991-
3992-
if (parse_one_feature(state, a, 0))
3993-
continue;
3994-
3995-
if (skip_prefix(a, "cat-blob-fd=", &a)) {
3996-
option_cat_blob_fd(state, a);
3997-
continue;
3998-
}
3978+
int argc = parse_options(state->argc, state->argv, state->prefix,
3979+
state->option, fast_import_usage,
3980+
PARSE_OPT_KEEP_ARGV0);
39993981

4000-
die(_("unknown option --%s"), a);
4001-
}
4002-
if (i != state->argc)
3982+
if (argc > 1)
40033983
usage_with_options(fast_import_usage, state->option);
40043984

40053985
state->seen_data_command = 1;
@@ -4135,11 +4115,6 @@ int cmd_fast_import(int argc,
41354115
{
41364116
struct fast_import_state state;
41374117

4138-
/*
4139-
* NEEDSWORK: For now this is used only to render
4140-
* `-h`/`--help-all` usage messages. The actual parsing is
4141-
* done by parse_one_option()/parse_one_feature().
4142-
*/
41434118
struct option fast_import_options[] = {
41444119
OPT_GROUP(N_("Common")),
41454120
OPT_CALLBACK_F(0, "date-format", NULL, N_("fmt"),
@@ -4230,6 +4205,16 @@ int cmd_fast_import(int argc,
42304205
* "feature" lines at the start of the stream (which allows the command
42314206
* line to override stream data). But we must do an early parse of any
42324207
* command-line options that impact how we interpret the feature lines.
4208+
*
4209+
* NEEDSWORK: This scan only matches the exact "--allow-unsafe-features"
4210+
* spelling and stops at the first argument that doesn't start with a
4211+
* dash. As parse_options() below also accepts unambiguous abbreviations
4212+
* and values separated by a space from their option, the two disagree
4213+
* for command lines like "--allow-unsafe" or "--depth 5
4214+
* --allow-unsafe-features": parse_options() accepts the option, but
4215+
* this scan doesn't see it, so unsafe features from the stream are
4216+
* still refused. This errs on the safe side, but should be fixed by
4217+
* teaching this scan about the options that take a value.
42334218
*/
42344219
for (int i = 1; i < argc; i++) {
42354220
const char *arg = argv[i];

t/t9300-fast-import.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2827,6 +2827,13 @@ test_expect_success 'R: unknown commandline options are rejected' '\
28272827
test_must_fail git fast-import --non-existing-option < /dev/null
28282828
'
28292829

2830+
test_expect_success 'R: feature-only names are rejected on the command line' '
2831+
for opt in --alias --get-mark --ls --notes
2832+
do
2833+
test_must_fail git fast-import "$opt" </dev/null || return 1
2834+
done
2835+
'
2836+
28302837
test_expect_success 'R: die on invalid option argument' '
28312838
echo "option git active-branches=-5" |
28322839
test_must_fail git fast-import &&

0 commit comments

Comments
 (0)