Git development
 help / color / mirror / Atom feed
From: Patrick Steinhardt <ps@pks.im>
To: me@black-desk.cn
Cc: git@vger.kernel.org,
	Kristoffer Haugsbakk <kristofferhaugsbakk@fastmail.com>,
	Junio C Hamano <gitster@pobox.com>
Subject: Re: [PATCH v3 2/2] config: add "worktree" and "worktree/i" includeIf conditions
Date: Tue, 12 May 2026 09:14:03 +0200	[thread overview]
Message-ID: <agLTO0amktCWMsiE@pks.im> (raw)
In-Reply-To: <20260403-includeif-worktree-v3-2-109ce5782b03@black-desk.cn>

On Fri, Apr 03, 2026 at 03:02:29PM +0800, Chen Linxuan via B4 Relay wrote:
> From: Chen Linxuan <me@black-desk.cn>
> 
> The includeIf mechanism already supports matching on the .git
> directory path (gitdir) and the currently checked out branch
> (onbranch).  But in multi-worktree setups the .git directory of a
> linked worktree points into the main repository's .git/worktrees/
> area, which makes gitdir patterns cumbersome when one wants to
> include config based on the working tree's checkout path instead.
> 
> Introduce two new condition keywords:
> 
>   - worktree:<pattern> matches the realpath of the current worktree's
>     working directory (i.e. repo_get_work_tree()) against a glob
>     pattern.  This is the path returned by git rev-parse
>     --show-toplevel.
> 
>   - worktree/i:<pattern> is the case-insensitive variant.

Seems sensible.

> The implementation reuses the include_by_path() helper introduced in
> the previous commit, passing the worktree path in place of the
> gitdir.  The condition never matches in bare repositories (where
> there is no worktree) or during early config reading (where no
> repository is available).

Right. This is because `repo_get_work_tree()` would return a NULL
pointer in these cases, and `include_by_path()` exits early in that
case.

> diff --git a/Documentation/config.adoc b/Documentation/config.adoc
> index 62eebe7c5450..a4f3ec905098 100644
> --- a/Documentation/config.adoc
> +++ b/Documentation/config.adoc
> @@ -146,6 +146,48 @@ refer to linkgit:gitignore[5] for details. For convenience:
>  	This is the same as `gitdir` except that matching is done
>  	case-insensitively (e.g. on case-insensitive file systems)
>  
> +`worktree`::
> +	The data that follows the keyword `worktree` and a colon is used as a
> +	glob pattern. If the working directory of the current worktree matches
> +	the pattern, the include condition is met.
> ++
> +The worktree location is the path where files are checked out (as returned
> +by `git rev-parse --show-toplevel`). This is different from `gitdir`, which
> +matches the `.git` directory path. In a linked worktree, the worktree path
> +is the directory where that worktree's files are located, not the main
> +repository's `.git` directory.
> ++
> +The pattern can contain standard globbing wildcards and two additional
> +ones, `**/` and `/**`, that can match multiple path components. Please
> +refer to linkgit:gitignore[5] for details. For convenience:
> +
> + * If the pattern starts with `~/`, `~` will be substituted with the
> +   content of the environment variable `HOME`.
> +
> + * If the pattern starts with `./`, it is replaced with the directory
> +   containing the current config file.
> +
> + * If the pattern does not start with either `~/`, `./` or `/`, `**/`
> +   will be automatically prepended. For example, the pattern `foo/bar`
> +   becomes `**/foo/bar` and would match `/any/path/to/foo/bar`.
> +
> + * If the pattern ends with `/`, `**` will be automatically added. For
> +   example, the pattern `foo/` becomes `foo/**`. In other words, it
> +   matches "foo" and everything inside, recursively.

This whole listing here is the exact same as we have for the `gitdir`
condition. Can we maybe deduplicate these into a common section?

> diff --git a/config.c b/config.c
> index 7d5dae0e8450..6d0c2d0725e4 100644
> --- a/config.c
> +++ b/config.c
> @@ -400,6 +400,12 @@ static int include_condition_is_true(const struct key_value_info *kvi,
>  		return include_by_path(kvi, opts->git_dir, cond, cond_len, 0);
>  	else if (skip_prefix_mem(cond, cond_len, "gitdir/i:", &cond, &cond_len))
>  		return include_by_path(kvi, opts->git_dir, cond, cond_len, 1);
> +	else if (skip_prefix_mem(cond, cond_len, "worktree:", &cond, &cond_len))
> +		return include_by_path(kvi, inc->repo ? repo_get_work_tree(inc->repo) : NULL,
> +				       cond, cond_len, 0);
> +	else if (skip_prefix_mem(cond, cond_len, "worktree/i:", &cond, &cond_len))
> +		return include_by_path(kvi, inc->repo ? repo_get_work_tree(inc->repo) : NULL,
> +				       cond, cond_len, 1);
>  	else if (skip_prefix_mem(cond, cond_len, "onbranch:", &cond, &cond_len))
>  		return include_by_branch(inc, cond, cond_len);
>  	else if (skip_prefix_mem(cond, cond_len, "hasconfig:remote.*.url:", &cond,

I feel like this is something that we might eventually want to convert
to be table-driven. But I think that doesn't have to happen as part of
this patch series.

> diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh
> index 6e51f892f320..8a5ba4b884d3 100755
> --- a/t/t1305-config-include.sh
> +++ b/t/t1305-config-include.sh

Just because it was explicitly mentioned: we might also want to have a
test that verifies this works with early-config parsing. We already have
a similar test for "gitdir:" in "conditional include, early config
reading".

And should we also have a "nongit" branch where we verify outside a
repository?

Other than that this series looks good to me, thanks!

Patrick

  reply	other threads:[~2026-05-12  7:14 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-03  7:02 [PATCH v3 0/2] includeIf: add "worktree" condition for matching working tree path Chen Linxuan via B4 Relay
2026-04-03  7:02 ` [PATCH v3 1/2] config: refactor include_by_gitdir() into include_by_path() Chen Linxuan via B4 Relay
2026-05-12  7:13   ` Patrick Steinhardt
2026-04-03  7:02 ` [PATCH v3 2/2] config: add "worktree" and "worktree/i" includeIf conditions Chen Linxuan via B4 Relay
2026-05-12  7:14   ` Patrick Steinhardt [this message]
2026-05-12 15:07     ` Phillip Wood
2026-05-12 16:09       ` Junio C Hamano
2026-05-13  2:55         ` Chen Linxuan
2026-05-13  2:47     ` Chen Linxuan
2026-05-13  5:56       ` Patrick Steinhardt
2026-05-12  6:41 ` [PATCH v3 0/2] includeIf: add "worktree" condition for matching working tree path Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=agLTO0amktCWMsiE@pks.im \
    --to=ps@pks.im \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=kristofferhaugsbakk@fastmail.com \
    --cc=me@black-desk.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox