git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v8 2/2] config: add "worktree" and "worktree/i" includeIf conditions

From
Patrick Steinhardt <ps@pks.im>
Date
Jul 13, 2026, 11:16 UTC
Message-ID
<alTJCTKR9jOWfgbk@pks.im>
In-Reply-To
<20260710-includeif-worktree-v8-2-04686d8a616c@black-desk.cn>
On Fri, Jul 10, 2026 at 02:43:30PM +0800, Chen Linxuan via B4 Relay wrote:
Show 27 quoted lines
> diff --git a/Documentation/config.adoc b/Documentation/config.adoc
> index 15b1a4d59347..1ef72de62f2b 100644
> --- a/Documentation/config.adoc
> +++ b/Documentation/config.adoc
> @@ -146,6 +146,51 @@ 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 uses the same glob syntax as `gitdir` (including `~/`, `./`,
> +`**/`, and trailing-`/` prefix matching). This condition will never match
> +in a bare repository (which has no worktree).
> ++
> +Unlike `gitdir`, the `worktree` condition currently matches only the
> +realpath-resolved worktree location. If the working tree was entered via a
> +symbolic link, a pattern that uses the symbolic-link spelling may not match;
> +use the real path instead.

It might be worth noticing that this is essentially a limitation and that this limitation may be fixed at a later point in time. But that alone is not worth a reroll.

Show 73 quoted lines
> diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh
> index f3892578e4ff..4e840dfdb35b 100755
> --- a/t/t1305-config-include.sh
> +++ b/t/t1305-config-include.sh
> @@ -396,4 +396,132 @@ test_expect_success 'onbranch without repository but explicit nonexistent Git di
>  	test_must_fail nongit git --git-dir=nonexistent config get foo.bar
>  '
>  
> +# worktree: conditional include tests
> +
> +test_expect_success 'conditional include, worktree bare repo' '
> +	git init --bare wt-bare &&
> +	(
> +		cd wt-bare &&
> +		echo "[includeIf \"worktree:/\"]path=bar-bare" >>config &&
> +		echo "[test]wtbare=1" >bar-bare &&
> +		test_must_fail git config test.wtbare
> +	)
> +'
> +
> +test_expect_success 'conditional include, worktree multiple worktrees' '
> +	git init wt-multi &&
> +	(
> +		cd wt-multi &&
> +		test_commit initial &&
> +		git worktree add -b linked-branch ../wt-linked HEAD &&
> +		git worktree add -b prefix-branch ../wt-prefix/linked HEAD
> +	) &&
> +	wt_main="$(cd wt-multi && pwd)" &&
> +	wt_linked="$(cd wt-linked && pwd)" &&
> +	wt_prefix_parent="$(cd wt-prefix && pwd)" &&
> +	cat >>wt-multi/.git/config <<-EOF &&
> +	[includeIf "worktree:$wt_main"]
> +		path = main-config
> +	[includeIf "worktree:$wt_linked"]
> +		path = linked-config
> +	[includeIf "worktree:$wt_prefix_parent/"]
> +		path = prefix-config
> +	EOF
> +	echo "[test]mainvar=main" >wt-multi/.git/main-config &&
> +	echo "[test]linkedvar=linked" >wt-multi/.git/linked-config &&
> +	echo "[test]prefixvar=prefix" >wt-multi/.git/prefix-config &&
> +	echo main >expect &&
> +	git -C wt-multi config test.mainvar >actual &&
> +	test_cmp expect actual &&
> +	test_must_fail git -C wt-multi config test.linkedvar &&
> +	test_must_fail git -C wt-multi config test.prefixvar &&
> +	echo linked >expect &&
> +	git -C wt-linked config test.linkedvar >actual &&
> +	test_cmp expect actual &&
> +	test_must_fail git -C wt-linked config test.mainvar &&
> +	test_must_fail git -C wt-linked config test.prefixvar &&
> +	echo prefix >expect &&
> +	git -C wt-prefix/linked config test.prefixvar >actual &&
> +	test_cmp expect actual &&
> +	test_must_fail git -C wt-prefix/linked config test.mainvar &&
> +	test_must_fail git -C wt-prefix/linked config test.linkedvar
> +'
> +
> +test_expect_success SYMLINKS 'conditional include, worktree resolves symlinks' '
> +	mkdir real-wt &&
> +	ln -s real-wt link-wt &&
> +	git init link-wt/repo &&
> +	(
> +		cd link-wt/repo &&
> +		# repo->worktree resolves symlinks, so use real path in pattern
> +		echo "[includeIf \"worktree:**/real-wt/repo\"]path=bar-link" >>.git/config &&
> +		echo "[test]wtlink=2" >.git/bar-link &&
> +		echo 2 >expect &&
> +		git config test.wtlink >actual &&
> +		test_cmp expect actual
> +	)
> +'

There should arguably be a test with `test_expect_failure` that shows that we in theory _want_ to use both the realpath, but also the symlinked path to resolve this.

In any case, I think this version is good enough. It's a bit sad that we cannot easily handle symlinked paths right now, but I'd say that this is acceptable for now. We might fix this eventually, once we have cleaned up "setup.c" to not modify global state left and right.

Thanks!
Patrick
Previous: Chen Linxuan via B4 Relay
Message 4 of 4 in “includeIf: add "worktree" condition for matching working tree path”
  1. 0/2 includeIf: add "worktree" condition for matching working tree pathChen Linxuan via B4 Relay, Jul 10, 2026
  2. 1/2 config: refactor include_by_gitdir() into include_by_path()Chen Linxuan via B4 Relay, Jul 10, 2026
  3. 2/2 config: add "worktree" and "worktree/i" includeIf conditionsChen Linxuan via B4 Relay, Jul 10, 2026
  4. Patrick SteinhardtJul 13, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.