[PATCH v3 11/12] fast-import: use parse_options() for command line options

Christian Couder <[email protected]>
Newsgroups org.kernel.vger.git
Message-ID <[email protected]>
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 9c8398f0c9 (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 <[email protected]>
---
 Documentation/git-fast-import.adoc |  7 +++++
 builtin/fast-import.c              | 43 ++++++++++--------------------
 t/t9300-fast-import.sh             |  7 +++++
 3 files changed, 28 insertions(+), 29 deletions(-)

diff --git a/Documentation/git-fast-import.adoc b/Documentation/git-fast-import.adoc
index 7c5900e048..fd165e11d2 100644
--- a/Documentation/git-fast-import.adoc
+++ b/Documentation/git-fast-import.adoc
@@ -65,6 +65,13 @@ Only enable this option if you trust the program generating the
 fast-import stream! This option is enabled automatically for
 remote-helpers that use the `import` capability, as they are
 already trusted to run their own code.
++
+Note that this option has to be spelled in full, and has to appear
+before any option whose value is separated from it by a space, for
+the unsafe `feature` commands in the stream to be allowed. So
+`--allow-unsafe` or `--depth 5 --allow-unsafe-features` still refuse
+them, while `--allow-unsafe-features --depth 5` and
+`--depth=5 --allow-unsafe-features` allow them.
 
 `--signed-tags=<mode>`::
 	Specify how to handle signed tags. Behaves in the same way as
diff --git a/builtin/fast-import.c b/builtin/fast-import.c
index 40cc9c4a23..dd873ec433 100644
--- a/builtin/fast-import.c
+++ b/builtin/fast-import.c
@@ -3975,31 +3975,11 @@ static const char *const fast_import_usage[] = {
 
 static void parse_argv(struct fast_import_state *state)
 {
-	unsigned int i;
-
-	for (i = 1; i < state->argc; i++) {
-		const char *a = state->argv[i];
-
-		if (*a != '-' || !strcmp(a, "--"))
-			break;
-
-		if (!skip_prefix(a, "--", &a))
-			die(_("unknown option %s"), a);
-
-		if (parse_one_option(state, a))
-			continue;
-
-		if (parse_one_feature(state, a, 0))
-			continue;
-
-		if (skip_prefix(a, "cat-blob-fd=", &a)) {
-			option_cat_blob_fd(state, a);
-			continue;
-		}
+	int argc = parse_options(state->argc, state->argv, state->prefix,
+				 state->option, fast_import_usage,
+				 PARSE_OPT_KEEP_ARGV0);
 
-		die(_("unknown option --%s"), a);
-	}
-	if (i != state->argc)
+	if (argc > 1)
 		usage_with_options(fast_import_usage, state->option);
 
 	state->seen_data_command = 1;
@@ -4135,11 +4115,6 @@ int cmd_fast_import(int argc,
 {
 	struct fast_import_state state;
 
-	/*
-	 * NEEDSWORK: For now this is used only to render
-	 * `-h`/`--help-all` usage messages. The actual parsing is
-	 * done by parse_one_option()/parse_one_feature().
-	 */
 	struct option fast_import_options[] = {
 		OPT_GROUP(N_("Common")),
 		OPT_CALLBACK_F(0, "date-format", NULL, N_("fmt"),
@@ -4230,6 +4205,16 @@ int cmd_fast_import(int argc,
 	 * "feature" lines at the start of the stream (which allows the command
 	 * line to override stream data). But we must do an early parse of any
 	 * command-line options that impact how we interpret the feature lines.
+	 *
+	 * NEEDSWORK: This scan only matches the exact "--allow-unsafe-features"
+	 * spelling and stops at the first argument that doesn't start with a
+	 * dash. As parse_options() below also accepts unambiguous abbreviations
+	 * and values separated by a space from their option, the two disagree
+	 * for command lines like "--allow-unsafe" or "--depth 5
+	 * --allow-unsafe-features": parse_options() accepts the option, but
+	 * this scan doesn't see it, so unsafe features from the stream are
+	 * still refused. This errs on the safe side, but should be fixed by
+	 * teaching this scan about the options that take a value.
 	 */
 	for (int i = 1; i < argc; i++) {
 		const char *arg = argv[i];
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index fe6c2617ac..d9de2ef0d8 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -2827,6 +2827,13 @@ test_expect_success 'R: unknown commandline options are rejected' '\
 	test_must_fail git fast-import --non-existing-option < /dev/null
 '
 
+test_expect_success 'R: feature-only names are rejected on the command line' '
+	for opt in --alias --get-mark --ls --notes
+	do
+		test_must_fail git fast-import "$opt" </dev/null || return 1
+	done
+'
+
 test_expect_success 'R: die on invalid option argument' '
 	echo "option git active-branches=-5" |
 	test_must_fail git fast-import &&
-- 
2.55.0.530.gdb3615d990.dirty
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.