Skip to content

Commit 0624c63

Browse files
avargitster
authored andcommitted
config: match both symlink & realpath versions in IncludeIf.gitdir:*
Change the conditional inclusion mechanism to support e.g. gitdir:~/git_tree/repo where ~/git_tree is a symlink to /mnt/stuff/repo. This worked in the initial version of this facility[1], but regressed later in the series while solving a related bug[2]. Now gitdir: will match against the symlinked path (e.g. gitdir:~/git_tree/repo) in addition to the current /mnt/stuff/repo path. Since this is already in a release version note in the documentation that this behavior changed, so users who expect their configuration to work on both v2.13.0 and some future version of git with this fix aren't utterly confused. 1. commit 3efd0be ("config: add conditional include", 2017-03-01) 2. commit 86f9515 ("config: resolve symlinks in conditional include's patterns", 2017-04-05) Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent c9672ba commit 0624c63

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
@@ -140,6 +140,16 @@ A few more notes on matching via `gitdir` and `gitdir/i`:
140140

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

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

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)