Skip to content

Commit 1e5c504

Browse files
committed
config: introduce an Operating System-specific includeIf condition
It is relatively common for users to maintain identical `~/.gitconfig` files across all of their setups, using the `includeIf` construct liberally to adjust the settings to the respective setup as needed. In case of Operating System-specific adjustments, Git currently offers no support to the users and they typically use a work-around like this: [includeIf "gitdir:/home/"] path = ~/.gitconfig-linux [includeIf "gitdir:/Users/"] path = ~/.gitconfig-mac [includeIf "gitdir:C:"] path = ~/.gitconfig-windows However, this is fragile, as it would not even allow to discern between Operating Systems that happen to host their home directories in `/home/`, such as Linux and the BSDs. Let's introduce a new condition: `os:<uname-s>` where `<uname-s>` is the system name, i.e. the output of `uname -s`. This addresses git-for-windows#4125 Signed-off-by: Johannes Schindelin <[email protected]>
1 parent e4a4b31 commit 1e5c504

File tree

3 files changed

+26
-0
lines changed

3 files changed

+26
-0
lines changed

Documentation/config.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,11 @@ As for the naming of this keyword, it is for forwards compatibiliy with
186186
a naming scheme that supports more variable-based include conditions,
187187
but currently Git only supports the exact keyword described above.
188188

189+
`os`::
190+
The data that follows this keyword is taken as the name of an
191+
Operating System; If it matches the output of `uname -s`, the
192+
include condition is met.
193+
189194
A few more notes on matching via `gitdir` and `gitdir/i`:
190195

191196
* Symlinks in `$GIT_DIR` are not resolved before matching.

config.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,15 @@ static int include_by_remote_url(struct config_include_data *inc,
394394
inc->remote_urls);
395395
}
396396

397+
static int include_by_os(const char *cond, size_t cond_len)
398+
{
399+
struct utsname uname_info;
400+
401+
return !uname(&uname_info) &&
402+
!strncasecmp(uname_info.sysname, cond, cond_len) &&
403+
!uname_info.sysname[cond_len];
404+
}
405+
397406
static int include_condition_is_true(struct config_include_data *inc,
398407
const char *cond, size_t cond_len)
399408
{
@@ -408,6 +417,8 @@ static int include_condition_is_true(struct config_include_data *inc,
408417
else if (skip_prefix_mem(cond, cond_len, "hasconfig:remote.*.url:", &cond,
409418
&cond_len))
410419
return include_by_remote_url(inc, cond, cond_len);
420+
else if (skip_prefix_mem(cond, cond_len, "os:", &cond, &cond_len))
421+
return include_by_os(cond, cond_len);
411422

412423
/* unknown conditionals are always false */
413424
return 0;

t/t1309-early-config.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,14 @@ test_expect_success 'onbranch config outside of git repo' '
100100
nongit git help
101101
'
102102

103+
test_expect_success '[includeIf "os:..."]' '
104+
test_config x.y 0 &&
105+
echo "[x] y = z" >.git/xyz &&
106+
uname_s="$(uname -s)" &&
107+
test_config "includeIf.os:not-$uname_s.path" xyz &&
108+
test 0 = "$(git config x.y)" &&
109+
test_config "includeIf.os:$uname_s.path" xyz &&
110+
test z = "$(git config x.y)"
111+
'
112+
103113
test_done

0 commit comments

Comments
 (0)