From: "Randall S. Becker" <rsbecker@xxxxxxxxxxxxx> This enhancement extends the [includeIf] semantics to include conditional inclusion based on whether the conditional is within a specific worktree or case-insensitive worktree. The [includeIf "worktree:path"] and [includeIf "worktree/i:path"] and analogous to the gitdir: and gitdir/i: conditions, respectively. Signed-off-by: Randall S. Becker <rsbecker@xxxxxxxxxxxxx> --- config.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/config.c b/config.c index f9c400ad30..e2b2364579 100644 --- a/config.c +++ b/config.c @@ -272,6 +272,64 @@ static int include_by_gitdir(const struct config_options *opts, return ret; } +static int include_by_worktree(const struct config_options *opts, + const char *cond, size_t cond_len, int icase) +{ + struct strbuf text = STRBUF_INIT; + struct strbuf pattern = STRBUF_INIT; + int ret = 0, prefix; + const char *worktree; + int already_tried_absolute = 0; + + if (the_repository->worktree) + worktree = the_repository->worktree; + else + goto done; + + strbuf_realpath(&text, worktree, 1); + strbuf_add(&pattern, cond, cond_len); + prefix = prepare_include_condition_pattern(&pattern); + +again: + if (prefix < 0) + goto done; + + if (prefix > 0) { + /* + * perform literal matching on the prefix part so that + * any wildcard character in it can't create side effects. + */ + if (text.len < prefix) + goto done; + if (!icase && strncmp(pattern.buf, text.buf, prefix)) + goto done; + if (icase && strncasecmp(pattern.buf, text.buf, prefix)) + goto done; + } + + ret = !wildmatch(pattern.buf + prefix, text.buf + prefix, + WM_PATHNAME | (icase ? WM_CASEFOLD : 0)); + + if (!ret && !already_tried_absolute) { + /* + * We've tried e.g. matching worktree:~/work, but if + * ~/work is a symlink to /mnt/storage/work + * strbuf_realpath() will expand it, so the rule won't + * match. Let's match against a + * strbuf_add_absolute_path() version of the path, + * which'll do the right thing + */ + strbuf_reset(&text); + strbuf_add_absolute_path(&text, worktree); + already_tried_absolute = 1; + goto again; + } +done: + strbuf_release(&pattern); + strbuf_release(&text); + return ret; +} + static int include_by_branch(const char *cond, size_t cond_len) { int flags; @@ -300,6 +358,11 @@ static int include_condition_is_true(const struct config_options *opts, return include_by_gitdir(opts, cond, cond_len, 0); else if (skip_prefix_mem(cond, cond_len, "gitdir/i:", &cond, &cond_len)) return include_by_gitdir(opts, cond, cond_len, 1); + else if (skip_prefix_mem(cond, cond_len, "worktree:", &cond, &cond_len)) + return include_by_worktree(opts, cond, cond_len, 0); + else if (skip_prefix_mem(cond, cond_len, "worktree/i:", &cond, + &cond_len)) + return include_by_worktree(opts, cond, cond_len, 1); else if (skip_prefix_mem(cond, cond_len, "onbranch:", &cond, &cond_len)) return include_by_branch(cond, cond_len); -- 2.32.0