diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2020-10-11 11:32:04 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-11 11:32:04 +0100 |
commit | 94e345826e849d48d0225418dd969cf0e18e34c5 (patch) | |
tree | f0a8c79c760090dab3a580aab9adc028865da956 | |
parent | 6244791aa38bad967d8eddd777aa55d60f4b1a37 (diff) | |
parent | c1f1bcad4d97bc5df3110bbcc5023a57744d4037 (diff) | |
download | libgit2-94e345826e849d48d0225418dd969cf0e18e34c5.tar.gz |
Merge pull request #5651 from libgit2/ethomson/clone_branch
clone: update origin's HEAD
-rw-r--r-- | src/clone.c | 66 | ||||
-rw-r--r-- | tests/online/clone.c | 7 |
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); } |