diff --git a/builtin/clone.c b/builtin/clone.c index 9288fe2aa0..eafbd3de4e 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -1290,8 +1290,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix) option_no_checkout = 1; } - our_head_points_at = NULL; - if (transport_ls_refs_options.unborn_head_target && skip_prefix(transport_ls_refs_options.unborn_head_target, "refs/heads/", &branch)) { @@ -1303,7 +1301,20 @@ int cmd_clone(int argc, const char **argv, const char *prefix) ref = ref_free; } - if (!option_bare) + /* + * We may have selected a local default branch name "foo", + * and even though the remote's HEAD does not point there, + * it may still have a "foo" branch. If so, set it up so + * that we can follow the usual checkout code later. + * + * Note that for an empty repo we'll already have set + * option_no_checkout above, which would work against us here. + * But for an empty repo, find_remote_branch() can never find + * a match. + */ + our_head_points_at = find_remote_branch(mapped_refs, branch); + + if (!option_bare && !our_head_points_at) install_branch_config(0, branch, remote_name, ref); free(ref_free); } diff --git a/t/t5605-clone-local.sh b/t/t5605-clone-local.sh index 7d63365f93..aa38db6416 100755 --- a/t/t5605-clone-local.sh +++ b/t/t5605-clone-local.sh @@ -21,7 +21,9 @@ test_expect_success 'preparing origin repository' ' git bundle create b2.bundle main && mkdir dir && cp b1.bundle dir/b3 && - cp b1.bundle b4 + cp b1.bundle b4 && + git branch not-main main && + git bundle create b5.bundle not-main ' test_expect_success 'local clone without .git suffix' ' @@ -83,11 +85,19 @@ test_expect_success 'bundle clone from b4.bundle that does not exist' ' test_must_fail git clone b4.bundle bb ' -test_expect_success 'bundle clone with nonexistent HEAD' ' +test_expect_success 'bundle clone with nonexistent HEAD (match default)' ' git clone b2.bundle b2 && (cd b2 && git fetch && - test_must_fail git rev-parse --verify refs/heads/main) + git rev-parse --verify refs/heads/main) +' + +test_expect_success 'bundle clone with nonexistent HEAD (no match default)' ' + git clone b5.bundle b5 && + (cd b5 && + git fetch && + test_must_fail git rev-parse --verify refs/heads/main && + test_must_fail git rev-parse --verify refs/heads/not-main) ' test_expect_success 'clone empty repository' ' diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index 2b3a78b842..5d42a355a8 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -288,6 +288,27 @@ test_expect_success 'bare clone propagates unborn HEAD from non-empty repo' ' ! grep "warning:" stderr ' +test_expect_success 'defaulted HEAD uses remote branch if available' ' + test_when_finished "rm -rf file_unborn_parent file_unborn_child" && + + git init file_unborn_parent && + ( + cd file_unborn_parent && + git config lsrefs.unborn ignore && + git checkout -b branchwithstuff && + test_commit --no-tag stuff && + git symbolic-ref HEAD refs/heads/mydefaultbranch + ) && + + GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= \ + git -c init.defaultBranch=branchwithstuff -c protocol.version=2 \ + clone "file://$(pwd)/file_unborn_parent" \ + file_unborn_child 2>stderr && + grep "refs/heads/branchwithstuff" file_unborn_child/.git/HEAD && + test_path_is_file file_unborn_child/stuff.t && + ! grep "warning:" stderr +' + test_expect_success 'fetch with file:// using protocol v2' ' test_when_finished "rm -f log" &&