Commit d365029406087471fda7cbf7bda68e8453200494

Etienne Samson 2018-06-20T02:27:14

remote: add a flag to prevent generation of the default fetchspec

diff --git a/include/git2/remote.h b/include/git2/remote.h
index 7962f07..3e8292f 100644
--- a/include/git2/remote.h
+++ b/include/git2/remote.h
@@ -47,6 +47,9 @@ GIT_EXTERN(int) git_remote_create(
 typedef enum {
 	/** Ignore the repository apply.insteadOf configuration */
 	GIT_REMOTE_CREATE_SKIP_INSTEADOF = (1 << 0),
+
+	/** Don't build a fetchspec from the name if none is set */
+	GIT_REMOTE_CREATE_SKIP_DEFAULT_FETCHSPEC = (1 << 1),
 } git_remote_create_flags;
 
 /**
diff --git a/src/remote.c b/src/remote.c
index 9dcd2fe..ac79ad7 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -230,6 +230,7 @@ static int create_internal(git_remote **out, const char *url, const git_remote_c
 	git_config *config_ro = NULL, *config_rw;
 	git_buf canonical_url = GIT_BUF_INIT;
 	git_buf var = GIT_BUF_INIT;
+	git_buf specbuf = GIT_BUF_INIT;
 	const git_remote_create_options dummy_opts = GIT_REMOTE_CREATE_OPTIONS_INIT;
 	int error = -1;
 
@@ -282,13 +283,24 @@ static int create_internal(git_remote **out, const char *url, const git_remote_c
 			goto on_error;
 	}
 
-	if (opts->fetchspec != NULL) {
-		if ((error = add_refspec(remote, opts->fetchspec, true)) < 0)
+	if (opts->fetchspec != NULL ||
+	    (opts->name && !(opts->flags & GIT_REMOTE_CREATE_SKIP_DEFAULT_FETCHSPEC))) {
+		const char *fetch = NULL;
+		if (opts->fetchspec) {
+			fetch = opts->fetchspec;
+		} else {
+			if ((error = default_fetchspec_for_name(&specbuf, opts->name)) < 0)
+				goto on_error;
+
+			fetch = git_buf_cstr(&specbuf);
+		}
+
+		if ((error = add_refspec(remote, fetch, true)) < 0)
 			goto on_error;
 
 		/* only write for named remotes with a repository */
 		if (opts->repository && opts->name &&
-		    ((error = write_add_refspec(opts->repository, opts->name, opts->fetchspec, true)) < 0 ||
+		    ((error = write_add_refspec(opts->repository, opts->name, fetch, true)) < 0 ||
 		    (error = lookup_remote_prune_config(remote, config_ro, opts->name)) < 0))
 			goto on_error;
 
@@ -314,6 +326,7 @@ on_error:
 		git_remote_free(remote);
 
 	git_config_free(config_ro);
+	git_buf_dispose(&specbuf);
 	git_buf_dispose(&canonical_url);
 	git_buf_dispose(&var);
 	return error;
@@ -336,7 +349,6 @@ int git_remote_create(git_remote **out, git_repository *repo, const char *name, 
 
 	opts.repository = repo;
 	opts.name = name;
-	opts.fetchspec = git_buf_cstr(&buf);
 
 	error = create_internal(out, url, &opts);
 
@@ -361,6 +373,7 @@ int git_remote_create_with_fetchspec(git_remote **out, git_repository *repo, con
 	opts.repository = repo;
 	opts.name = name;
 	opts.fetchspec = fetch;
+	opts.flags = GIT_REMOTE_CREATE_SKIP_DEFAULT_FETCHSPEC;
 
 	return create_internal(out, url, &opts);
 }
diff --git a/tests/remote/create.c b/tests/remote/create.c
index 9c51ed6..4526af8 100644
--- a/tests/remote/create.c
+++ b/tests/remote/create.c
@@ -52,8 +52,6 @@ void test_remote_create__named(void)
 	git_config *cfg;
 	const char *cfg_val;
 
-	cl_skip(); // Later
-
 	size_t section_count = count_config_entries_match(_repo, "remote\\.");
 
 	cl_git_pass(git_remote_create(&remote, _repo, "valid-name", TEST_URL));
@@ -200,8 +198,6 @@ void test_remote_create__with_opts_named(void)
 	opts.name = "test-new";
 	opts.repository = _repo;
 
-	cl_skip(); // Later
-
 	cl_git_pass(git_remote_create_with_opts(&remote, TEST_URL, &opts));
 	cl_assert_equal_s(git_remote_name(remote), "test-new");
 	cl_assert_equal_s(git_remote_url(remote), TEST_URL);
@@ -246,7 +242,7 @@ void test_remote_create__with_opts_named_no_fetchspec(void)
 
 	opts.name = "test-new";
 	opts.repository = _repo;
-//	opts.flags = GIT_REMOTE_CREATE_SKIP_DEFAULT_FETCHSPEC; // Later
+	opts.flags = GIT_REMOTE_CREATE_SKIP_DEFAULT_FETCHSPEC;
 
 	cl_git_pass(git_remote_create_with_opts(&remote, TEST_URL, &opts));
 	cl_assert_equal_s(git_remote_name(remote), "test-new");