mbox series

[v3,0/3] clone: suppress unexpected advice message during clone

Message ID 20250325005148.1771502-1-jltobler@gmail.com (mailing list archive)
Headers show
Series clone: suppress unexpected advice message during clone | expand

Message

Justin Tobler March 25, 2025, 12:51 a.m. UTC
It has been reported[1] that starting in Git v2.45.0, cloning from a bundle
results in the default branch name advice message always being displayed
when it was previously not. It can be reproduced by the following:

        git init bundle-repo &&
        git -C bundle-repo commit --allow-empty -m init &&
        git -C bundle-repo bundle create ../repo.bundle --all &&
        git clone repo.bundle bundle-clone

This issue bisects to 199f44cb2ead (builtin/clone: allow remote helpers
to detect repo, 2024-02-27) where the refdb is partially initialized
during clones before remote helpers are executed. This partial
initialization creates the HEAD file and "refs/" directory.

A side-effect of this change is that the location of the first
`git_default_branch_name()` gets deferred to a later point of execution.
This matters because `git_default_branch_name()` only computes the
default branch name once and returns a cached value for subsequent
invocations. After this change, the `git_default_branch_name()` call
site that actually computes the value becomes `guess_remote_head()` and
is configured to always show the advice message.

Also, `guess_remote_head()` only invokes `git_default_branch_name()` in
cases where the transport is unable to figure out the remote HEAD and
must guess. This explains why the advice message gets printed for bundle
clones, but not all clones.

This series addresses the issue by adapting `guess_remote_head()` to
support configuring the underlying `git_default_branch_name()`, which
has since been renamed to `repo_default_branch_name()`, to be quiet and
suppress the advice message.

Changes since V2:

        - The default branch name advice message may also print with the
          `--single-branch` option in certain scenarios. This instance
          is also suppressed by setting the `REMOTE_GUESS_HEAD_QUIET`
          flag for another `guess_remote_head()` call site invoked
          during clones.

Changes since V1:

        - Instead of adding an additional boolean to
          `guess_remote_head()` to suppress the advice message, the
          function is adapted to accepts flags that accoplish the same
          thing.

        - Added a test to validate that the advice message is not being
          printed.

        - While we are here, added another patch to allow the default
          branch name advice message to be suppressrd by the
          `--no-advice` option.

Thanks,
-Justin

[1]: <7EC98E2F-144D-4974-94F6-FC24B443651D@norbauer.com>

Justin Tobler (3):
  remote: allow `guess_remote_head()` to suppress advice
  builtin/clone: suppress unexpected default branch advice
  advice: allow disabling default branch name advice

 advice.c                |  1 +
 advice.h                |  1 +
 builtin/clone.c         |  7 +++++--
 builtin/fetch.c         |  2 +-
 builtin/remote.c        |  2 +-
 refs.c                  |  3 ++-
 remote.c                | 10 ++++++----
 remote.h                | 11 +++++++----
 t/t0001-init.sh         |  8 ++++++++
 t/t5607-clone-bundle.sh | 12 ++++++++++++
 10 files changed, 44 insertions(+), 13 deletions(-)

Range-diff against v2:
1:  4dae06d2dd = 1:  4dae06d2dd remote: allow `guess_remote_head()` to suppress advice
2:  1180caabf1 ! 2:  2a69b881c4 builtin/clone: suppress unexpected default branch advice
    @@ Commit message
         Signed-off-by: Justin Tobler <jltobler@gmail.com>
     
      ## builtin/clone.c ##
    +@@ builtin/clone.c: static struct ref *wanted_peer_refs(struct clone_opts *opts,
    + 		if (head)
    + 			tail_link_ref(head, &tail);
    + 		if (option_single_branch)
    +-			refs = to_free = guess_remote_head(head, refs, 0);
    ++			refs = to_free =
    ++				guess_remote_head(head, refs,
    ++						  REMOTE_GUESS_HEAD_QUIET);
    + 	} else if (option_single_branch) {
    + 		local_refs = NULL;
    + 		tail = &local_refs;
     @@ builtin/clone.c: int cmd_clone(int argc,
      	}
      
    @@ t/t5607-clone-bundle.sh: test_expect_success 'git bundle v3 rejects unknown capa
     +	git -C bundle-repo commit --allow-empty -m init &&
     +	git -C bundle-repo bundle create repo.bundle --all &&
     +	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= \
    -+		git clone bundle-repo/repo.bundle clone-repo 2>err &&
    ++		git clone --single-branch bundle-repo/repo.bundle clone-repo 2>err &&
     +
     +	test_grep ! "hint: " err
     +'
3:  6fef1d070c = 3:  98b32cdc99 advice: allow disabling default branch name advice

base-commit: 683c54c999c301c2cd6f715c411407c413b1d84e

Comments

Phillip Wood March 25, 2025, 2:35 p.m. UTC | #1
Hi Justin

The range-diff below looks good to me, Thanks for working on this

Phillip

On 25/03/2025 00:51, Justin Tobler wrote:
> Range-diff against v2:
> 1:  4dae06d2dd = 1:  4dae06d2dd remote: allow `guess_remote_head()` to suppress advice
> 2:  1180caabf1 ! 2:  2a69b881c4 builtin/clone: suppress unexpected default branch advice
>      @@ Commit message
>           Signed-off-by: Justin Tobler <jltobler@gmail.com>
>       
>        ## builtin/clone.c ##
>      +@@ builtin/clone.c: static struct ref *wanted_peer_refs(struct clone_opts *opts,
>      + 		if (head)
>      + 			tail_link_ref(head, &tail);
>      + 		if (option_single_branch)
>      +-			refs = to_free = guess_remote_head(head, refs, 0);
>      ++			refs = to_free =
>      ++				guess_remote_head(head, refs,
>      ++						  REMOTE_GUESS_HEAD_QUIET);
>      + 	} else if (option_single_branch) {
>      + 		local_refs = NULL;
>      + 		tail = &local_refs;
>       @@ builtin/clone.c: int cmd_clone(int argc,
>        	}
>        
>      @@ t/t5607-clone-bundle.sh: test_expect_success 'git bundle v3 rejects unknown capa
>       +	git -C bundle-repo commit --allow-empty -m init &&
>       +	git -C bundle-repo bundle create repo.bundle --all &&
>       +	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= \
>      -+		git clone bundle-repo/repo.bundle clone-repo 2>err &&
>      ++		git clone --single-branch bundle-repo/repo.bundle clone-repo 2>err &&
>       +
>       +	test_grep ! "hint: " err
>       +'
> 3:  6fef1d070c = 3:  98b32cdc99 advice: allow disabling default branch name advice
> 
> base-commit: 683c54c999c301c2cd6f715c411407c413b1d84e