Commit 4d968f134b8ccd20e5a5b26ee160372076c55f5c

nulltoken 2012-10-15T06:12:57

clone: Explicit support of no-checkout option

diff --git a/include/git2/clone.h b/include/git2/clone.h
index 40292ed..c4dfc65 100644
--- a/include/git2/clone.h
+++ b/include/git2/clone.h
@@ -29,9 +29,12 @@ GIT_BEGIN_DECL
  * @param out pointer that will receive the resulting repository object
  * @param origin_url repository to clone from
  * @param workdir_path local directory to clone to
- * @param fetch_stats pointer to structure that receives fetch progress information (may be NULL)
- * @param checkout_opts options for the checkout step (may be NULL)
- * @return 0 on success, GIT_ERROR otherwise (use giterr_last for information about the error)
+ * @param fetch_stats pointer to structure that receives fetch progress
+ * information (may be NULL)
+ * @param checkout_opts options for the checkout step. If NULL, no checkout
+ * is performed
+ * @return 0 on success, GIT_ERROR otherwise (use giterr_last for information
+ * about the error)
  */
 GIT_EXTERN(int) git_clone(git_repository **out,
 								  const char *origin_url,
diff --git a/src/clone.c b/src/clone.c
index 00e39d3..7193166 100644
--- a/src/clone.c
+++ b/src/clone.c
@@ -290,6 +290,19 @@ static bool path_is_okay(const char *path)
 	return true;
 }
 
+static bool should_checkout(
+	git_repository *repo,
+	bool is_bare,
+	git_checkout_opts *opts)
+{
+	if (is_bare)
+		return false;
+
+	if (!opts)
+		return false;
+
+	return !git_repository_head_orphan(repo);
+}
 
 static int clone_internal(
 	git_repository **out,
@@ -298,7 +311,7 @@ static int clone_internal(
 	git_indexer_stats *fetch_stats,
 	git_indexer_stats *checkout_stats,
 	git_checkout_opts *checkout_opts,
-	int is_bare)
+	bool is_bare)
 {
 	int retcode = GIT_ERROR;
 	git_repository *repo = NULL;
@@ -321,7 +334,7 @@ static int clone_internal(
 		}
 	}
 
-	if (!retcode && !is_bare && !git_repository_head_orphan(repo))
+	if (!retcode && should_checkout(repo, is_bare, checkout_opts))
 		retcode = git_checkout_head(*out, checkout_opts, checkout_stats);
 
 	return retcode;
diff --git a/tests-clar/clone/network.c b/tests-clar/clone/network.c
index cf3c73b..af1eca1 100644
--- a/tests-clar/clone/network.c
+++ b/tests-clar/clone/network.c
@@ -72,3 +72,31 @@ void test_clone_network__empty_repository(void)
 
 	git_reference_free(head);
 }
+
+void test_clone_network__can_prevent_the_checkout_of_a_standard_repo(void)
+{
+	git_buf path = GIT_BUF_INIT;
+
+	cl_set_cleanup(&cleanup_repository, "./no-checkout");
+
+	cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./no-checkout", NULL, NULL, NULL));
+
+	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "master.txt"));
+	cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&path)));
+}
+
+void test_clone_network__can_checkout_a_cloned_repo(void)
+{
+	git_checkout_opts opts;
+	git_buf path = GIT_BUF_INIT;
+
+	memset(&opts, 0, sizeof(opts));
+	opts.checkout_strategy = GIT_CHECKOUT_CREATE_MISSING;
+
+	cl_set_cleanup(&cleanup_repository, "./default-checkout");
+
+	cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./default-checkout", NULL, NULL, &opts));
+
+	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "master.txt"));
+	cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&path)));
+}