Skip to content

Commit b784d0b

Browse files
committed
Merge branch 'ab/conditional-config-with-symlinks'
The recently introduced "[includeIf "gitdir:$dir"] path=..." mechansim has further been taught to take symlinks into account. The directory "$dir" specified in "gitdir:$dir" may be a symlink to a real location, not something that $(getcwd) may return. In such a case, a realpath of "$dir" is compared with the real path of the current repository to determine if the contents from the named path should be included. * ab/conditional-config-with-symlinks: config: match both symlink & realpath versions in IncludeIf.gitdir:*
2 parents 02c531e + 0624c63 commit b784d0b

3 files changed

Lines changed: 49 additions & 0 deletions

File tree

Documentation/config.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,16 @@ A few more notes on matching via `gitdir` and `gitdir/i`:
145145

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

148+
* Both the symlink & realpath versions of paths will be matched
149+
outside of `$GIT_DIR`. E.g. if ~/git is a symlink to
150+
/mnt/storage/git, both `gitdir:~/git` and `gitdir:/mnt/storage/git`
151+
will match.
152+
+
153+
This was not the case in the initial release of this feature in
154+
v2.13.0, which only matched the realpath version. Configuration that
155+
wants to be compatible with the initial release of this feature needs
156+
to either specify only the realpath version, or both versions.
157+
148158
* Note that "../" is not special and will match literally, which is
149159
unlikely what you want.
150160

config.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ static int include_by_gitdir(const struct config_options *opts,
214214
struct strbuf pattern = STRBUF_INIT;
215215
int ret = 0, prefix;
216216
const char *git_dir;
217+
int already_tried_absolute = 0;
217218

218219
if (opts->git_dir)
219220
git_dir = opts->git_dir;
@@ -226,6 +227,7 @@ static int include_by_gitdir(const struct config_options *opts,
226227
strbuf_add(&pattern, cond, cond_len);
227228
prefix = prepare_include_condition_pattern(&pattern);
228229

230+
again:
229231
if (prefix < 0)
230232
goto done;
231233

@@ -245,6 +247,20 @@ static int include_by_gitdir(const struct config_options *opts,
245247
ret = !wildmatch(pattern.buf + prefix, text.buf + prefix,
246248
icase ? WM_CASEFOLD : 0, NULL);
247249

250+
if (!ret && !already_tried_absolute) {
251+
/*
252+
* We've tried e.g. matching gitdir:~/work, but if
253+
* ~/work is a symlink to /mnt/storage/work
254+
* strbuf_realpath() will expand it, so the rule won't
255+
* match. Let's match against a
256+
* strbuf_add_absolute_path() version of the path,
257+
* which'll do the right thing
258+
*/
259+
strbuf_reset(&text);
260+
strbuf_add_absolute_path(&text, git_dir);
261+
already_tried_absolute = 1;
262+
goto again;
263+
}
248264
done:
249265
strbuf_release(&pattern);
250266
strbuf_release(&text);

t/t1305-config-include.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,29 @@ test_expect_success SYMLINKS 'conditional include, relative path with symlinks'
273273
)
274274
'
275275

276+
test_expect_success SYMLINKS 'conditional include, gitdir matching symlink' '
277+
ln -s foo bar &&
278+
(
279+
cd bar &&
280+
echo "[includeIf \"gitdir:bar/\"]path=bar7" >>.git/config &&
281+
echo "[test]seven=7" >.git/bar7 &&
282+
echo 7 >expect &&
283+
git config test.seven >actual &&
284+
test_cmp expect actual
285+
)
286+
'
287+
288+
test_expect_success SYMLINKS 'conditional include, gitdir matching symlink, icase' '
289+
(
290+
cd bar &&
291+
echo "[includeIf \"gitdir/i:BAR/\"]path=bar8" >>.git/config &&
292+
echo "[test]eight=8" >.git/bar8 &&
293+
echo 8 >expect &&
294+
git config test.eight >actual &&
295+
test_cmp expect actual
296+
)
297+
'
298+
276299
test_expect_success 'include cycles are detected' '
277300
cat >.gitconfig <<-\EOF &&
278301
[test]value = gitconfig

0 commit comments

Comments
 (0)