Commit 86e5003d86b04c4a91db88fcd004e63b6a344792

Edward Thomson 2021-12-23T14:22:34

Merge branch 'pr/6062'

diff --git a/include/git2/worktree.h b/include/git2/worktree.h
index 85cf1a6..8691f96 100644
--- a/include/git2/worktree.h
+++ b/include/git2/worktree.h
@@ -86,10 +86,15 @@ typedef struct git_worktree_add_options {
 
 	int lock; /**< lock newly created worktree */
 	git_reference *ref; /**< reference to use for the new worktree HEAD */
+
+	/**
+	 * Options for the checkout.
+	 */
+	git_checkout_options checkout_options;
 } git_worktree_add_options;
 
 #define GIT_WORKTREE_ADD_OPTIONS_VERSION 1
-#define GIT_WORKTREE_ADD_OPTIONS_INIT {GIT_WORKTREE_ADD_OPTIONS_VERSION,0,NULL}
+#define GIT_WORKTREE_ADD_OPTIONS_INIT {GIT_WORKTREE_ADD_OPTIONS_VERSION,0,NULL,GIT_CHECKOUT_OPTIONS_INIT}
 
 /**
  * Initialize git_worktree_add_options structure
diff --git a/src/worktree.c b/src/worktree.c
index e08d6d4..2ac2274 100644
--- a/src/worktree.c
+++ b/src/worktree.c
@@ -304,16 +304,13 @@ int git_worktree_add(git_worktree **out, git_repository *repo,
 	git_reference *ref = NULL, *head = NULL;
 	git_commit *commit = NULL;
 	git_repository *wt = NULL;
-	git_checkout_options coopts = GIT_CHECKOUT_OPTIONS_INIT;
+	git_checkout_options coopts;
 	git_worktree_add_options wtopts = GIT_WORKTREE_ADD_OPTIONS_INIT;
 	int err;
 
 	GIT_ERROR_CHECK_VERSION(
 		opts, GIT_WORKTREE_ADD_OPTIONS_VERSION, "git_worktree_add_options");
 
-	if (opts)
-		memcpy(&wtopts, opts, sizeof(wtopts));
-
 	GIT_ASSERT_ARG(out);
 	GIT_ASSERT_ARG(repo);
 	GIT_ASSERT_ARG(name);
@@ -321,6 +318,11 @@ int git_worktree_add(git_worktree **out, git_repository *repo,
 
 	*out = NULL;
 
+	if (opts)
+		memcpy(&wtopts, opts, sizeof(wtopts));
+
+	memcpy(&coopts, &wtopts.checkout_options, sizeof(coopts));
+
 	if (wtopts.ref) {
 		if (!git_reference_is_branch(wtopts.ref)) {
 			git_error_set(GIT_ERROR_WORKTREE, "reference is not a branch");
@@ -405,7 +407,6 @@ int git_worktree_add(git_worktree **out, git_repository *repo,
 		goto out;
 
 	/* Checkout worktree's HEAD */
-	coopts.checkout_strategy = GIT_CHECKOUT_FORCE;
 	if ((err = git_checkout_head(wt, &coopts)) < 0)
 		goto out;
 
diff --git a/tests/worktree/worktree.c b/tests/worktree/worktree.c
index 6f14b17..66273d1 100644
--- a/tests/worktree/worktree.c
+++ b/tests/worktree/worktree.c
@@ -292,6 +292,28 @@ void test_worktree_worktree__add_with_explicit_branch(void)
 	git_worktree_free(wt);
 }
 
+void test_worktree_worktree__add_no_checkout(void)
+{
+	git_worktree *wt;
+	git_repository *wtrepo;
+	git_index *index;
+	git_str path = GIT_STR_INIT;
+	git_worktree_add_options opts = GIT_WORKTREE_ADD_OPTIONS_INIT;
+
+	opts.checkout_options.checkout_strategy = GIT_CHECKOUT_NONE;
+
+	cl_git_pass(git_str_joinpath(&path, fixture.repo->workdir, "../worktree-no-checkout"));
+	cl_git_pass(git_worktree_add(&wt, fixture.repo, "worktree-no-checkout", path.ptr, &opts));
+
+	cl_git_pass(git_repository_open(&wtrepo, path.ptr));
+	cl_git_pass(git_repository_index(&index, wtrepo));
+	cl_assert_equal_i(git_index_entrycount(index), 0);
+
+	git_str_dispose(&path);
+	git_worktree_free(wt);
+	git_index_free(index);
+	git_repository_free(wtrepo);
+}
 
 void test_worktree_worktree__init_existing_worktree(void)
 {