Implement analog for 'git checkout --branch xxx ...'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
diff --git a/include/git2/clone.h b/include/git2/clone.h
index e299c15..9bb92eb 100644
--- a/include/git2/clone.h
+++ b/include/git2/clone.h
@@ -57,6 +57,8 @@ GIT_BEGIN_DECL
* the origin remote before the fetch is initiated.
* - `remote_autotag` may be used to specify the autotag setting before the
* initial fetch.
+ * - `checkout_branch` gives the name of the branch to checkout. NULL means
+ * use the remote's HEAD.
*/
typedef struct git_clone_options {
@@ -76,6 +78,7 @@ typedef struct git_clone_options {
git_transport *transport;
git_remote_callbacks *remote_callbacks;
git_remote_autotag_option_t remote_autotag;
+ const char* checkout_branch;
} git_clone_options;
#define GIT_CLONE_OPTIONS_VERSION 1
diff --git a/src/clone.c b/src/clone.c
index 32ac08b..e9686dc 100644
--- a/src/clone.c
+++ b/src/clone.c
@@ -260,6 +260,31 @@ cleanup:
return retcode;
}
+static int update_head_to_branch(
+ git_repository *repo,
+ const git_clone_options *options)
+{
+ int retcode;
+ git_buf remote_branch_name = GIT_BUF_INIT;
+ git_reference* remote_ref = NULL;
+
+ assert(options->checkout_branch);
+
+ if ((retcode = git_buf_printf(&remote_branch_name, GIT_REFS_REMOTES_DIR "%s/%s",
+ options->remote_name, options->checkout_branch)) < 0 )
+ goto cleanup;
+
+ 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),
+ options->checkout_branch);
+
+cleanup:
+ git_reference_free(remote_ref);
+ return retcode;
+}
+
/*
* submodules?
*/
@@ -331,8 +356,13 @@ static int setup_remotes_and_fetch(
options->fetch_progress_payload)) {
/* Create "origin/foo" branches for all remote branches */
if (!git_remote_update_tips(origin)) {
+ /* Point HEAD to the requested branch */
+ if (options->checkout_branch) {
+ if (!update_head_to_branch(repo, options))
+ retcode = 0;
+ }
/* Point HEAD to the same ref as the remote's head */
- if (!update_head_to_remote(repo, origin)) {
+ else if (!update_head_to_remote(repo, origin)) {
retcode = 0;
}
}