diff --git a/builtin/clone.c b/builtin/clone.c index 3baf1acc3c..9288fe2aa0 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -1266,36 +1266,31 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (transport_fetch_refs(transport, mapped_refs)) die(_("remote transport reported error")); } - - remote_head = find_ref_by_name(refs, "HEAD"); - remote_head_points_at = - guess_remote_head(remote_head, mapped_refs, 0); - - if (option_branch) { - our_head_points_at = - find_remote_branch(mapped_refs, option_branch); - - if (!our_head_points_at) - die(_("Remote branch %s not found in upstream %s"), - option_branch, remote_name); - } - else - our_head_points_at = remote_head_points_at; } - else { + + remote_head = find_ref_by_name(refs, "HEAD"); + remote_head_points_at = guess_remote_head(remote_head, mapped_refs, 0); + + if (option_branch) { + our_head_points_at = find_remote_branch(mapped_refs, option_branch); + if (!our_head_points_at) + die(_("Remote branch %s not found in upstream %s"), + option_branch, remote_name); + } else if (remote_head_points_at) { + our_head_points_at = remote_head_points_at; + } else if (remote_head) { + our_head_points_at = NULL; + } else { const char *branch; const char *ref; char *ref_free = NULL; - if (option_branch) - die(_("Remote branch %s not found in upstream %s"), - option_branch, remote_name); + if (!mapped_refs) { + warning(_("You appear to have cloned an empty repository.")); + option_no_checkout = 1; + } - warning(_("You appear to have cloned an empty repository.")); our_head_points_at = NULL; - remote_head_points_at = NULL; - remote_head = NULL; - option_no_checkout = 1; if (transport_ls_refs_options.unborn_head_target && skip_prefix(transport_ls_refs_options.unborn_head_target, diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index 00ce9aec23..2b3a78b842 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -250,6 +250,44 @@ test_expect_success 'bare clone propagates empty default branch' ' grep "refs/heads/mydefaultbranch" file_empty_child.git/HEAD ' +test_expect_success 'clone propagates unborn HEAD from non-empty repo' ' + test_when_finished "rm -rf file_unborn_parent file_unborn_child" && + + git init file_unborn_parent && + ( + cd file_unborn_parent && + 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=main -c protocol.version=2 \ + clone "file://$(pwd)/file_unborn_parent" \ + file_unborn_child 2>stderr && + grep "refs/heads/mydefaultbranch" file_unborn_child/.git/HEAD && + grep "warning: remote HEAD refers to nonexistent ref" stderr +' + +test_expect_success 'bare clone propagates unborn HEAD from non-empty repo' ' + test_when_finished "rm -rf file_unborn_parent file_unborn_child.git" && + + git init file_unborn_parent && + ( + cd file_unborn_parent && + 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=main -c protocol.version=2 \ + clone --bare "file://$(pwd)/file_unborn_parent" \ + file_unborn_child.git 2>stderr && + grep "refs/heads/mydefaultbranch" file_unborn_child.git/HEAD && + ! grep "warning:" stderr +' + test_expect_success 'fetch with file:// using protocol v2' ' test_when_finished "rm -f log" &&