summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2021-01-10 21:32:28 +0000
committerGitHub <noreply@github.com>2021-01-10 21:32:28 +0000
commit487f2a8287c4d1d41d39e05ac53d0e50c679d7e9 (patch)
tree86841120849593fe2d270208b109a4288450c89b
parentc6cf7f0e6927f1b264a7dda2467d70b9f744a01f (diff)
parent923c0f7b763bf3d20f9cd8f02ab9b1d400c733ab (diff)
downloadlibgit2-487f2a8287c4d1d41d39e05ac53d0e50c679d7e9.tar.gz
Merge pull request #5775 from libgit2/ethomson/clone_branch
clone: set refs/remotes/origin/HEAD when branch is specified
-rw-r--r--src/clone.c63
-rw-r--r--tests/clone/nonetwork.c8
2 files changed, 50 insertions, 21 deletions
diff --git a/src/clone.c b/src/clone.c
index 7ae90b09e..6d5ebf6b0 100644
--- a/src/clone.c
+++ b/src/clone.c
@@ -162,6 +162,37 @@ done:
return error;
}
+static int update_remote_head_byname(
+ git_repository *repo,
+ const char *remote_name,
+ const char *tracking_branch_name,
+ const char *reflog_message)
+{
+ git_buf tracking_head_name = GIT_BUF_INIT;
+ git_reference *remote_head = NULL;
+ int error;
+
+ if ((error = git_buf_printf(&tracking_head_name,
+ "%s%s/%s",
+ GIT_REFS_REMOTES_DIR,
+ remote_name,
+ GIT_HEAD_FILE)) < 0)
+ goto cleanup;
+
+ error = git_reference_symbolic_create(
+ &remote_head,
+ repo,
+ git_buf_cstr(&tracking_head_name),
+ tracking_branch_name,
+ true,
+ reflog_message);
+
+cleanup:
+ git_reference_free(remote_head);
+ git_buf_dispose(&tracking_head_name);
+ return error;
+}
+
static int update_remote_head(
git_repository *repo,
git_remote *remote,
@@ -169,9 +200,7 @@ static int update_remote_head(
const char *reflog_message)
{
git_refspec *refspec;
- git_reference *remote_head = NULL;
- git_buf remote_head_name = GIT_BUF_INIT;
- git_buf remote_branch_name = GIT_BUF_INIT;
+ git_buf tracking_branch_name = GIT_BUF_INIT;
int error;
/* Determine the remote tracking ref name from the local branch */
@@ -184,30 +213,19 @@ static int update_remote_head(
}
if ((error = git_refspec_transform(
- &remote_branch_name,
+ &tracking_branch_name,
refspec,
git_buf_cstr(target))) < 0)
goto cleanup;
- if ((error = git_buf_printf(&remote_head_name,
- "%s%s/%s",
- GIT_REFS_REMOTES_DIR,
- git_remote_name(remote),
- GIT_HEAD_FILE)) < 0)
- goto cleanup;
-
- error = git_reference_symbolic_create(
- &remote_head,
+ error = update_remote_head_byname(
repo,
- git_buf_cstr(&remote_head_name),
- git_buf_cstr(&remote_branch_name),
- true,
+ git_remote_name(remote),
+ git_buf_cstr(&tracking_branch_name),
reflog_message);
cleanup:
- git_reference_free(remote_head);
- git_buf_dispose(&remote_branch_name);
- git_buf_dispose(&remote_head_name);
+ git_buf_dispose(&tracking_branch_name);
return error;
}
@@ -277,8 +295,11 @@ static int update_head_to_branch(
if ((retcode = git_reference_lookup(&remote_ref, repo, git_buf_cstr(&remote_branch_name))) < 0)
goto cleanup;
- retcode = update_head_to_new_branch(repo, git_reference_target(remote_ref), branch,
- reflog_message);
+ if ((retcode = update_head_to_new_branch(repo, git_reference_target(remote_ref), branch,
+ reflog_message)) < 0)
+ goto cleanup;
+
+ retcode = update_remote_head_byname(repo, remote_name, remote_branch_name.ptr, reflog_message);
cleanup:
git_reference_free(remote_ref);
diff --git a/tests/clone/nonetwork.c b/tests/clone/nonetwork.c
index 7ca49085c..d4da3d3af 100644
--- a/tests/clone/nonetwork.c
+++ b/tests/clone/nonetwork.c
@@ -158,6 +158,8 @@ void test_clone_nonetwork__can_prevent_the_checkout_of_a_standard_repo(void)
void test_clone_nonetwork__can_checkout_given_branch(void)
{
+ git_reference *remote_head;
+
g_options.checkout_branch = "test";
cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
@@ -167,6 +169,12 @@ void test_clone_nonetwork__can_checkout_given_branch(void)
cl_assert_equal_s(git_reference_name(g_ref), "refs/heads/test");
cl_assert(git_path_exists("foo/readme.txt"));
+
+ cl_git_pass(git_reference_lookup(&remote_head, g_repo, "refs/remotes/origin/HEAD"));
+ cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(remote_head));
+ cl_assert_equal_s("refs/remotes/origin/test", git_reference_symbolic_target(remote_head));
+
+ git_reference_free(remote_head);
}
static int clone_cancel_fetch_transfer_progress_cb(