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

Re: [PATCH v2 1/1] config: work around bug with includeif:onbranch and early config

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Jul 31, 2019, 22:13 UTC
Message-ID
<nycvar.QRO.7.76.6.1908010004130.21907@tvgsbejvaqbjf.bet>
In-Reply-To
<20190731220204.GA1933@sigill.intra.peff.net>
Hi Peff,
On Wed, 31 Jul 2019, Jeff King wrote:
Show 16 quoted lines
> On Wed, Jul 31, 2019 at 01:06:42PM -0700, Johannes Schindelin via GitGitGadget wrote:
>
> > Technically, there is a way to solve this properly: teach the refs
> > machinery to initialize the ref_store from a given gitdir/commondir pair
> > (which we _do_ have in the early config code path), and then use that in
> > `include_by_branch()`. This, however, is a pretty involved project, and
> > we're already in the feature freeze for Git v2.23.0.
>
> This gets tricky, because some commands are intentionally avoiding the
> normal lookup procedure (e.g., clone or init, and probably things like
> upload-pack that want to enter another repo). So I think it is OK as
> long as the early-config code is explicitly saying "and please look at
> the refs in this specific direectory now", and it doesn't affect other
> possible code paths that might look at refs. I _think_ that's what
> you're suggesting above, but I just want to make sure (not that it
> matters either way for this patch).

I think we already have the `git clone` problem with `includeif.gitdir:`. AFAICT we _will_ discover a Git directory when cloning inside an existing Git worktree.

> As a workaround, I suspect in many cases it might work to simply do a
> gentle setup (e.g., in "help"), but we simply weren't doing it before
> because there was no use case. That obviously wouldn't work for
> something like clone, though.
Right.

And as you say, there was no use case, and I would even contend that there still is no use case. In the cover letter, I tried to concoct something (using a branch-dependent pager) that sounds _really_ far-fetched to even me.

Show 14 quoted lines
>
> > diff --git a/config.c b/config.c
> > index ed7f58e0fc..3900e4947b 100644
> > --- a/config.c
> > +++ b/config.c
> > @@ -275,7 +275,8 @@ static int include_by_branch(const char *cond, size_t cond_len)
> >  	int flags;
> >  	int ret;
> >  	struct strbuf pattern = STRBUF_INIT;
> > -	const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, &flags);
> > +	const char *refname = !the_repository || !the_repository->gitdir ?
> > +		NULL : resolve_ref_unsafe("HEAD", 0, NULL, &flags);
>
> I think the_repository is always non-NULL.

No, it totally can be `NULL`. I know because my first version of the patch did not have that extra check, and `git help -a` would segfault outside a Git worktree when I had an `includeif.onbranch:` in my `~/.gitconfig`.

I tried to explain that in the commit message, but obviously did a poor job:

    Note: when calling above-mentioned two commands _outside_ of any Git
    worktree (passing the `--global` flag to `git config`, as there is
    obviously no repository config available), at the point when
    `include_by_branch()` is called, `the_repository` is `NULL`, therefore
    we have to be extra careful not to dereference it in that case.
> The way similar sites check this is withV
> "!startup_info->have_repository" or have_git_dir(). The early-config
> code uses the latter, so we should probably match it here.

Quite frankly, I'd rather not. At this point, it is not important whether or not we discovered a Git directory, but whether or not we have populated a dereference'able `the_repository`. Those are two different things.

Show 5 quoted lines
>   Side note: I suspect there are some cleanup opportunities. IIRC, I had
>   to add have_git_dir() to cover some cases where $GIT_DIR was set but
>   we hadn't explicitly done a setup step, but there's been a lot of
>   refactoring and cleanup in the initialization code since then. I'm not
>   sure if it's still necessary.

Yeah, well, I am not necessarily certain that we always ask the right questions, such as asking whether we found a startup repository when we need, in fact, to know whether `the_repository->refs` would cause a segmentation fault because we would dereference a `NULL` pointer ;-)

Show 16 quoted lines
>
> > diff --git a/t/t1309-early-config.sh b/t/t1309-early-config.sh
> > index 413642aa56..0c37e7180d 100755
> > --- a/t/t1309-early-config.sh
> > +++ b/t/t1309-early-config.sh
> > @@ -89,4 +89,9 @@ test_expect_failure 'ignore .git/ with invalid config' '
> >  	test_with_config "["
> >  '
> >
> > +test_expect_success 'early config and onbranch' '
> > +	echo "[broken" >broken &&
> > +	test_with_config "[includeif \"onbranch:refs/heads/master\"]path=../broken"
> > +'
>
> OK, so we know we didn't see the broken config because we'd have barfed
> if we actually included it. Makes sense.
That was the idea :-)

Thanks for the review! Dscho

Previous: Jeff KingNext: Jeff King
Message 7 of 17 in “Make the includeif:onbranch feature more robust”
  1. 0/1 Make the includeif:onbranch feature more robustJohannes Schindelin via GitGitGadget, Jul 31, 2019
  2. 1/1 config: work around bug with includeif:onbranch and early configJohannes Schindelin via GitGitGadget, Jul 31, 2019
  3. Junio C HamanoJul 31, 2019
  4. 0/1 Make the includeif:onbranch feature more robustJohannes Schindelin via GitGitGadget, Jul 31, 2019
  5. 1/1 config: work around bug with includeif:onbranch and early configJohannes Schindelin via GitGitGadget, Jul 31, 2019
  6. Jeff KingJul 31, 2019
  7. Johannes SchindelinJul 31, 2019
  8. Jeff KingJul 31, 2019
  9. Jeff KingAug 1, 2019
  10. Jeff HostetlerAug 1, 2019
  11. 0/3 the_repository initialization cleanupJeff King, Aug 6, 2019
  12. 1/3 t1309: use short branch name in includeIf.onbranch testJeff King, Aug 6, 2019
  13. 2/3 common-main: delay trace2 initializationJeff King, Aug 6, 2019
  14. 3/3 config: stop checking whether the_repository is NULLJeff King, Aug 6, 2019
  15. Jeff KingAug 6, 2019
  16. Johannes SchindelinAug 8, 2019
  17. Jeff KingAug 6, 2019

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.