git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 3/3] parseopt: values of pathname type can be prefixed with :(optional)

From
Junio C Hamano <gitster@pobox.com>
Date
Oct 14, 2024, 20:44 UTC
Message-ID
<20241014204427.1712182-4-gitster@pobox.com>
In-Reply-To
<20241014204427.1712182-1-gitster@pobox.com>

In the previous step, we introduced an optional filename that can be given to a configuration variable, and nullify the fact that such a configuration setting even existed if the named path is missing or empty.

Let's do the same for command line options that name a pathname.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 parse-options.c                           | 31 +++++++++++++++--------
 t/t7500-commit-template-squash-signoff.sh | 12 ++++++++-
 2 files changed, 31 insertions(+), 12 deletions(-)
diff --git a/parse-options.c b/parse-options.c
index 33bfba0ed4..7a2a3b1f08 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -75,7 +75,6 @@ static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
 {
 	const char *s, *arg;
 	const int unset = flags & OPT_UNSET;
-	int err;
 
 	if (unset && p->opt)
 		return error(_("%s takes no value"), optname(opt, flags));
@@ -131,21 +130,31 @@ static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
 	case OPTION_FILENAME:
 	{
 		const char *value;
-
-		FREE_AND_NULL(*(char **)opt->value);
-
-		err = 0;
+		int is_optional;
 
 		if (unset)
 			value = NULL;
 		else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
-			value = (const char *) opt->defval;
-		else
-			err = get_arg(p, opt, flags, &value);
+			value = (char *)opt->defval;
+		else {
+			int err = get_arg(p, opt, flags, &value);
+			if (err)
+				return err;
+		}
+		if (!value)
+			return 0;
 
-		if (!err)
-			*(char **)opt->value = fix_filename(p->prefix, value);
-		return err;
+		is_optional = skip_prefix(value, ":(optional)", &value);
+		if (!value)
+			is_optional = 0;
+		value = fix_filename(p->prefix, value);
+		if (is_optional && is_empty_or_missing_file(value)) {
+			free((char *)value);
+		} else {
+			FREE_AND_NULL(*(char **)opt->value);
+			*(const char **)opt->value = value;
+		}
+		return 0;
 	}
 	case OPTION_CALLBACK:
 	{
diff --git a/t/t7500-commit-template-squash-signoff.sh b/t/t7500-commit-template-squash-signoff.sh
index e28a79987d..c065f12baf 100755
--- a/t/t7500-commit-template-squash-signoff.sh
+++ b/t/t7500-commit-template-squash-signoff.sh
@@ -37,12 +37,22 @@ test_expect_success 'nonexistent template file should return error' '
 	)
 '
 
+test_expect_success 'nonexistent optional template file on command line' '
+	echo changes >> foo &&
+	git add foo &&
+	(
+		GIT_EDITOR="echo hello >\"\$1\"" &&
+		export GIT_EDITOR &&
+		git commit --template ":(optional)$PWD/notexist"
+	)
+'
+
 test_expect_success 'nonexistent template file in config should return error' '
 	test_config commit.template "$PWD"/notexist &&
 	(
 		GIT_EDITOR="echo hello >\"\$1\"" &&
 		export GIT_EDITOR &&
-		test_must_fail git commit
+		test_must_fail git commit --allow-empty
 	)
 '
 
-- 
2.47.0-148-g19c85929c5
Previous: Junio C HamanoNext: Junio C Hamano
Message 11 of 47 in “blame: Skip missing ignore-revs file”
  1. 0/1 blame: Skip missing ignore-revs fileNoah Pendleton, Aug 7, 2021
  2. Junio C HamanoAug 7, 2021
  3. Noah PendletonAug 7, 2021
  4. Junio C HamanoAug 8, 2021
  5. Junio C HamanoAug 8, 2021
  6. Noah PendletonAug 8, 2021
  7. Junio C HamanoAug 9, 2021
  8. 0/3 specifying a file that can optionally existJunio C Hamano, Oct 14, 2024
  9. 1/3 t7500: make each piece more independentJunio C Hamano, Oct 14, 2024
  10. 2/3 config: values of pathname type can be prefixed with :(optional)Junio C Hamano, Oct 14, 2024
  11. 3/3 parseopt: values of pathname type can be prefixed with :(optional)Junio C Hamano, Oct 14, 2024
  12. 0/3 specifying a file that can optionally existJunio C Hamano, May 1, 2025
  13. 1/3 t7500: make each piece more independentJunio C Hamano, May 1, 2025
  14. 2/3 config: values of pathname type can be prefixed with :(optional)Junio C Hamano, May 1, 2025
  15. Patrick SteinhardtMay 2, 2025
  16. Phillip WoodMay 2, 2025
  17. Junio C HamanoMay 2, 2025
  18. 3/3 parseopt: values of pathname type can be prefixed with :(optional)Junio C Hamano, May 1, 2025
  19. 0/3 Support :(optional) filepathsD. Ben Knoble, Sep 28, 2025
  20. 1/3 t7500: make each piece more independentD. Ben Knoble, Sep 28, 2025
  21. 2/3 config: values of pathname type can be prefixed with :(optional)D. Ben Knoble, Sep 28, 2025
  22. Phillip WoodSep 30, 2025
  23. Junio C HamanoOct 6, 2025
  24. Junio C HamanoOct 6, 2025
  25. Junio C HamanoOct 6, 2025
  26. Junio C HamanoOct 6, 2025
  27. Kristoffer HaugsbakkOct 7, 2025
  28. Junio C HamanoOct 7, 2025
  29. D. Ben KnobleNov 2, 2025
  30. 3/3 parseopt: values of pathname type can be prefixed with :(optional)D. Ben Knoble, Sep 28, 2025
  31. Phillip WoodSep 30, 2025
  32. D. Ben KnobleNov 2, 2025
  33. Eric SunshineNov 3, 2025
  34. D. Ben KnobleNov 4, 2025
  35. Junio C HamanoSep 28, 2025
  36. Ben KnobleSep 29, 2025
  37. t7500: fix tests with absolute path following ":(optional)" on WindowsJohannes Sixt, Oct 20, 2025
  38. Ben KnobleOct 20, 2025
  39. Johannes SixtOct 20, 2025
  40. Junio C HamanoOct 20, 2025
  41. D. Ben KnobleOct 20, 2025
  42. D. Ben KnobleOct 20, 2025
  43. Eric SunshineOct 20, 2025
  44. Junio C HamanoOct 20, 2025
  45. Johannes SixtOct 20, 2025
  46. Thranur AndulMar 4, 2022
  47. blame: add config `blame.ignoreRevsFileIsOptional`Noah Pendleton, Aug 8, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.