Commit 621b50e4d55e98870b575b418a9b6fc8a024c65e

Ben Straub 2012-12-19T16:51:37

Clone: trust but verify

diff --git a/src/clone.c b/src/clone.c
index 9bbbe3d..7e3427b 100644
--- a/src/clone.c
+++ b/src/clone.c
@@ -295,6 +295,9 @@ static int create_and_configure_origin(
 	    (error = git_remote_set_pushurl(origin, options->pushurl)) < 0)
 		goto on_error;
 
+	if ((error = git_remote_save(origin)) < 0)
+		goto on_error;
+
 	*out = origin;
 	return 0;
 
diff --git a/tests-clar/clone/network.c b/tests-clar/clone/network.c
index c840939..154fbe8 100644
--- a/tests-clar/clone/network.c
+++ b/tests-clar/clone/network.c
@@ -142,3 +142,66 @@ void test_clone_network__can_checkout_a_cloned_repo(void)
 	git_reference_free(head);
 	git_buf_free(&path);
 }
+
+static int update_tips(const char *refname, const git_oid *a, const git_oid *b, void *payload)
+{
+	int *callcount = (int*)payload;
+	GIT_UNUSED(refname); GIT_UNUSED(a); GIT_UNUSED(b);
+	*callcount = *callcount + 1;
+	return 0;
+}
+
+void test_clone_network__custom_remote_callbacks(void)
+{
+	git_remote_callbacks remote_callbacks = GIT_REMOTE_CALLBACKS_INIT;
+	int callcount = 0;
+
+	cl_set_cleanup(&cleanup_repository, "./foo");
+
+	g_options.remote_callbacks = &remote_callbacks;
+	remote_callbacks.update_tips = update_tips;
+	remote_callbacks.payload = &callcount;
+
+	cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options));
+	cl_assert(callcount > 0);
+}
+
+struct cred_user_pass {
+	const char *user;
+	const char *pass;
+};
+
+static int cred_acquire(
+	git_cred **cred,
+	const char *url,
+	unsigned int allowed_types,
+	void *payload)
+{
+	struct cred_user_pass *user_pass = (struct cred_user_pass*)payload;
+
+	GIT_UNUSED(url);
+	if ((GIT_CREDTYPE_USERPASS_PLAINTEXT & allowed_types) == 0 ||
+			git_cred_userpass_plaintext_new(cred, user_pass->user, user_pass->pass) < 0)
+		return -1;
+
+	return 0;
+}
+
+void test_clone_network__credentials(void)
+{
+	/* Remote URL environment variable must be set.  User and password are optional.  */
+	const char *remote_url = cl_getenv("GITTEST_REMOTE_URL");
+	struct cred_user_pass user_pass = {
+		cl_getenv("GITTEST_REMOTE_USER"),
+		cl_getenv("GITTEST_REMOTE_PASS")
+	};
+
+	if (!remote_url) return;
+
+	cl_set_cleanup(&cleanup_repository, "./foo");
+
+	g_options.cred_acquire_cb = cred_acquire;
+	g_options.cred_acquire_payload = &user_pass;
+
+	cl_git_pass(git_clone(&g_repo, remote_url, "./foo", &g_options));
+}
diff --git a/tests-clar/clone/nonetwork.c b/tests-clar/clone/nonetwork.c
index 8cf4a46..982e089 100644
--- a/tests-clar/clone/nonetwork.c
+++ b/tests-clar/clone/nonetwork.c
@@ -74,3 +74,84 @@ void test_clone_nonetwork__fail_with_already_existing_but_non_empty_directory(vo
 	cl_git_mkfile("./foo/bar", "Baz!");
 	cl_git_fail(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
 }
+
+void test_clone_nonetwork__custom_origin_name(void)
+{
+	git_remote *remote;
+
+	cl_set_cleanup(&cleanup_repository, "./foo");
+	g_options.remote_name = "my_origin";
+	cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
+
+	cl_git_pass(git_remote_load(&remote, g_repo, "my_origin"));
+
+	git_remote_free(remote);
+}
+
+void test_clone_nonetwork__custom_push_url(void)
+{
+	git_remote *remote;
+	const char *url = "http://example.com";
+
+	cl_set_cleanup(&cleanup_repository, "./foo");
+	g_options.pushurl = url;
+	cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
+
+	cl_git_pass(git_remote_load(&remote, g_repo, "origin"));
+	cl_assert_equal_s(url, git_remote_pushurl(remote));
+
+	git_remote_free(remote);
+}
+
+void test_clone_nonetwork__custom_fetch_spec(void)
+{
+	git_remote *remote;
+	git_reference *master;
+	const git_refspec *actual_fs;
+	const char *spec = "+refs/heads/master:refs/heads/foo";
+
+	cl_set_cleanup(&cleanup_repository, "./foo");
+	g_options.fetch_spec = spec;
+	cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
+
+	cl_git_pass(git_remote_load(&remote, g_repo, "origin"));
+	actual_fs = git_remote_fetchspec(remote);
+	cl_assert_equal_s("refs/heads/master", git_refspec_src(actual_fs));
+	cl_assert_equal_s("refs/heads/foo", git_refspec_dst(actual_fs));
+
+	cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/foo"));
+	git_reference_free(master);
+
+	git_remote_free(remote);
+}
+
+void test_clone_nonetwork__custom_push_spec(void)
+{
+	git_remote *remote;
+	const git_refspec *actual_fs;
+	const char *spec = "+refs/heads/master:refs/heads/foo";
+
+	cl_set_cleanup(&cleanup_repository, "./foo");
+	g_options.push_spec = spec;
+	cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
+
+	cl_git_pass(git_remote_load(&remote, g_repo, "origin"));
+	actual_fs = git_remote_pushspec(remote);
+	cl_assert_equal_s("refs/heads/master", git_refspec_src(actual_fs));
+	cl_assert_equal_s("refs/heads/foo", git_refspec_dst(actual_fs));
+
+	git_remote_free(remote);
+}
+
+void test_clone_nonetwork__custom_autotag(void)
+{
+	git_strarray tags = {0};
+
+	cl_set_cleanup(&cleanup_repository, "./foo");
+	g_options.remote_autotag = GIT_REMOTE_DOWNLOAD_TAGS_NONE;
+	cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options));
+
+	cl_git_pass(git_tag_list(&tags, g_repo));
+	cl_assert_equal_i(0, tags.count);
+}
+