diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2021-01-07 17:34:17 +0000 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2021-01-07 17:34:17 +0000 |
commit | 923c0f7b763bf3d20f9cd8f02ab9b1d400c733ab (patch) | |
tree | d15b03e22d550c03811138f7ac2f023e45c1718c | |
parent | c31032a3cf449b77c1ca2a966ec3ca31f2f1fb00 (diff) | |
download | libgit2-923c0f7b763bf3d20f9cd8f02ab9b1d400c733ab.tar.gz |
clone: set refs/remotes/origin/HEAD when branch is specifiedethomson/clone_branch
When a branch is specified to check out in clone, update the remote
tracking `HEAD` to point to it. This mimics git's behavior, when
`git clone -b <name>` is used.
-rw-r--r-- | src/clone.c | 63 | ||||
-rw-r--r-- | tests/clone/nonetwork.c | 8 |
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( |