Re: [PATCH v2 2/3] config: values of pathname type can be prefixed with :(optional)
- From
Junio C Hamano <gitster@pobox.com>
- Date
- Oct 6, 2025, 20:22 UTC
- Message-ID
- <xmqqikgrok4u.fsf@gitster.g>
- In-Reply-To
- <xmqqms63ok7g.fsf@gitster.g>
Junio C Hamano <gitster@pobox.com> writes:
Show 5 quoted lines
> So, here is the preliminary clea-up step that should come before > [2/3] > > --- >8 --- > Subject: [PATCH] t7500: fix GIT_EDITOR shell snippet
And this is [2/3] rebased on top.
--- >8 --- Subject: [PATCH] config: values of pathname type can be prefixed with :(optional)
Sometimes people want to specify additional configuration data as "best effort" basis. Maybe commit.template configuration file points at somewhere in ~/template/ but on a particular system, the file may not exist and the user may be OK without using the template in such a case.
When the value given to a configuration variable whose type is pathname wants to signal such an optional file, it can be marked by prepending ":(optional)" in front of it. Such a setting that is marked optional would avoid getting the command barf for a missing file, as an optional configuration setting that names a missing file is not even seen.
cf. <xmqq5ywehb69.fsf@gitster.g>
Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: D. Ben Knoble <ben.knoble+github@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com> --- Documentation/config.adoc | 4 +++- config.c | 16 ++++++++++++++-- t/t7500-commit-template-squash-signoff.sh | 8 ++++++++ wrapper.c | 13 +++++++++++++ wrapper.h | 4 +++- 5 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/Documentation/config.adoc b/Documentation/config.adoc index cc769251be..7301ced836 100644 --- a/Documentation/config.adoc +++ b/Documentation/config.adoc @@ -358,7 +358,9 @@ compiled without runtime prefix support, the compiled-in prefix will be substituted instead. In the unlikely event that a literal path needs to be specified that should _not_ be expanded, it needs to be prefixed by `./`, like so: `./%(prefix)/bin`. - ++ +If prefixed with `:(optional)`, the configuration variable is treated +as if it does not exist, if the named path does not exist. Variables ~~~~~~~~~ diff --git a/config.c b/config.c index 97ffef4270..73fc74c8fa 100644 --- a/config.c +++ b/config.c @@ -1279,11 +1279,23 @@ int git_config_string(char **dest, const char *var, const char *value) int git_config_pathname(char **dest, const char *var, const char *value) { + int is_optional; + char *path; + if (!value) return config_error_nonbool(var); - *dest = interpolate_path(value, 0); - if (!*dest) + + is_optional = skip_prefix(value, ":(optional)", &value); + path = interpolate_path(value, 0); + if (!path) die(_("failed to expand user dir in: '%s'"), value); + + if (is_optional && is_missing_file(path)) { + free(path); + return 0; + } + + *dest = path; return 0; } diff --git a/t/t7500-commit-template-squash-signoff.sh b/t/t7500-commit-template-squash-signoff.sh index 4922543256..a85229e556 100755 --- a/t/t7500-commit-template-squash-signoff.sh +++ b/t/t7500-commit-template-squash-signoff.sh @@ -46,6 +46,14 @@ test_expect_success 'nonexistent template file in config should return error' ' ) ' +test_expect_success 'nonexistent optional template file in config' ' + test_config commit.template ":(optional)$PWD"/notexist && + GIT_EDITOR="echo hello >" git commit --allow-empty && + git cat-file commit HEAD | sed -e "1,/^$/d" >actual && + echo hello >expect && + test_cmp expect actual +' + # From now on we'll use a template file that exists. TEMPLATE="$PWD"/template diff --git a/wrapper.c b/wrapper.c index 2f00d2ac87..3d507d4204 100644 --- a/wrapper.c +++ b/wrapper.c @@ -721,6 +721,19 @@ int xgethostname(char *buf, size_t len) return ret; } +int is_missing_file(const char *filename) +{ + struct stat st; + + if (stat(filename, &st) < 0) { + if (errno == ENOENT) + return 1; + die_errno(_("could not stat %s"), filename); + } + + return 0; +} + int is_empty_or_missing_file(const char *filename) { struct stat st; diff --git a/wrapper.h b/wrapper.h index 7df824e34a..44a8597ac3 100644 --- a/wrapper.h +++ b/wrapper.h @@ -66,7 +66,9 @@ void write_file_buf(const char *path, const char *buf, size_t len); __attribute__((format (printf, 2, 3))) void write_file(const char *path, const char *fmt, ...); -/* Return 1 if the file is empty or does not exists, 0 otherwise. */ +/* Return 1 if the file does not exist, 0 otherwise. */ +int is_missing_file(const char *filename); +/* Return 1 if the file is empty or does not exist, 0 otherwise. */ int is_empty_or_missing_file(const char *filename); enum fsync_action {
-- 2.51.0-580-g8258b70b6e