Skip to content

Commit

Permalink
Merge pull request libgit2#5651 from libgit2/ethomson/clone_branch
Browse files Browse the repository at this point in the history
clone: update origin's HEAD
  • Loading branch information
ethomson authored Oct 11, 2020
2 parents 6244791 + c1f1bca commit 94e3458
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 17 deletions.
66 changes: 50 additions & 16 deletions src/clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,17 +162,64 @@ static int update_head_to_default(git_repository *repo)
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,
const char *reflog_message)
{
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)
Expand All @@ -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(
Expand All @@ -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;
Expand Down
7 changes: 6 additions & 1 deletion tests/online/clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);
}
Expand Down

0 comments on commit 94e3458

Please sign in to comment.