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

Re: [PATCH] worktree: update is_bare heuristics

From
Junio C Hamano <gitster@pobox.com>
Date
Apr 18, 2019, 02:16 UTC
Message-ID
<xmqqo954gira.fsf@gitster-ct.c.googlers.com>
In-Reply-To
<20190417212128.52475-1-jonathantanmy@google.com>
Jonathan Tan <jonathantanmy@google.com> writes:

[jc: pinging the current area expert for the multiple worktree setup for sanity checking]

Show 27 quoted lines
> When "git branch -D <name>" is run, Git usually first checks if that
> branch is currently checked out. But this check is not performed if the
> Git directory of that repository is not at "<repo>/.git", which is the
> case if that repository is a submodule that has its Git directory stored
> as "super/.git/modules/<repo>", for example.
>
> This is because get_main_worktree() in worktree.c sets is_bare on a
> worktree only using the heuristic that a repo is bare if the worktree's
> path ends in "/.git", and not bare otherwise. This is_bare code was
> introduced in 92718b7438 ("worktree: add details to the worktree
> struct", 2015-10-08), following a pre-core.bare heuristic. This patch
> does 2 things:
>
>  - Teach get_main_worktree() to use is_bare_repository() instead,
>    introduced in 7d1864ce67 ("Introduce is_bare_repository() and
>    core.bare configuration variable", 2007-01-07) and updated in
>    e90fdc39b6 ("Clean up work-tree handling", 2007-08-01). This solves
>    the "git branch -D <name>" problem described above. However...
>
>  - If a repository has core.bare=1 but the "git" command is being run
>    from one of its added worktrees, is_bare_repository() returns false
>    (which is fine, since there is a worktree available). However,
>    commands like "git worktree list" currently distinguish between a
>    repository that has core.bare=1 but has a worktree available, and a
>    repository that is truly non-bare (core.bare=0). To preserve this
>    distinction, also check core.bare when setting is_bare. If
>    core.bare=1, trust it, and otherwise, use is_bare_repository().

I am not sure if the latter is worth keeping, but the former definitely is a huge improvement, I would imagine. Somebody did "git branch -D <that-branch>" by accident in a submodule checkout, or something?

Show 13 quoted lines
> +test_expect_success 'deleting checked-out branch from repo that is a submodule' '
> +	test_when_finished "rm -rf repo1 repo2" &&
> +
> +	git init repo1 &&
> +	git init repo1/sub &&
> +	test_commit -C repo1/sub x &&
> +	git -C repo1 submodule add ./sub &&
> +	git -C repo1 commit -m "adding sub" &&
> +
> +	git clone --recurse-submodules repo1 repo2 &&
> +	git -C repo2/sub checkout -b work &&
> +	test_must_fail git -C repo2/sub branch -D work
> +'
That is a quite straightforward reproduction recipe.  Very good.
Show 15 quoted lines
> diff --git a/worktree.c b/worktree.c
> index b45bfeb9d3..5d52b2ba53 100644
> --- a/worktree.c
> +++ b/worktree.c
> @@ -49,18 +49,17 @@ static struct worktree *get_main_worktree(void)
>  	struct worktree *worktree = NULL;
>  	struct strbuf path = STRBUF_INIT;
>  	struct strbuf worktree_path = STRBUF_INIT;
> -	int is_bare = 0;
>  
>  	strbuf_add_absolute_path(&worktree_path, get_git_common_dir());
> -	is_bare = !strbuf_strip_suffix(&worktree_path, "/.git");
> -	if (is_bare)
> +	if (!strbuf_strip_suffix(&worktree_path, "/.git"))
>  		strbuf_strip_suffix(&worktree_path, "/.");

So, we'd drop /.git or /. from the end, without any behaviour change. But we no longer take the fact that it was not the ".git" subdirectory into account, as that is unreliable?

Show 7 quoted lines
>  	strbuf_addf(&path, "%s/HEAD", get_git_common_dir());
>  
>  	worktree = xcalloc(1, sizeof(*worktree));
>  	worktree->path = strbuf_detach(&worktree_path, NULL);
> -	worktree->is_bare = is_bare;
> +	worktree->is_bare = (is_bare_repository_cfg == 1) ||
> +		is_bare_repository();

And instead core.bare being '1' is used as the definite sign that we are dealing with a bare repository.

It all makes sense to me.
Thanks for working on it.
>  	add_head_info(worktree);
>  
>  	strbuf_release(&path);
Previous: Jonathan TanNext: Johannes Schindelin
Message 2 of 10 in “worktree: update is_bare heuristics”
  1. worktree: update is_bare heuristicsJonathan Tan, Apr 17, 2019
  2. Junio C HamanoApr 18, 2019
  3. Johannes SchindelinApr 18, 2019
  4. Jonathan TanApr 18, 2019
  5. Duy NguyenApr 18, 2019
  6. Jonathan TanApr 18, 2019
  7. Jeff KingApr 18, 2019
  8. Duy NguyenApr 19, 2019
  9. Duy NguyenApr 19, 2019
  10. worktree: update is_bare heuristicsJonathan Tan, Apr 19, 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.