summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2020-10-11 11:32:04 +0100
committerGitHub <noreply@github.com>2020-10-11 11:32:04 +0100
commit94e345826e849d48d0225418dd969cf0e18e34c5 (patch)
treef0a8c79c760090dab3a580aab9adc028865da956
parent6244791aa38bad967d8eddd777aa55d60f4b1a37 (diff)
parentc1f1bcad4d97bc5df3110bbcc5023a57744d4037 (diff)
downloadlibgit2-94e345826e849d48d0225418dd969cf0e18e34c5.tar.gz
Merge pull request #5651 from libgit2/ethomson/clone_branch
clone: update origin's HEAD
-rw-r--r--src/clone.c66
-rw-r--r--tests/online/clone.c7
2 files changed, 56 insertions, 17 deletions
diff --git a/src/clone.c b/src/clone.c
index a662a7652..a93ec475f 100644
--- a/src/clone.c
+++ b/src/clone.c
@@ -162,6 +162,55 @@ done:
return error;
}
+static int update_remote_head(
+ git_repository *repo,
+ git_remote *remote,
+ git_buf *target,
+ 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;
+ int error;
+
+ /* Determine the remote tracking ref name from the local branch */
+ refspec = git_remote__matching_refspec(remote, git_buf_cstr(target));
+
+ if (refspec == NULL) {
+ git_error_set(GIT_ERROR_NET, "the remote's default branch does not fit the refspec configuration");
+ error = GIT_EINVALIDSPEC;
+ goto cleanup;
+ }
+
+ if ((error = git_refspec_transform(
+ &remote_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,
+ repo,
+ git_buf_cstr(&remote_head_name),
+ git_buf_cstr(&remote_branch_name),
+ true,
+ reflog_message);
+
+cleanup:
+ git_reference_free(remote_head);
+ git_buf_dispose(&remote_branch_name);
+ git_buf_dispose(&remote_head_name);
+ return error;
+}
+
static int update_head_to_remote(
git_repository *repo,
git_remote *remote,
@@ -169,10 +218,8 @@ static int update_head_to_remote(
{
int error = 0;
size_t refs_len;
- git_refspec *refspec;
const git_remote_head *remote_head, **refs;
const git_oid *remote_head_id;
- git_buf remote_branch_name = GIT_BUF_INIT;
git_buf branch = GIT_BUF_INIT;
if ((error = git_remote_ls(&refs, &refs_len, remote)) < 0)
@@ -195,19 +242,7 @@ static int update_head_to_remote(
goto cleanup;
}
- refspec = git_remote__matching_refspec(remote, git_buf_cstr(&branch));
-
- if (refspec == NULL) {
- git_error_set(GIT_ERROR_NET, "the remote's default branch does not fit the refspec configuration");
- error = GIT_EINVALIDSPEC;
- goto cleanup;
- }
-
- /* Determine the remote tracking ref name from the local branch */
- if ((error = git_refspec_transform(
- &remote_branch_name,
- refspec,
- git_buf_cstr(&branch))) < 0)
+ if ((error = update_remote_head(repo, remote, &branch, reflog_message)) < 0)
goto cleanup;
error = update_head_to_new_branch(
@@ -217,7 +252,6 @@ static int update_head_to_remote(
reflog_message);
cleanup:
- git_buf_dispose(&remote_branch_name);
git_buf_dispose(&branch);
return error;
diff --git a/tests/online/clone.c b/tests/online/clone.c
index 9107956bd..c62baac2d 100644
--- a/tests/online/clone.c
+++ b/tests/online/clone.c
@@ -176,7 +176,7 @@ static int fetch_progress(const git_indexer_progress *stats, void *payload)
void test_online_clone__can_checkout_a_cloned_repo(void)
{
git_buf path = GIT_BUF_INIT;
- git_reference *head;
+ git_reference *head, *remote_head;
bool checkout_progress_cb_was_called = false,
fetch_progress_cb_was_called = false;
@@ -195,9 +195,14 @@ void test_online_clone__can_checkout_a_cloned_repo(void)
cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(head));
cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head));
+ 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/master", git_reference_symbolic_target(remote_head));
+
cl_assert_equal_i(true, checkout_progress_cb_was_called);
cl_assert_equal_i(true, fetch_progress_cb_was_called);
+ git_reference_free(remote_head);
git_reference_free(head);
git_buf_dispose(&path);
}