Currently, customizing the configuration depending on the machine running git has to be done manually. Add support for a new includeIf keyword "hostname:" to conditionally include configuration files depending on the hostname. Signed-off-by: Ignacio Encinas <ignacio@xxxxxxxxxxxx> --- Documentation/config.txt | 9 +++++++++ config.c | 17 ++++++++++++++++ t/t1305-config-include.sh | 42 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) diff --git a/Documentation/config.txt b/Documentation/config.txt index e3a74dd1c19d..9a22fd260935 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -186,6 +186,11 @@ As for the naming of this keyword, it is for forwards compatibility with a naming scheme that supports more variable-based include conditions, but currently Git only supports the exact keyword described above. +`hostname`:: + The data that follows the keyword `hostname:` is taken to be a + pattern with standard globbing wildcards. If the current + hostname matches the pattern, the include condition is met. + A few more notes on matching via `gitdir` and `gitdir/i`: * Symlinks in `$GIT_DIR` are not resolved before matching. @@ -261,6 +266,10 @@ Example path = foo.inc [remote "origin"] url = https://example.com/git + +; include only if the hostname of the machine matches some-hostname +[includeIf "hostname:some-hostname"] + path = foo.inc ---- Values diff --git a/config.c b/config.c index 3cfeb3d8bd99..50b3f6d24c50 100644 --- a/config.c +++ b/config.c @@ -317,6 +317,21 @@ static int include_by_branch(const char *cond, size_t cond_len) return ret; } +static int include_by_hostname(const char *cond, size_t cond_len) +{ + int ret; + char my_host[HOST_NAME_MAX + 1]; + struct strbuf pattern = STRBUF_INIT; + + if (xgethostname(my_host, sizeof(my_host))) + return 0; + + strbuf_add(&pattern, cond, cond_len); + ret = !wildmatch(pattern.buf, my_host, 0); + strbuf_release(&pattern); + return ret; +} + static int add_remote_url(const char *var, const char *value, const struct config_context *ctx UNUSED, void *data) { @@ -406,6 +421,8 @@ static int include_condition_is_true(const struct key_value_info *kvi, else if (skip_prefix_mem(cond, cond_len, "hasconfig:remote.*.url:", &cond, &cond_len)) return include_by_remote_url(inc, cond, cond_len); + else if (skip_prefix_mem(cond, cond_len, "hostname:", &cond, &cond_len)) + return include_by_hostname(cond, cond_len); /* unknown conditionals are always false */ return 0; diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh index 5cde79ef8c4f..e0a1d51d50ad 100755 --- a/t/t1305-config-include.sh +++ b/t/t1305-config-include.sh @@ -357,4 +357,46 @@ test_expect_success 'include cycles are detected' ' grep "exceeded maximum include depth" stderr ' +test_expect_success 'conditional include, hostname' ' + cat >>.git/config <<-EOF && + [includeIf "hostname:$(hostname)a"] + path = bar12 + EOF + cat >>.git/bar12 <<-EOF && + [test] + twelve=12 + EOF + + test_must_fail git config test.twelve && + + cat >>.git/config <<-EOF && + [includeIf "hostname:$(hostname)"] + path = bar12 + EOF + echo 12 >expect && + git config test.twelve >actual && + test_cmp expect actual +' + +test_expect_success 'conditional include, hostname, wildcard' ' + cat >>.git/config <<-EOF && + [includeIf "hostname:$(hostname)a*"] + path = bar13 + EOF + cat >>.git/bar13 <<-EOF && + [test] + thirteen = 13 + EOF + + test_must_fail git config test.thirteen && + + cat >>.git/config <<-EOF && + [includeIf "hostname:$(hostname)*"] + path = bar13 + EOF + echo 13 >expect && + git config test.thirteen >actual && + test_cmp expect actual +' + test_done -- 2.44.0