Initial commit

This commit is contained in:
jiapengyu
2026-07-27 13:37:48 +08:00
commit ecba71e2a5
39123 changed files with 5989154 additions and 0 deletions
+46
View File
@@ -0,0 +1,46 @@
#include "clar_libgit2.h"
#include "git2/cred_helpers.h"
void test_network_cred__stock_userpass_validates_args(void)
{
git_cred_userpass_payload payload = {0};
cl_git_fail(git_cred_userpass(NULL, NULL, NULL, 0, NULL));
payload.username = "user";
cl_git_fail(git_cred_userpass(NULL, NULL, NULL, 0, &payload));
payload.username = NULL;
payload.username = "pass";
cl_git_fail(git_cred_userpass(NULL, NULL, NULL, 0, &payload));
}
void test_network_cred__stock_userpass_validates_that_method_is_allowed(void)
{
git_cred *cred;
git_cred_userpass_payload payload = {"user", "pass"};
cl_git_fail(git_cred_userpass(&cred, NULL, NULL, 0, &payload));
cl_git_pass(git_cred_userpass(&cred, NULL, NULL, GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload));
git_cred_free(cred);
}
void test_network_cred__stock_userpass_properly_handles_username_in_url(void)
{
git_cred *cred;
git_cred_userpass_payload payload = {"alice", "password"};
cl_git_pass(git_cred_userpass(&cred, NULL, NULL, GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload));
cl_assert_equal_s("alice", git_cred_get_username(cred));
git_cred_free(cred);
cl_git_pass(git_cred_userpass(&cred, NULL, "bob", GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload));
cl_assert_equal_s("alice", git_cred_get_username(cred));
git_cred_free(cred);
payload.username = NULL;
cl_git_pass(git_cred_userpass(&cred, NULL, "bob", GIT_CREDTYPE_USERPASS_PLAINTEXT, &payload));
cl_assert_equal_s("bob", git_cred_get_username(cred));
git_cred_free(cred);
}
+512
View File
@@ -0,0 +1,512 @@
#include "clar_libgit2.h"
#include "buffer.h"
#include "path.h"
#include "remote.h"
static const char* tagger_name = "Vicent Marti";
static const char* tagger_email = "vicent@github.com";
static const char* tagger_message = "This is my tag.\n\nThere are many tags, but this one is mine\n";
static int transfer_cb(const git_indexer_progress *stats, void *payload)
{
int *callcount = (int*)payload;
GIT_UNUSED(stats);
(*callcount)++;
return 0;
}
static void cleanup_local_repo(void *path)
{
cl_fixture_cleanup((char *)path);
}
void test_network_fetchlocal__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_network_fetchlocal__complete(void)
{
git_repository *repo;
git_remote *origin;
int callcount = 0;
git_strarray refnames = {0};
const char *url = cl_git_fixture_url("testrepo.git");
git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
options.callbacks.transfer_progress = transfer_cb;
options.callbacks.payload = &callcount;
cl_set_cleanup(&cleanup_local_repo, "foo");
cl_git_pass(git_repository_init(&repo, "foo", true));
cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(19, (int)refnames.count);
cl_assert(callcount > 0);
git_strarray_free(&refnames);
git_remote_free(origin);
git_repository_free(repo);
}
void test_network_fetchlocal__prune(void)
{
git_repository *repo;
git_remote *origin;
int callcount = 0;
git_strarray refnames = {0};
git_reference *ref;
git_repository *remote_repo = cl_git_sandbox_init("testrepo.git");
const char *url = cl_git_path_url(git_repository_path(remote_repo));
git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
options.callbacks.transfer_progress = transfer_cb;
options.callbacks.payload = &callcount;
cl_set_cleanup(&cleanup_local_repo, "foo");
cl_git_pass(git_repository_init(&repo, "foo", true));
cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(19, (int)refnames.count);
cl_assert(callcount > 0);
git_strarray_free(&refnames);
git_remote_free(origin);
cl_git_pass(git_reference_lookup(&ref, remote_repo, "refs/heads/br2"));
cl_git_pass(git_reference_delete(ref));
git_reference_free(ref);
cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN));
cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
cl_git_pass(git_remote_prune(origin, &options.callbacks));
cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(18, (int)refnames.count);
git_strarray_free(&refnames);
git_remote_free(origin);
cl_git_pass(git_reference_lookup(&ref, remote_repo, "refs/heads/packed"));
cl_git_pass(git_reference_delete(ref));
git_reference_free(ref);
cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN));
cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
cl_git_pass(git_remote_prune(origin, &options.callbacks));
cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(17, (int)refnames.count);
git_strarray_free(&refnames);
git_remote_free(origin);
git_repository_free(repo);
}
int update_tips_fail_on_call(const char *ref, const git_oid *old, const git_oid *new, void *data)
{
GIT_UNUSED(ref);
GIT_UNUSED(old);
GIT_UNUSED(new);
GIT_UNUSED(data);
cl_fail("update tips called");
return 0;
}
void assert_ref_exists(git_repository *repo, const char *name)
{
git_reference *ref;
cl_git_pass(git_reference_lookup(&ref, repo, name));
git_reference_free(ref);
}
void test_network_fetchlocal__prune_overlapping(void)
{
git_repository *repo;
git_remote *origin;
int callcount = 0;
git_strarray refnames = {0};
git_reference *ref;
git_config *config;
git_oid target;
git_repository *remote_repo = cl_git_sandbox_init("testrepo.git");
const char *url = cl_git_path_url(git_repository_path(remote_repo));
git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
options.callbacks.transfer_progress = transfer_cb;
options.callbacks.payload = &callcount;
cl_git_pass(git_reference_lookup(&ref, remote_repo, "refs/heads/master"));
git_oid_cpy(&target, git_reference_target(ref));
git_reference_free(ref);
cl_git_pass(git_reference_create(&ref, remote_repo, "refs/pull/42/head", &target, 1, NULL));
git_reference_free(ref);
cl_set_cleanup(&cleanup_local_repo, "foo");
cl_git_pass(git_repository_init(&repo, "foo", true));
cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
cl_git_pass(git_repository_config(&config, repo));
cl_git_pass(git_config_set_bool(config, "remote.origin.prune", true));
cl_git_pass(git_config_set_multivar(config, "remote.origin.fetch", "^$", "refs/pull/*/head:refs/remotes/origin/pr/*"));
git_remote_free(origin);
cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN));
cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
assert_ref_exists(repo, "refs/remotes/origin/master");
assert_ref_exists(repo, "refs/remotes/origin/pr/42");
cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(20, (int)refnames.count);
git_strarray_free(&refnames);
cl_git_pass(git_config_delete_multivar(config, "remote.origin.fetch", "refs"));
cl_git_pass(git_config_set_multivar(config, "remote.origin.fetch", "^$", "refs/pull/*/head:refs/remotes/origin/pr/*"));
cl_git_pass(git_config_set_multivar(config, "remote.origin.fetch", "^$", "refs/heads/*:refs/remotes/origin/*"));
git_remote_free(origin);
cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN));
options.callbacks.update_tips = update_tips_fail_on_call;
cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
assert_ref_exists(repo, "refs/remotes/origin/master");
assert_ref_exists(repo, "refs/remotes/origin/pr/42");
cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(20, (int)refnames.count);
git_strarray_free(&refnames);
cl_git_pass(git_config_delete_multivar(config, "remote.origin.fetch", "refs"));
cl_git_pass(git_config_set_multivar(config, "remote.origin.fetch", "^$", "refs/heads/*:refs/remotes/origin/*"));
cl_git_pass(git_config_set_multivar(config, "remote.origin.fetch", "^$", "refs/pull/*/head:refs/remotes/origin/pr/*"));
git_remote_free(origin);
cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN));
options.callbacks.update_tips = update_tips_fail_on_call;
cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
git_config_free(config);
git_strarray_free(&refnames);
git_remote_free(origin);
git_repository_free(repo);
}
void test_network_fetchlocal__fetchprune(void)
{
git_repository *repo;
git_remote *origin;
int callcount = 0;
git_strarray refnames = {0};
git_reference *ref;
git_config *config;
git_repository *remote_repo = cl_git_sandbox_init("testrepo.git");
const char *url = cl_git_path_url(git_repository_path(remote_repo));
git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
options.callbacks.transfer_progress = transfer_cb;
options.callbacks.payload = &callcount;
cl_set_cleanup(&cleanup_local_repo, "foo");
cl_git_pass(git_repository_init(&repo, "foo", true));
cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(19, (int)refnames.count);
cl_assert(callcount > 0);
git_strarray_free(&refnames);
git_remote_free(origin);
cl_git_pass(git_reference_lookup(&ref, remote_repo, "refs/heads/br2"));
cl_git_pass(git_reference_delete(ref));
git_reference_free(ref);
cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN));
cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
cl_git_pass(git_remote_prune(origin, &options.callbacks));
cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(18, (int)refnames.count);
git_strarray_free(&refnames);
git_remote_free(origin);
cl_git_pass(git_reference_lookup(&ref, remote_repo, "refs/heads/packed"));
cl_git_pass(git_reference_delete(ref));
git_reference_free(ref);
cl_git_pass(git_repository_config(&config, repo));
cl_git_pass(git_config_set_bool(config, "remote.origin.prune", 1));
git_config_free(config);
cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN));
cl_assert_equal_i(1, git_remote_prune_refs(origin));
cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(17, (int)refnames.count);
git_strarray_free(&refnames);
git_remote_free(origin);
git_repository_free(repo);
}
void test_network_fetchlocal__prune_tag(void)
{
git_repository *repo;
git_remote *origin;
int callcount = 0;
git_reference *ref;
git_config *config;
git_oid tag_id;
git_signature *tagger;
git_object *obj;
git_repository *remote_repo = cl_git_sandbox_init("testrepo.git");
const char *url = cl_git_path_url(git_repository_path(remote_repo));
git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
options.callbacks.transfer_progress = transfer_cb;
options.callbacks.payload = &callcount;
cl_set_cleanup(&cleanup_local_repo, "foo");
cl_git_pass(git_repository_init(&repo, "foo", true));
cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
git_remote_free(origin);
cl_git_pass(git_revparse_single(&obj, repo, "origin/master"));
cl_git_pass(git_reference_create(&ref, repo, "refs/remotes/origin/fake-remote", git_object_id(obj), 1, NULL));
git_reference_free(ref);
/* create signature */
cl_git_pass(git_signature_new(&tagger, tagger_name, tagger_email, 123456789, 60));
cl_git_pass(
git_tag_create(&tag_id, repo,
"some-tag", obj, tagger, tagger_message, 0)
);
git_signature_free(tagger);
cl_git_pass(git_repository_config(&config, repo));
cl_git_pass(git_config_set_bool(config, "remote.origin.prune", 1));
git_config_free(config);
cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN));
cl_assert_equal_i(1, git_remote_prune_refs(origin));
cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
assert_ref_exists(repo, "refs/tags/some-tag");
cl_git_fail_with(GIT_ENOTFOUND, git_reference_lookup(&ref, repo, "refs/remotes/origin/fake-remote"));
git_object_free(obj);
git_remote_free(origin);
git_repository_free(repo);
}
void test_network_fetchlocal__partial(void)
{
git_repository *repo = cl_git_sandbox_init("partial-testrepo");
git_remote *origin;
int callcount = 0;
git_strarray refnames = {0};
const char *url;
git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
options.callbacks.transfer_progress = transfer_cb;
options.callbacks.payload = &callcount;
cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(1, (int)refnames.count);
url = cl_git_fixture_url("testrepo.git");
cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
git_strarray_free(&refnames);
cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(20, (int)refnames.count); /* 18 remote + 1 local */
cl_assert(callcount > 0);
git_strarray_free(&refnames);
git_remote_free(origin);
}
static int remote_mirror_cb(git_remote **out, git_repository *repo,
const char *name, const char *url, void *payload)
{
int error;
git_remote *remote;
GIT_UNUSED(payload);
if ((error = git_remote_create_with_fetchspec(&remote, repo, name, url, "+refs/*:refs/*")) < 0)
return error;
*out = remote;
return 0;
}
void test_network_fetchlocal__clone_into_mirror(void)
{
git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
git_repository *repo;
git_reference *ref;
opts.bare = true;
opts.remote_cb = remote_mirror_cb;
cl_git_pass(git_clone(&repo, cl_git_fixture_url("testrepo.git"), "./foo.git", &opts));
cl_git_pass(git_reference_lookup(&ref, repo, "HEAD"));
cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(ref));
cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(ref));
git_reference_free(ref);
cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/test/master"));
git_reference_free(ref);
git_repository_free(repo);
cl_fixture_cleanup("./foo.git");
}
void test_network_fetchlocal__all_refs(void)
{
git_repository *repo;
git_remote *remote;
git_reference *ref;
char *allrefs = "+refs/*:refs/*";
git_strarray refspecs = {
&allrefs,
1,
};
cl_git_pass(git_repository_init(&repo, "./foo.git", true));
cl_git_pass(git_remote_create_anonymous(&remote, repo, cl_git_fixture_url("testrepo.git")));
cl_git_pass(git_remote_fetch(remote, &refspecs, NULL, NULL));
cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/test/master"));
git_reference_free(ref);
cl_git_pass(git_reference_lookup(&ref, repo, "refs/tags/test"));
git_reference_free(ref);
git_remote_free(remote);
git_repository_free(repo);
cl_fixture_cleanup("./foo.git");
}
void test_network_fetchlocal__multi_remotes(void)
{
git_repository *repo = cl_git_sandbox_init("testrepo.git");
git_remote *test, *test2;
git_strarray refnames = {0};
git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
options.callbacks.transfer_progress = transfer_cb;
cl_git_pass(git_remote_set_url(repo, "test", cl_git_fixture_url("testrepo.git")));
cl_git_pass(git_remote_lookup(&test, repo, "test"));
cl_git_pass(git_remote_fetch(test, NULL, &options, NULL));
cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(33, (int)refnames.count);
git_strarray_free(&refnames);
cl_git_pass(git_remote_set_url(repo, "test_with_pushurl", cl_git_fixture_url("testrepo.git")));
cl_git_pass(git_remote_lookup(&test2, repo, "test_with_pushurl"));
cl_git_pass(git_remote_fetch(test2, NULL, &options, NULL));
cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(45, (int)refnames.count);
git_strarray_free(&refnames);
git_remote_free(test);
git_remote_free(test2);
}
static int sideband_cb(const char *str, int len, void *payload)
{
int *count = (int *) payload;
GIT_UNUSED(str);
GIT_UNUSED(len);
(*count)++;
return 0;
}
void test_network_fetchlocal__call_progress(void)
{
git_repository *repo;
git_remote *remote;
git_fetch_options options = GIT_FETCH_OPTIONS_INIT;
int callcount = 0;
cl_git_pass(git_repository_init(&repo, "foo.git", true));
cl_set_cleanup(cleanup_local_repo, "foo.git");
cl_git_pass(git_remote_create_with_fetchspec(&remote, repo, "origin", cl_git_fixture_url("testrepo.git"), "+refs/heads/*:refs/heads/*"));
options.callbacks.sideband_progress = sideband_cb;
options.callbacks.payload = &callcount;
cl_git_pass(git_remote_fetch(remote, NULL, &options, NULL));
cl_assert(callcount != 0);
git_remote_free(remote);
git_repository_free(repo);
}
void test_network_fetchlocal__prune_load_remote_prune_config(void)
{
git_repository *repo;
git_remote *origin;
git_config *config;
git_repository *remote_repo = cl_git_sandbox_init("testrepo.git");
const char *url = cl_git_path_url(git_repository_path(remote_repo));
cl_set_cleanup(&cleanup_local_repo, "foo");
cl_git_pass(git_repository_init(&repo, "foo", true));
cl_git_pass(git_repository_config(&config, repo));
cl_git_pass(git_config_set_bool(config, "remote.origin.prune", 1));
cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
cl_assert_equal_i(1, git_remote_prune_refs(origin));
git_config_free(config);
git_remote_free(origin);
git_repository_free(repo);
}
void test_network_fetchlocal__prune_load_fetch_prune_config(void)
{
git_repository *repo;
git_remote *origin;
git_config *config;
git_repository *remote_repo = cl_git_sandbox_init("testrepo.git");
const char *url = cl_git_path_url(git_repository_path(remote_repo));
cl_set_cleanup(&cleanup_local_repo, "foo");
cl_git_pass(git_repository_init(&repo, "foo", true));
cl_git_pass(git_repository_config(&config, repo));
cl_git_pass(git_config_set_bool(config, "fetch.prune", 1));
cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
cl_assert_equal_i(1, git_remote_prune_refs(origin));
git_config_free(config);
git_remote_free(origin);
git_repository_free(repo);
}
+13
View File
@@ -0,0 +1,13 @@
#include "clar_libgit2.h"
#include "netops.h"
void test_network_matchhost__match(void)
{
cl_git_pass(gitno__match_host("*.example.org", "www.example.org"));
cl_git_pass(gitno__match_host("*.foo.example.org", "www.foo.example.org"));
cl_git_fail(gitno__match_host("*.foo.example.org", "foo.example.org"));
cl_git_fail(gitno__match_host("*.foo.example.org", "www.example.org"));
cl_git_fail(gitno__match_host("*.example.org", "example.org"));
cl_git_fail(gitno__match_host("*.example.org", "www.foo.example.org"));
cl_git_fail(gitno__match_host("*.example.org", "blah.www.www.example.org"));
}
+129
View File
@@ -0,0 +1,129 @@
#include "clar_libgit2.h"
#include "net.h"
#include "netops.h"
static git_net_url conndata;
void test_network_redirect__initialize(void)
{
memset(&conndata, 0, sizeof(conndata));
}
void test_network_redirect__cleanup(void)
{
git_net_url_dispose(&conndata);
}
void test_network_redirect__redirect_http(void)
{
cl_git_pass(git_net_url_parse(&conndata,
"http://example.com/foo/bar/baz"));
cl_git_pass(gitno_connection_data_handle_redirect(&conndata,
"http://example.com/foo/bar/baz", "bar/baz"));
cl_assert_equal_s(conndata.scheme, "http");
cl_assert_equal_s(conndata.host, "example.com");
cl_assert_equal_s(conndata.port, "80");
cl_assert_equal_s(conndata.path, "/foo/");
cl_assert_equal_p(conndata.username, NULL);
cl_assert_equal_p(conndata.password, NULL);
}
void test_network_redirect__redirect_ssl(void)
{
cl_git_pass(git_net_url_parse(&conndata,
"https://example.com/foo/bar/baz"));
cl_git_pass(gitno_connection_data_handle_redirect(&conndata,
"https://example.com/foo/bar/baz", "bar/baz"));
cl_assert_equal_s(conndata.scheme, "https");
cl_assert_equal_s(conndata.host, "example.com");
cl_assert_equal_s(conndata.port, "443");
cl_assert_equal_s(conndata.path, "/foo/");
cl_assert_equal_p(conndata.username, NULL);
cl_assert_equal_p(conndata.password, NULL);
}
void test_network_redirect__redirect_leaves_root_path(void)
{
cl_git_pass(git_net_url_parse(&conndata,
"https://example.com/foo/bar/baz"));
cl_git_pass(gitno_connection_data_handle_redirect(&conndata,
"https://example.com/foo/bar/baz", "/foo/bar/baz"));
cl_assert_equal_s(conndata.scheme, "https");
cl_assert_equal_s(conndata.host, "example.com");
cl_assert_equal_s(conndata.port, "443");
cl_assert_equal_s(conndata.path, "/");
cl_assert_equal_p(conndata.username, NULL);
cl_assert_equal_p(conndata.password, NULL);
}
void test_network_redirect__redirect_encoded_username_password(void)
{
cl_git_pass(git_net_url_parse(&conndata,
"https://user%2fname:pass%40word%zyx%v@example.com/foo/bar/baz"));
cl_git_pass(gitno_connection_data_handle_redirect(&conndata,
"https://user%2fname:pass%40word%zyx%v@example.com/foo/bar/baz", "bar/baz"));
cl_assert_equal_s(conndata.scheme, "https");
cl_assert_equal_s(conndata.host, "example.com");
cl_assert_equal_s(conndata.port, "443");
cl_assert_equal_s(conndata.path, "/foo/");
cl_assert_equal_s(conndata.username, "user/name");
cl_assert_equal_s(conndata.password, "pass@word%zyx%v");
}
void test_network_redirect__redirect_cross_host_denied(void)
{
cl_git_pass(git_net_url_parse(&conndata, "https://bar.com/bar/baz"));
cl_git_fail_with(gitno_connection_data_handle_redirect(&conndata,
"https://foo.com/bar/baz", NULL),
-1);
}
void test_network_redirect__redirect_http_downgrade_denied(void)
{
cl_git_pass(git_net_url_parse(&conndata, "https://foo.com/bar/baz"));
cl_git_fail_with(gitno_connection_data_handle_redirect(&conndata,
"http://foo.com/bar/baz", NULL),
-1);
}
void test_network_redirect__redirect_relative(void)
{
cl_git_pass(git_net_url_parse(&conndata, "http://foo.com/bar/baz/biff"));
cl_git_pass(gitno_connection_data_handle_redirect(&conndata,
"/zap/baz/biff?bam", NULL));
cl_assert_equal_s(conndata.scheme, "http");
cl_assert_equal_s(conndata.host, "foo.com");
cl_assert_equal_s(conndata.port, "80");
cl_assert_equal_s(conndata.path, "/zap/baz/biff?bam");
cl_assert_equal_p(conndata.username, NULL);
cl_assert_equal_p(conndata.password, NULL);
}
void test_network_redirect__redirect_relative_ssl(void)
{
cl_git_pass(git_net_url_parse(&conndata, "https://foo.com/bar/baz/biff"));
cl_git_pass(gitno_connection_data_handle_redirect(&conndata,
"/zap/baz/biff?bam", NULL));
cl_assert_equal_s(conndata.scheme, "https");
cl_assert_equal_s(conndata.host, "foo.com");
cl_assert_equal_s(conndata.port, "443");
cl_assert_equal_s(conndata.path, "/zap/baz/biff?bam");
cl_assert_equal_p(conndata.username, NULL);
cl_assert_equal_p(conndata.password, NULL);
}
void test_network_redirect__service_query_no_query_params_in_location(void)
{
cl_git_pass(git_net_url_parse(&conndata, "https://foo.com/bar/info/refs?service=git-upload-pack"));
cl_git_pass(gitno_connection_data_handle_redirect(&conndata,
"/baz/info/refs", "/info/refs?service=git-upload-pack"));
cl_assert_equal_s(conndata.path, "/baz");
}
void test_network_redirect__service_query_with_query_params_in_location(void)
{
cl_git_pass(git_net_url_parse(&conndata, "https://foo.com/bar/info/refs?service=git-upload-pack"));
cl_git_pass(gitno_connection_data_handle_redirect(&conndata,
"/baz/info/refs?service=git-upload-pack", "/info/refs?service=git-upload-pack"));
cl_assert_equal_s(conndata.path, "/baz");
}
+191
View File
@@ -0,0 +1,191 @@
#include "clar_libgit2.h"
#include "refspec.h"
#include "remote.h"
static void assert_refspec(unsigned int direction, const char *input, bool is_expected_to_be_valid)
{
git_refspec refspec;
int error;
error = git_refspec__parse(&refspec, input, direction == GIT_DIRECTION_FETCH);
git_refspec__dispose(&refspec);
if (is_expected_to_be_valid)
cl_assert_equal_i(0, error);
else
cl_assert_equal_i(GIT_ERROR, error);
}
void test_network_refspecs__parsing(void)
{
/* Ported from https://github.com/git/git/blob/abd2bde78bd994166900290434a2048e660dabed/t/t5511-refspec.sh */
assert_refspec(GIT_DIRECTION_PUSH, "", false);
assert_refspec(GIT_DIRECTION_PUSH, ":", true);
assert_refspec(GIT_DIRECTION_PUSH, "::", false);
assert_refspec(GIT_DIRECTION_PUSH, "+:", true);
assert_refspec(GIT_DIRECTION_FETCH, "", true);
assert_refspec(GIT_DIRECTION_PUSH, ":", true);
assert_refspec(GIT_DIRECTION_FETCH, "::", false);
assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/*:refs/remotes/frotz/*", true);
assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/*:refs/remotes/frotz", false);
assert_refspec(GIT_DIRECTION_PUSH, "refs/heads:refs/remotes/frotz/*", false);
assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/master:refs/remotes/frotz/xyzzy", true);
/*
* These have invalid LHS, but we do not have a formal "valid sha-1
* expression syntax checker" so they are not checked with the current
* code. They will be caught downstream anyway, but we may want to
* have tighter check later...
*/
/*assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/master::refs/remotes/frotz/xyzzy", false); */
/*assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/maste :refs/remotes/frotz/xyzzy", false); */
assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/*:refs/remotes/frotz/*", true);
assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/*:refs/remotes/frotz", false);
assert_refspec(GIT_DIRECTION_FETCH, "refs/heads:refs/remotes/frotz/*", false);
assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/master:refs/remotes/frotz/xyzzy", true);
assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/master::refs/remotes/frotz/xyzzy", false);
assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/maste :refs/remotes/frotz/xyzzy", false);
assert_refspec(GIT_DIRECTION_PUSH, "master~1:refs/remotes/frotz/backup", true);
assert_refspec(GIT_DIRECTION_FETCH, "master~1:refs/remotes/frotz/backup", false);
assert_refspec(GIT_DIRECTION_PUSH, "HEAD~4:refs/remotes/frotz/new", true);
assert_refspec(GIT_DIRECTION_FETCH, "HEAD~4:refs/remotes/frotz/new", false);
assert_refspec(GIT_DIRECTION_PUSH, "HEAD", true);
assert_refspec(GIT_DIRECTION_FETCH, "HEAD", true);
assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/ nitfol", false);
assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/ nitfol", false);
assert_refspec(GIT_DIRECTION_PUSH, "HEAD:", false);
assert_refspec(GIT_DIRECTION_FETCH, "HEAD:", true);
assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/ nitfol:", false);
assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/ nitfol:", false);
assert_refspec(GIT_DIRECTION_PUSH, ":refs/remotes/frotz/deleteme", true);
assert_refspec(GIT_DIRECTION_FETCH, ":refs/remotes/frotz/HEAD-to-me", true);
assert_refspec(GIT_DIRECTION_PUSH, ":refs/remotes/frotz/delete me", false);
assert_refspec(GIT_DIRECTION_FETCH, ":refs/remotes/frotz/HEAD to me", false);
assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/*/for-linus:refs/remotes/mine/*-blah", true);
assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/*/for-linus:refs/remotes/mine/*-blah", true);
assert_refspec(GIT_DIRECTION_FETCH, "refs/heads*/for-linus:refs/remotes/mine/*", true);
assert_refspec(GIT_DIRECTION_PUSH, "refs/heads*/for-linus:refs/remotes/mine/*", true);
assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/*/*/for-linus:refs/remotes/mine/*", false);
assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/*/*/for-linus:refs/remotes/mine/*", false);
assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/*g*/for-linus:refs/remotes/mine/*", false);
assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/*g*/for-linus:refs/remotes/mine/*", false);
assert_refspec(GIT_DIRECTION_FETCH, "refs/heads/*/for-linus:refs/remotes/mine/*", true);
assert_refspec(GIT_DIRECTION_PUSH, "refs/heads/*/for-linus:refs/remotes/mine/*", true);
assert_refspec(GIT_DIRECTION_FETCH, "master", true);
assert_refspec(GIT_DIRECTION_PUSH, "master", true);
assert_refspec(GIT_DIRECTION_FETCH, "refs/pull/*/head:refs/remotes/origin/pr/*", true);
}
static void assert_valid_transform(const char *refspec, const char *name, const char *result)
{
git_refspec spec;
git_buf buf = GIT_BUF_INIT;
cl_git_pass(git_refspec__parse(&spec, refspec, true));
cl_git_pass(git_refspec_transform(&buf, &spec, name));
cl_assert_equal_s(result, buf.ptr);
git_buf_dispose(&buf);
git_refspec__dispose(&spec);
}
void test_network_refspecs__transform_mid_star(void)
{
assert_valid_transform("refs/pull/*/head:refs/remotes/origin/pr/*", "refs/pull/23/head", "refs/remotes/origin/pr/23");
assert_valid_transform("refs/heads/*:refs/remotes/origin/*", "refs/heads/master", "refs/remotes/origin/master");
assert_valid_transform("refs/heads/*:refs/remotes/origin/*", "refs/heads/user/feature", "refs/remotes/origin/user/feature");
assert_valid_transform("refs/heads/*:refs/heads/*", "refs/heads/master", "refs/heads/master");
assert_valid_transform("refs/heads/*:refs/heads/*", "refs/heads/user/feature", "refs/heads/user/feature");
assert_valid_transform("refs/*:refs/*", "refs/heads/master", "refs/heads/master");
}
void test_network_refspecs__transform_loosened_star(void)
{
assert_valid_transform("refs/heads/branch-*:refs/remotes/origin/branch-*", "refs/heads/branch-a", "refs/remotes/origin/branch-a");
assert_valid_transform("refs/heads/branch-*/head:refs/remotes/origin/branch-*/head", "refs/heads/branch-a/head", "refs/remotes/origin/branch-a/head");
}
void test_network_refspecs__transform_nested_star(void)
{
assert_valid_transform("refs/heads/x*x/for-linus:refs/remotes/mine/*", "refs/heads/xbranchx/for-linus", "refs/remotes/mine/branch");
}
void test_network_refspecs__no_dst(void)
{
assert_valid_transform("refs/heads/master:", "refs/heads/master", "");
}
static void assert_invalid_transform(const char *refspec, const char *name)
{
git_refspec spec;
git_buf buf = GIT_BUF_INIT;
git_refspec__parse(&spec, refspec, true);
cl_git_fail(git_refspec_transform(&buf, &spec, name));
git_buf_dispose(&buf);
git_refspec__dispose(&spec);
}
void test_network_refspecs__invalid(void)
{
assert_invalid_transform("refs/heads/*:refs/remotes/origin/*", "master");
assert_invalid_transform("refs/heads/*:refs/remotes/origin/*", "refs/headz/master");
}
static void assert_invalid_rtransform(const char *refspec, const char *name)
{
git_refspec spec;
git_buf buf = GIT_BUF_INIT;
git_refspec__parse(&spec, refspec, true);
cl_git_fail(git_refspec_rtransform(&buf, &spec, name));
git_buf_dispose(&buf);
git_refspec__dispose(&spec);
}
void test_network_refspecs__invalid_reverse(void)
{
assert_invalid_rtransform("refs/heads/*:refs/remotes/origin/*", "master");
assert_invalid_rtransform("refs/heads/*:refs/remotes/origin/*", "refs/remotes/o/master");
}
void test_network_refspecs__matching(void)
{
git_refspec spec;
cl_git_pass(git_refspec__parse(&spec, ":", false));
cl_assert_equal_s(":", spec.string);
cl_assert_equal_s("", spec.src);
cl_assert_equal_s("", spec.dst);
git_refspec__dispose(&spec);
}
void test_network_refspecs__parse_free(void)
{
git_refspec *spec = NULL;
cl_git_fail(git_refspec_parse(&spec, "", 0));
cl_git_fail(git_refspec_parse(&spec, ":::", 0));
cl_git_pass(git_refspec_parse(&spec, "HEAD:", 1));
cl_assert(spec != NULL);
git_refspec_free(spec);
}
@@ -0,0 +1,108 @@
#include "clar_libgit2.h"
#include "buffer.h"
#include "refspec.h"
#include "remote.h"
static git_remote *g_remote;
static git_repository *g_repo_a, *g_repo_b;
void test_network_remote_defaultbranch__initialize(void)
{
g_repo_a = cl_git_sandbox_init("testrepo.git");
cl_git_pass(git_repository_init(&g_repo_b, "repo-b.git", true));
cl_git_pass(git_remote_create(&g_remote, g_repo_b, "origin", git_repository_path(g_repo_a)));
}
void test_network_remote_defaultbranch__cleanup(void)
{
git_remote_free(g_remote);
git_repository_free(g_repo_b);
cl_git_sandbox_cleanup();
cl_fixture_cleanup("repo-b.git");
}
static void assert_default_branch(const char *should)
{
git_buf name = GIT_BUF_INIT;
cl_git_pass(git_remote_connect(g_remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL));
cl_git_pass(git_remote_default_branch(&name, g_remote));
cl_assert_equal_s(should, name.ptr);
git_buf_dispose(&name);
}
void test_network_remote_defaultbranch__master(void)
{
assert_default_branch("refs/heads/master");
}
void test_network_remote_defaultbranch__master_does_not_win(void)
{
cl_git_pass(git_repository_set_head(g_repo_a, "refs/heads/not-good"));
assert_default_branch("refs/heads/not-good");
}
void test_network_remote_defaultbranch__master_on_detached(void)
{
cl_git_pass(git_repository_detach_head(g_repo_a));
assert_default_branch("refs/heads/master");
}
void test_network_remote_defaultbranch__no_default_branch(void)
{
git_remote *remote_b;
const git_remote_head **heads;
size_t len;
git_buf buf = GIT_BUF_INIT;
cl_git_pass(git_remote_create(&remote_b, g_repo_b, "self", git_repository_path(g_repo_b)));
cl_git_pass(git_remote_connect(remote_b, GIT_DIRECTION_FETCH, NULL, NULL, NULL));
cl_git_pass(git_remote_ls(&heads, &len, remote_b));
cl_assert_equal_i(0, len);
cl_git_fail_with(GIT_ENOTFOUND, git_remote_default_branch(&buf, remote_b));
git_remote_free(remote_b);
}
void test_network_remote_defaultbranch__detached_sharing_nonbranch_id(void)
{
git_oid id, id_cloned;
git_reference *ref;
git_buf buf = GIT_BUF_INIT;
git_repository *cloned_repo;
cl_git_pass(git_reference_name_to_id(&id, g_repo_a, "HEAD"));
cl_git_pass(git_repository_detach_head(g_repo_a));
cl_git_pass(git_reference_remove(g_repo_a, "refs/heads/master"));
cl_git_pass(git_reference_remove(g_repo_a, "refs/heads/not-good"));
cl_git_pass(git_reference_create(&ref, g_repo_a, "refs/foo/bar", &id, 1, NULL));
git_reference_free(ref);
cl_git_pass(git_remote_connect(g_remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL));
cl_git_fail_with(GIT_ENOTFOUND, git_remote_default_branch(&buf, g_remote));
cl_git_pass(git_clone(&cloned_repo, git_repository_path(g_repo_a), "./local-detached", NULL));
cl_assert(git_repository_head_detached(cloned_repo));
cl_git_pass(git_reference_name_to_id(&id_cloned, g_repo_a, "HEAD"));
cl_assert(git_oid_equal(&id, &id_cloned));
git_repository_free(cloned_repo);
}
void test_network_remote_defaultbranch__unborn_HEAD_with_branches(void)
{
git_reference *ref;
git_repository *cloned_repo;
cl_git_pass(git_reference_symbolic_create(&ref, g_repo_a, "HEAD", "refs/heads/i-dont-exist", 1, NULL));
git_reference_free(ref);
cl_git_pass(git_clone(&cloned_repo, git_repository_path(g_repo_a), "./semi-empty", NULL));
cl_assert(git_repository_head_unborn(cloned_repo));
git_repository_free(cloned_repo);
}
+46
View File
@@ -0,0 +1,46 @@
#include "clar_libgit2.h"
#include "config/config_helpers.h"
#include "repository.h"
static git_repository *_repo;
void test_network_remote_delete__initialize(void)
{
_repo = cl_git_sandbox_init("testrepo.git");
}
void test_network_remote_delete__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_network_remote_delete__remove_remote_tracking_branches(void)
{
git_reference *ref;
cl_git_pass(git_remote_delete(_repo, "test"));
cl_git_fail_with(GIT_ENOTFOUND, git_reference_lookup(&ref, _repo, "refs/remotes/test/master"));
}
void test_network_remote_delete__remove_remote_configuration_settings(void)
{
cl_assert(count_config_entries_match(_repo, "remote\\.test\\.+") > 0);
cl_git_pass(git_remote_delete(_repo, "test"));
cl_assert_equal_i(0, count_config_entries_match(_repo, "remote\\.test\\.+"));
}
void test_network_remote_delete__remove_branch_upstream_configuration_settings(void)
{
assert_config_entry_existence(_repo, "branch.mergeless.remote", true);
assert_config_entry_existence(_repo, "branch.master.remote", true);
cl_git_pass(git_remote_delete(_repo, "test"));
assert_config_entry_existence(_repo, "branch.mergeless.remote", false);
assert_config_entry_existence(_repo, "branch.mergeless.merge", false);
assert_config_entry_existence(_repo, "branch.master.remote", false);
assert_config_entry_existence(_repo, "branch.master.merge", false);
}
+17
View File
@@ -0,0 +1,17 @@
#include "clar_libgit2.h"
void test_network_remote_isvalidname__can_detect_invalid_formats(void)
{
cl_assert_equal_i(false, git_remote_is_valid_name("/"));
cl_assert_equal_i(false, git_remote_is_valid_name("//"));
cl_assert_equal_i(false, git_remote_is_valid_name(".lock"));
cl_assert_equal_i(false, git_remote_is_valid_name("a.lock"));
cl_assert_equal_i(false, git_remote_is_valid_name("/no/leading/slash"));
cl_assert_equal_i(false, git_remote_is_valid_name("no/trailing/slash/"));
}
void test_network_remote_isvalidname__wont_hopefully_choke_on_valid_formats(void)
{
cl_assert_equal_i(true, git_remote_is_valid_name("webmatrix"));
cl_assert_equal_i(true, git_remote_is_valid_name("yishaigalatzer/rules"));
}
+484
View File
@@ -0,0 +1,484 @@
#include "clar_libgit2.h"
#include "buffer.h"
#include "path.h"
#include "posix.h"
#include "git2/sys/repository.h"
static git_repository *repo;
static git_buf file_path_buf = GIT_BUF_INIT;
static git_remote *remote;
static char *push_refspec_strings[] = {
"refs/heads/master",
};
static git_strarray push_array = {
push_refspec_strings,
1,
};
void test_network_remote_local__initialize(void)
{
cl_git_pass(git_repository_init(&repo, "remotelocal/", 0));
cl_git_pass(git_repository_set_ident(repo, "Foo Bar", "foo@example.com"));
cl_assert(repo != NULL);
}
void test_network_remote_local__cleanup(void)
{
git_buf_dispose(&file_path_buf);
git_remote_free(remote);
remote = NULL;
git_repository_free(repo);
repo = NULL;
cl_fixture_cleanup("remotelocal");
}
static void connect_to_local_repository(const char *local_repository)
{
git_buf_sets(&file_path_buf, cl_git_path_url(local_repository));
cl_git_pass(git_remote_create_anonymous(&remote, repo, git_buf_cstr(&file_path_buf)));
cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL));
}
void test_network_remote_local__connected(void)
{
connect_to_local_repository(cl_fixture("testrepo.git"));
cl_assert(git_remote_connected(remote));
git_remote_disconnect(remote);
cl_assert(!git_remote_connected(remote));
}
void test_network_remote_local__retrieve_advertised_references(void)
{
const git_remote_head **refs;
size_t refs_len;
connect_to_local_repository(cl_fixture("testrepo.git"));
cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
cl_assert_equal_i(refs_len, 29);
}
void test_network_remote_local__retrieve_advertised_before_connect(void)
{
const git_remote_head **refs;
size_t refs_len = 0;
git_buf_sets(&file_path_buf, cl_git_path_url(cl_fixture("testrepo.git")));
cl_git_pass(git_remote_create_anonymous(&remote, repo, git_buf_cstr(&file_path_buf)));
cl_git_fail(git_remote_ls(&refs, &refs_len, remote));
}
void test_network_remote_local__retrieve_advertised_references_after_disconnect(void)
{
const git_remote_head **refs;
size_t refs_len;
connect_to_local_repository(cl_fixture("testrepo.git"));
git_remote_disconnect(remote);
cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
cl_assert_equal_i(refs_len, 29);
}
void test_network_remote_local__retrieve_advertised_references_from_spaced_repository(void)
{
const git_remote_head **refs;
size_t refs_len;
cl_fixture_sandbox("testrepo.git");
cl_git_pass(p_rename("testrepo.git", "spaced testrepo.git"));
connect_to_local_repository("spaced testrepo.git");
cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
cl_assert_equal_i(refs_len, 29);
git_remote_free(remote); /* Disconnect from the "spaced repo" before the cleanup */
remote = NULL;
cl_fixture_cleanup("spaced testrepo.git");
}
void test_network_remote_local__nested_tags_are_completely_peeled(void)
{
const git_remote_head **refs;
size_t refs_len, i;
connect_to_local_repository(cl_fixture("testrepo.git"));
cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
for (i = 0; i < refs_len; i++) {
if (!strcmp(refs[i]->name, "refs/tags/test^{}"))
cl_git_pass(git_oid_streq(&refs[i]->oid, "e90810b8df3e80c413d903f631643c716887138d"));
}
}
void test_network_remote_local__shorthand_fetch_refspec0(void)
{
char *refspec_strings[] = {
"master:remotes/sloppy/master",
"master:boh/sloppy/master",
};
git_strarray array = {
refspec_strings,
2,
};
git_reference *ref;
connect_to_local_repository(cl_fixture("testrepo.git"));
cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));
cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/sloppy/master"));
git_reference_free(ref);
cl_git_pass(git_reference_lookup(&ref, repo, "refs/heads/boh/sloppy/master"));
git_reference_free(ref);
}
void test_network_remote_local__shorthand_fetch_refspec1(void)
{
char *refspec_strings[] = {
"master",
"hard_tag",
};
git_strarray array = {
refspec_strings,
2,
};
git_reference *ref;
connect_to_local_repository(cl_fixture("testrepo.git"));
cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));
cl_git_fail(git_reference_lookup(&ref, repo, "refs/remotes/origin/master"));
cl_git_fail(git_reference_lookup(&ref, repo, "refs/tags/hard_tag"));
}
void test_network_remote_local__tagopt(void)
{
git_reference *ref;
git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
cl_git_pass(git_remote_create(&remote, repo, "tagopt", cl_git_path_url(cl_fixture("testrepo.git"))));
fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL;
cl_git_pass(git_remote_fetch(remote, NULL, &fetch_opts, NULL));
cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/tagopt/master"));
git_reference_free(ref);
cl_git_pass(git_reference_lookup(&ref, repo, "refs/tags/hard_tag"));
git_reference_free(ref);
fetch_opts.download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO;
cl_git_pass(git_remote_fetch(remote, NULL, &fetch_opts, NULL));
cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/tagopt/master"));
git_reference_free(ref);
}
void test_network_remote_local__push_to_bare_remote(void)
{
char *refspec_strings[] = {
"master:master",
};
git_strarray array = {
refspec_strings,
1,
};
/* Should be able to push to a bare remote */
git_remote *localremote;
/* Get some commits */
connect_to_local_repository(cl_fixture("testrepo.git"));
cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));
/* Set up an empty bare repo to push into */
{
git_repository *localbarerepo;
cl_git_pass(git_repository_init(&localbarerepo, "./localbare.git", 1));
git_repository_free(localbarerepo);
}
/* Connect to the bare repo */
cl_git_pass(git_remote_create_anonymous(&localremote, repo, "./localbare.git"));
cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH, NULL, NULL, NULL));
/* Try to push */
cl_git_pass(git_remote_upload(localremote, &push_array, NULL));
/* Clean up */
git_remote_free(localremote);
cl_fixture_cleanup("localbare.git");
}
void test_network_remote_local__push_to_bare_remote_with_file_url(void)
{
char *refspec_strings[] = {
"master:master",
};
git_strarray array = {
refspec_strings,
1,
};
/* Should be able to push to a bare remote */
git_remote *localremote;
const char *url;
/* Get some commits */
connect_to_local_repository(cl_fixture("testrepo.git"));
cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));
/* Set up an empty bare repo to push into */
{
git_repository *localbarerepo;
cl_git_pass(git_repository_init(&localbarerepo, "./localbare.git", 1));
git_repository_free(localbarerepo);
}
/* Create a file URL */
url = cl_git_path_url("./localbare.git");
/* Connect to the bare repo */
cl_git_pass(git_remote_create_anonymous(&localremote, repo, url));
cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH, NULL, NULL, NULL));
/* Try to push */
cl_git_pass(git_remote_upload(localremote, &push_array, NULL));
/* Clean up */
git_remote_free(localremote);
cl_fixture_cleanup("localbare.git");
}
void test_network_remote_local__push_to_non_bare_remote(void)
{
char *refspec_strings[] = {
"master:master",
};
git_strarray array = {
refspec_strings,
1,
};
/* Shouldn't be able to push to a non-bare remote */
git_remote *localremote;
git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
/* Get some commits */
connect_to_local_repository(cl_fixture("testrepo.git"));
cl_git_pass(git_remote_fetch(remote, &array, &fetch_opts, NULL));
/* Set up an empty non-bare repo to push into */
{
git_repository *remoterepo = NULL;
cl_git_pass(git_repository_init(&remoterepo, "localnonbare", 0));
git_repository_free(remoterepo);
}
/* Connect to the bare repo */
cl_git_pass(git_remote_create_anonymous(&localremote, repo, "./localnonbare"));
cl_git_pass(git_remote_connect(localremote, GIT_DIRECTION_PUSH, NULL, NULL, NULL));
/* Try to push */
cl_git_fail_with(GIT_EBAREREPO, git_remote_upload(localremote, &push_array, NULL));
/* Clean up */
git_remote_free(localremote);
cl_fixture_cleanup("localbare.git");
}
void test_network_remote_local__fetch(void)
{
char *refspec_strings[] = {
"master:remotes/sloppy/master",
};
git_strarray array = {
refspec_strings,
1,
};
git_reflog *log;
const git_reflog_entry *entry;
git_reference *ref;
connect_to_local_repository(cl_fixture("testrepo.git"));
cl_git_pass(git_remote_fetch(remote, &array, NULL, "UPDAAAAAATE!!"));
cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/sloppy/master"));
git_reference_free(ref);
cl_git_pass(git_reflog_read(&log, repo, "refs/remotes/sloppy/master"));
cl_assert_equal_i(1, git_reflog_entrycount(log));
entry = git_reflog_entry_byindex(log, 0);
cl_assert_equal_s("foo@example.com", git_reflog_entry_committer(entry)->email);
cl_assert_equal_s("UPDAAAAAATE!!", git_reflog_entry_message(entry));
git_reflog_free(log);
}
void test_network_remote_local__reflog(void)
{
char *refspec_strings[] = {
"master:remotes/sloppy/master",
};
git_strarray array = {
refspec_strings,
1,
};
git_reflog *log;
const git_reflog_entry *entry;
connect_to_local_repository(cl_fixture("testrepo.git"));
cl_git_pass(git_remote_fetch(remote, &array, NULL, "UPDAAAAAATE!!"));
cl_git_pass(git_reflog_read(&log, repo, "refs/remotes/sloppy/master"));
cl_assert_equal_i(1, git_reflog_entrycount(log));
entry = git_reflog_entry_byindex(log, 0);
cl_assert_equal_s("foo@example.com", git_reflog_entry_committer(entry)->email);
cl_assert_equal_s("UPDAAAAAATE!!", git_reflog_entry_message(entry));
git_reflog_free(log);
}
void test_network_remote_local__fetch_default_reflog_message(void)
{
char *refspec_strings[] = {
"master:remotes/sloppy/master",
};
git_strarray array = {
refspec_strings,
1,
};
git_reflog *log;
const git_reflog_entry *entry;
char expected_reflog_msg[1024];
connect_to_local_repository(cl_fixture("testrepo.git"));
cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));
cl_git_pass(git_reflog_read(&log, repo, "refs/remotes/sloppy/master"));
cl_assert_equal_i(1, git_reflog_entrycount(log));
entry = git_reflog_entry_byindex(log, 0);
cl_assert_equal_s("foo@example.com", git_reflog_entry_committer(entry)->email);
sprintf(expected_reflog_msg, "fetch %s", git_remote_url(remote));
cl_assert_equal_s(expected_reflog_msg, git_reflog_entry_message(entry));
git_reflog_free(log);
}
void test_network_remote_local__opportunistic_update(void)
{
git_reference *ref;
char *refspec_strings[] = {
"master",
};
git_strarray array = {
refspec_strings,
1,
};
/* this remote has a passive refspec of "refs/heads/<star>:refs/remotes/origin/<star>" */
cl_git_pass(git_remote_create(&remote, repo, "origin", cl_git_fixture_url("testrepo.git")));
/* and we pass the active refspec "master" */
cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));
/* and we expect that to update our copy of origin's master */
cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/origin/master"));
git_reference_free(ref);
}
void test_network_remote_local__update_tips_for_new_remote(void) {
git_repository *src_repo;
git_repository *dst_repo;
git_remote *new_remote;
git_reference* branch;
/* Copy test repo */
cl_fixture_sandbox("testrepo.git");
cl_git_pass(git_repository_open(&src_repo, "testrepo.git"));
/* Set up an empty bare repo to push into */
cl_git_pass(git_repository_init(&dst_repo, "./localbare.git", 1));
/* Push to bare repo */
cl_git_pass(git_remote_create(&new_remote, src_repo, "bare", "./localbare.git"));
cl_git_pass(git_remote_push(new_remote, &push_array, NULL));
/* Make sure remote branch has been created */
cl_git_pass(git_branch_lookup(&branch, src_repo, "bare/master", GIT_BRANCH_REMOTE));
git_reference_free(branch);
git_remote_free(new_remote);
git_repository_free(dst_repo);
cl_fixture_cleanup("localbare.git");
git_repository_free(src_repo);
cl_fixture_cleanup("testrepo.git");
}
void test_network_remote_local__push_delete(void)
{
git_repository *src_repo;
git_repository *dst_repo;
git_remote *remote;
git_reference *ref;
char *spec_push[] = { "refs/heads/master" };
char *spec_delete[] = { ":refs/heads/master" };
git_strarray specs = {
spec_push,
1,
};
src_repo = cl_git_sandbox_init("testrepo.git");
cl_git_pass(git_repository_init(&dst_repo, "target.git", 1));
cl_git_pass(git_remote_create(&remote, src_repo, "origin", "./target.git"));
/* Push the master branch and verify it's there */
cl_git_pass(git_remote_push(remote, &specs, NULL));
cl_git_pass(git_reference_lookup(&ref, dst_repo, "refs/heads/master"));
git_reference_free(ref);
specs.strings = spec_delete;
cl_git_pass(git_remote_push(remote, &specs, NULL));
cl_git_fail(git_reference_lookup(&ref, dst_repo, "refs/heads/master"));
git_remote_free(remote);
git_repository_free(dst_repo);
cl_fixture_cleanup("target.git");
cl_git_sandbox_cleanup();
}
void test_network_remote_local__anonymous_remote_inmemory_repo(void)
{
git_repository *inmemory;
git_remote *remote;
git_buf_sets(&file_path_buf, cl_git_path_url(cl_fixture("testrepo.git")));
cl_git_pass(git_repository_new(&inmemory));
cl_git_pass(git_remote_create_anonymous(&remote, inmemory, git_buf_cstr(&file_path_buf)));
cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL));
cl_assert(git_remote_connected(remote));
git_remote_disconnect(remote);
git_remote_free(remote);
git_repository_free(inmemory);
}
+114
View File
@@ -0,0 +1,114 @@
#include "clar_libgit2.h"
#include "git2/sys/commit.h"
static git_remote *_remote;
static git_repository *_repo, *_dummy;
void test_network_remote_push__initialize(void)
{
cl_fixture_sandbox("testrepo.git");
git_repository_open(&_repo, "testrepo.git");
/* We need a repository to have a remote */
cl_git_pass(git_repository_init(&_dummy, "dummy.git", true));
cl_git_pass(git_remote_create(&_remote, _dummy, "origin", cl_git_path_url("testrepo.git")));
}
void test_network_remote_push__cleanup(void)
{
git_remote_free(_remote);
_remote = NULL;
git_repository_free(_repo);
_repo = NULL;
git_repository_free(_dummy);
_dummy = NULL;
cl_fixture_cleanup("testrepo.git");
cl_fixture_cleanup("dummy.git");
}
int negotiation_cb(const git_push_update **updates, size_t len, void *payload)
{
const git_push_update *expected = payload;
cl_assert_equal_i(1, len);
cl_assert_equal_s(expected->src_refname, updates[0]->src_refname);
cl_assert_equal_s(expected->dst_refname, updates[0]->dst_refname);
cl_assert_equal_oid(&expected->src, &updates[0]->src);
cl_assert_equal_oid(&expected->dst, &updates[0]->dst);
return 0;
}
void test_network_remote_push__delete_notification(void)
{
git_push_options opts = GIT_PUSH_OPTIONS_INIT;
git_reference *ref;
git_push_update expected;
char *refspec = ":refs/heads/master";
const git_strarray refspecs = {
&refspec,
1,
};
cl_git_pass(git_reference_lookup(&ref, _repo, "refs/heads/master"));
expected.src_refname = "";
expected.dst_refname = "refs/heads/master";
memset(&expected.dst, 0, sizeof(git_oid));
git_oid_cpy(&expected.src, git_reference_target(ref));
opts.callbacks.push_negotiation = negotiation_cb;
opts.callbacks.payload = &expected;
cl_git_pass(git_remote_push(_remote, &refspecs, &opts));
git_reference_free(ref);
cl_git_fail_with(GIT_ENOTFOUND, git_reference_lookup(&ref, _repo, "refs/heads/master"));
}
void create_dummy_commit(git_reference **out, git_repository *repo)
{
git_index *index;
git_oid tree_id, commit_id;
git_signature *sig;
cl_git_pass(git_repository_index(&index, repo));
cl_git_pass(git_index_write_tree(&tree_id, index));
git_index_free(index);
cl_git_pass(git_signature_now(&sig, "Pusher Joe", "pjoe"));
cl_git_pass(git_commit_create_from_ids(&commit_id, repo, NULL, sig, sig,
NULL, "Empty tree\n", &tree_id, 0, NULL));
cl_git_pass(git_reference_create(out, repo, "refs/heads/empty-tree", &commit_id, true, "commit yo"));
git_signature_free(sig);
}
void test_network_remote_push__create_notification(void)
{
git_push_options opts = GIT_PUSH_OPTIONS_INIT;
git_reference *ref;
git_push_update expected;
char *refspec = "refs/heads/empty-tree";
const git_strarray refspecs = {
&refspec,
1,
};
create_dummy_commit(&ref, _dummy);
expected.src_refname = "refs/heads/empty-tree";
expected.dst_refname = "refs/heads/empty-tree";
git_oid_cpy(&expected.dst, git_reference_target(ref));
memset(&expected.src, 0, sizeof(git_oid));
opts.callbacks.push_negotiation = negotiation_cb;
opts.callbacks.payload = &expected;
cl_git_pass(git_remote_push(_remote, &refspecs, &opts));
git_reference_free(ref);
cl_git_pass(git_reference_lookup(&ref, _repo, "refs/heads/empty-tree"));
git_reference_free(ref);
}
+479
View File
@@ -0,0 +1,479 @@
#include "clar_libgit2.h"
#include "config/config_helpers.h"
#include "buffer.h"
#include "refspec.h"
#include "remote.h"
static git_remote *_remote;
static git_repository *_repo;
static const git_refspec *_refspec;
void test_network_remote_remotes__initialize(void)
{
_repo = cl_git_sandbox_init("testrepo.git");
cl_git_pass(git_remote_lookup(&_remote, _repo, "test"));
_refspec = git_remote_get_refspec(_remote, 0);
cl_assert(_refspec != NULL);
}
void test_network_remote_remotes__cleanup(void)
{
git_remote_free(_remote);
_remote = NULL;
cl_git_sandbox_cleanup();
}
void test_network_remote_remotes__parsing(void)
{
git_buf url = GIT_BUF_INIT;
git_remote *_remote2 = NULL;
cl_assert_equal_s(git_remote_name(_remote), "test");
cl_assert_equal_s(git_remote_url(_remote), "git://github.com/libgit2/libgit2");
cl_assert(git_remote_pushurl(_remote) == NULL);
cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_FETCH, NULL));
cl_assert_equal_s(url.ptr, "git://github.com/libgit2/libgit2");
cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, NULL));
cl_assert_equal_s(url.ptr, "git://github.com/libgit2/libgit2");
cl_git_pass(git_remote_lookup(&_remote2, _repo, "test_with_pushurl"));
cl_assert_equal_s(git_remote_name(_remote2), "test_with_pushurl");
cl_assert_equal_s(git_remote_url(_remote2), "git://github.com/libgit2/fetchlibgit2");
cl_assert_equal_s(git_remote_pushurl(_remote2), "git://github.com/libgit2/pushlibgit2");
cl_git_pass(git_remote__urlfordirection(&url, _remote2, GIT_DIRECTION_FETCH, NULL));
cl_assert_equal_s(url.ptr, "git://github.com/libgit2/fetchlibgit2");
cl_git_pass(git_remote__urlfordirection(&url, _remote2, GIT_DIRECTION_PUSH, NULL));
cl_assert_equal_s(url.ptr, "git://github.com/libgit2/pushlibgit2");
git_remote_free(_remote2);
git_buf_dispose(&url);
}
static int urlresolve_callback(git_buf *url_resolved, const char *url, int direction, void *payload)
{
cl_assert(strcmp(url, "git://github.com/libgit2/libgit2") == 0);
cl_assert(strcmp(payload, "payload") == 0);
cl_assert(url_resolved->size == 0);
if (direction == GIT_DIRECTION_PUSH)
git_buf_sets(url_resolved, "pushresolve");
if (direction == GIT_DIRECTION_FETCH)
git_buf_sets(url_resolved, "fetchresolve");
return GIT_OK;
}
void test_network_remote_remotes__urlresolve(void)
{
git_buf url = GIT_BUF_INIT;
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
callbacks.resolve_url = urlresolve_callback;
callbacks.payload = "payload";
cl_assert_equal_s(git_remote_name(_remote), "test");
cl_assert_equal_s(git_remote_url(_remote), "git://github.com/libgit2/libgit2");
cl_assert(git_remote_pushurl(_remote) == NULL);
cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_FETCH, &callbacks));
cl_assert_equal_s(url.ptr, "fetchresolve");
cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, &callbacks));
cl_assert_equal_s(url.ptr, "pushresolve");
git_buf_dispose(&url);
}
static int urlresolve_passthrough_callback(git_buf *url_resolved, const char *url, int direction, void *payload)
{
GIT_UNUSED(url_resolved);
GIT_UNUSED(url);
GIT_UNUSED(direction);
GIT_UNUSED(payload);
return GIT_PASSTHROUGH;
}
void test_network_remote_remotes__urlresolve_passthrough(void)
{
git_buf url = GIT_BUF_INIT;
const char *orig_url = "git://github.com/libgit2/libgit2";
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
callbacks.resolve_url = urlresolve_passthrough_callback;
cl_assert_equal_s(git_remote_name(_remote), "test");
cl_assert_equal_s(git_remote_url(_remote), orig_url);
cl_assert(git_remote_pushurl(_remote) == NULL);
cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_FETCH, &callbacks));
cl_assert_equal_s(url.ptr, orig_url);
cl_git_pass(git_remote__urlfordirection(&url, _remote, GIT_DIRECTION_PUSH, &callbacks));
cl_assert_equal_s(url.ptr, orig_url);
git_buf_dispose(&url);
}
void test_network_remote_remotes__pushurl(void)
{
const char *name = git_remote_name(_remote);
git_remote *mod;
cl_git_pass(git_remote_set_pushurl(_repo, name, "git://github.com/libgit2/notlibgit2"));
cl_git_pass(git_remote_lookup(&mod, _repo, name));
cl_assert_equal_s(git_remote_pushurl(mod), "git://github.com/libgit2/notlibgit2");
git_remote_free(mod);
cl_git_pass(git_remote_set_pushurl(_repo, name, NULL));
cl_git_pass(git_remote_lookup(&mod, _repo, name));
cl_assert(git_remote_pushurl(mod) == NULL);
git_remote_free(mod);
}
void test_network_remote_remotes__error_when_not_found(void)
{
git_remote *r;
cl_git_fail_with(git_remote_lookup(&r, _repo, "does-not-exist"), GIT_ENOTFOUND);
cl_assert(git_error_last() != NULL);
cl_assert(git_error_last()->klass == GIT_ERROR_CONFIG);
}
void test_network_remote_remotes__error_when_no_push_available(void)
{
git_remote *r;
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
char *specs = {
"refs/heads/master",
};
git_strarray arr = {
&specs,
1,
};
cl_git_pass(git_remote_create_anonymous(&r, _repo, cl_fixture("testrepo.git")));
callbacks.transport = git_transport_local;
cl_git_pass(git_remote_connect(r, GIT_DIRECTION_PUSH, &callbacks, NULL, NULL));
/* Make sure that push is really not available */
r->transport->push = NULL;
cl_git_fail_with(-1, git_remote_upload(r, &arr, NULL));
git_remote_free(r);
}
void test_network_remote_remotes__refspec_parsing(void)
{
cl_assert_equal_s(git_refspec_src(_refspec), "refs/heads/*");
cl_assert_equal_s(git_refspec_dst(_refspec), "refs/remotes/test/*");
}
void test_network_remote_remotes__add_fetchspec(void)
{
size_t size;
size = git_remote_refspec_count(_remote);
cl_git_pass(git_remote_add_fetch(_repo, "test", "refs/*:refs/*"));
size++;
git_remote_free(_remote);
cl_git_pass(git_remote_lookup(&_remote, _repo, "test"));
cl_assert_equal_i((int)size, (int)git_remote_refspec_count(_remote));
_refspec = git_remote_get_refspec(_remote, size - 1);
cl_assert_equal_s(git_refspec_src(_refspec), "refs/*");
cl_assert_equal_s(git_refspec_dst(_refspec), "refs/*");
cl_assert_equal_s(git_refspec_string(_refspec), "refs/*:refs/*");
cl_assert_equal_b(_refspec->push, false);
cl_git_fail_with(GIT_EINVALIDSPEC, git_remote_add_fetch(_repo, "test", "refs/*/foo/*:refs/*"));
}
void test_network_remote_remotes__dup(void)
{
git_strarray array;
git_remote *dup;
cl_git_pass(git_remote_dup(&dup, _remote));
cl_assert_equal_s(git_remote_name(dup), git_remote_name(_remote));
cl_assert_equal_s(git_remote_url(dup), git_remote_url(_remote));
cl_assert_equal_s(git_remote_pushurl(dup), git_remote_pushurl(_remote));
cl_git_pass(git_remote_get_fetch_refspecs(&array, _remote));
cl_assert_equal_i(1, (int)array.count);
cl_assert_equal_s("+refs/heads/*:refs/remotes/test/*", array.strings[0]);
git_strarray_free(&array);
cl_git_pass(git_remote_get_push_refspecs(&array, _remote));
cl_assert_equal_i(0, (int)array.count);
git_strarray_free(&array);
git_remote_free(dup);
}
void test_network_remote_remotes__add_pushspec(void)
{
size_t size;
size = git_remote_refspec_count(_remote);
cl_git_pass(git_remote_add_push(_repo, "test", "refs/*:refs/*"));
size++;
git_remote_free(_remote);
cl_git_pass(git_remote_lookup(&_remote, _repo, "test"));
cl_assert_equal_i((int)size, (int)git_remote_refspec_count(_remote));
_refspec = git_remote_get_refspec(_remote, size - 1);
cl_assert_equal_s(git_refspec_src(_refspec), "refs/*");
cl_assert_equal_s(git_refspec_dst(_refspec), "refs/*");
cl_assert_equal_s(git_refspec_string(_refspec), "refs/*:refs/*");
cl_assert_equal_b(_refspec->push, true);
}
void test_network_remote_remotes__fnmatch(void)
{
cl_assert(git_refspec_src_matches(_refspec, "refs/heads/master"));
cl_assert(git_refspec_src_matches(_refspec, "refs/heads/multi/level/branch"));
}
void test_network_remote_remotes__transform(void)
{
git_buf ref = GIT_BUF_INIT;
cl_git_pass(git_refspec_transform(&ref, _refspec, "refs/heads/master"));
cl_assert_equal_s(ref.ptr, "refs/remotes/test/master");
git_buf_dispose(&ref);
}
void test_network_remote_remotes__transform_destination_to_source(void)
{
git_buf ref = GIT_BUF_INIT;
cl_git_pass(git_refspec_rtransform(&ref, _refspec, "refs/remotes/test/master"));
cl_assert_equal_s(ref.ptr, "refs/heads/master");
git_buf_dispose(&ref);
}
void test_network_remote_remotes__missing_refspecs(void)
{
git_config *cfg;
git_remote_free(_remote);
_remote = NULL;
cl_git_pass(git_repository_config(&cfg, _repo));
cl_git_pass(git_config_set_string(cfg, "remote.specless.url", "http://example.com"));
cl_git_pass(git_remote_lookup(&_remote, _repo, "specless"));
git_config_free(cfg);
}
void test_network_remote_remotes__nonmatch_upstream_refspec(void)
{
git_config *config;
git_remote *remote;
char *specstr[] = {
"refs/tags/*:refs/tags/*",
};
git_strarray specs = {
specstr,
1,
};
cl_git_pass(git_remote_create(&remote, _repo, "taggy", git_repository_path(_repo)));
/*
* Set the current branch's upstream remote to a dummy ref so we call into the code
* which tries to check for the current branch's upstream in the refspecs
*/
cl_git_pass(git_repository_config(&config, _repo));
cl_git_pass(git_config_set_string(config, "branch.master.remote", "taggy"));
cl_git_pass(git_config_set_string(config, "branch.master.merge", "refs/heads/foo"));
cl_git_pass(git_remote_fetch(remote, &specs, NULL, NULL));
git_remote_free(remote);
}
void test_network_remote_remotes__list(void)
{
git_strarray list;
git_config *cfg;
cl_git_pass(git_remote_list(&list, _repo));
cl_assert(list.count == 5);
git_strarray_free(&list);
cl_git_pass(git_repository_config(&cfg, _repo));
/* Create a new remote */
cl_git_pass(git_config_set_string(cfg, "remote.specless.url", "http://example.com"));
/* Update a remote (previously without any url/pushurl entry) */
cl_git_pass(git_config_set_string(cfg, "remote.no-remote-url.pushurl", "http://example.com"));
cl_git_pass(git_remote_list(&list, _repo));
cl_assert(list.count == 7);
git_strarray_free(&list);
git_config_free(cfg);
}
void test_network_remote_remotes__loading_a_missing_remote_returns_ENOTFOUND(void)
{
git_remote_free(_remote);
_remote = NULL;
cl_assert_equal_i(GIT_ENOTFOUND, git_remote_lookup(&_remote, _repo, "just-left-few-minutes-ago"));
}
void test_network_remote_remotes__loading_with_an_invalid_name_returns_EINVALIDSPEC(void)
{
git_remote_free(_remote);
_remote = NULL;
cl_assert_equal_i(GIT_EINVALIDSPEC, git_remote_lookup(&_remote, _repo, "Inv@{id"));
}
/*
* $ git remote add addtest http://github.com/libgit2/libgit2
*
* $ cat .git/config
* [...]
* [remote "addtest"]
* url = http://github.com/libgit2/libgit2
* fetch = +refs/heads/\*:refs/remotes/addtest/\*
*/
void test_network_remote_remotes__add(void)
{
git_remote_free(_remote);
_remote = NULL;
cl_git_pass(git_remote_create(&_remote, _repo, "addtest", "http://github.com/libgit2/libgit2"));
cl_assert_equal_i(GIT_REMOTE_DOWNLOAD_TAGS_AUTO, git_remote_autotag(_remote));
git_remote_free(_remote);
_remote = NULL;
cl_git_pass(git_remote_lookup(&_remote, _repo, "addtest"));
cl_assert_equal_i(GIT_REMOTE_DOWNLOAD_TAGS_AUTO, git_remote_autotag(_remote));
_refspec = git_vector_get(&_remote->refspecs, 0);
cl_assert_equal_s("refs/heads/*", git_refspec_src(_refspec));
cl_assert(git_refspec_force(_refspec) == 1);
cl_assert_equal_s("refs/remotes/addtest/*", git_refspec_dst(_refspec));
cl_assert_equal_s(git_remote_url(_remote), "http://github.com/libgit2/libgit2");
}
void test_network_remote_remotes__tagopt(void)
{
const char *name = git_remote_name(_remote);
git_remote_set_autotag(_repo, name, GIT_REMOTE_DOWNLOAD_TAGS_ALL);
assert_config_entry_value(_repo, "remote.test.tagopt", "--tags");
git_remote_set_autotag(_repo, name, GIT_REMOTE_DOWNLOAD_TAGS_NONE);
assert_config_entry_value(_repo, "remote.test.tagopt", "--no-tags");
git_remote_set_autotag(_repo, name, GIT_REMOTE_DOWNLOAD_TAGS_AUTO);
assert_config_entry_existence(_repo, "remote.test.tagopt", false);
}
void test_network_remote_remotes__can_load_with_an_empty_url(void)
{
git_remote *remote = NULL;
cl_git_pass(git_remote_lookup(&remote, _repo, "empty-remote-url"));
cl_assert(remote->url == NULL);
cl_assert(remote->pushurl == NULL);
cl_git_fail(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL));
cl_assert(git_error_last() != NULL);
cl_assert(git_error_last()->klass == GIT_ERROR_INVALID);
git_remote_free(remote);
}
void test_network_remote_remotes__can_load_with_only_an_empty_pushurl(void)
{
git_remote *remote = NULL;
cl_git_pass(git_remote_lookup(&remote, _repo, "empty-remote-pushurl"));
cl_assert(remote->url == NULL);
cl_assert(remote->pushurl == NULL);
cl_git_fail(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL));
git_remote_free(remote);
}
void test_network_remote_remotes__returns_ENOTFOUND_when_neither_url_nor_pushurl(void)
{
git_remote *remote = NULL;
cl_git_fail_with(
git_remote_lookup(&remote, _repo, "no-remote-url"), GIT_ENOTFOUND);
}
static const char *fetch_refspecs[] = {
"+refs/heads/*:refs/remotes/origin/*",
"refs/tags/*:refs/tags/*",
"+refs/pull/*:refs/pull/*",
};
static const char *push_refspecs[] = {
"refs/heads/*:refs/heads/*",
"refs/tags/*:refs/tags/*",
"refs/notes/*:refs/notes/*",
};
void test_network_remote_remotes__query_refspecs(void)
{
git_remote *remote;
git_strarray array;
int i;
cl_git_pass(git_remote_create_with_fetchspec(&remote, _repo, "query", "git://github.com/libgit2/libgit2", NULL));
git_remote_free(remote);
for (i = 0; i < 3; i++) {
cl_git_pass(git_remote_add_fetch(_repo, "query", fetch_refspecs[i]));
cl_git_pass(git_remote_add_push(_repo, "query", push_refspecs[i]));
}
cl_git_pass(git_remote_lookup(&remote, _repo, "query"));
cl_git_pass(git_remote_get_fetch_refspecs(&array, remote));
for (i = 0; i < 3; i++) {
cl_assert_equal_s(fetch_refspecs[i], array.strings[i]);
}
git_strarray_free(&array);
cl_git_pass(git_remote_get_push_refspecs(&array, remote));
for (i = 0; i < 3; i++) {
cl_assert_equal_s(push_refspecs[i], array.strings[i]);
}
git_strarray_free(&array);
git_remote_free(remote);
git_remote_delete(_repo, "test");
}
+245
View File
@@ -0,0 +1,245 @@
#include "clar_libgit2.h"
#include "config/config_helpers.h"
#include "repository.h"
static git_repository *_repo;
static const char *_remote_name = "test";
void test_network_remote_rename__initialize(void)
{
_repo = cl_git_sandbox_init("testrepo.git");
}
void test_network_remote_rename__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_network_remote_rename__renaming_a_remote_moves_related_configuration_section(void)
{
git_strarray problems = {0};
assert_config_entry_existence(_repo, "remote.test.fetch", true);
assert_config_entry_existence(_repo, "remote.just/renamed.fetch", false);
cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "just/renamed"));
cl_assert_equal_i(0, problems.count);
git_strarray_free(&problems);
assert_config_entry_existence(_repo, "remote.test.fetch", false);
assert_config_entry_existence(_repo, "remote.just/renamed.fetch", true);
}
void test_network_remote_rename__renaming_a_remote_updates_branch_related_configuration_entries(void)
{
git_strarray problems = {0};
assert_config_entry_value(_repo, "branch.master.remote", "test");
cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "just/renamed"));
cl_assert_equal_i(0, problems.count);
git_strarray_free(&problems);
assert_config_entry_value(_repo, "branch.master.remote", "just/renamed");
}
void test_network_remote_rename__renaming_a_remote_updates_default_fetchrefspec(void)
{
git_strarray problems = {0};
cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "just/renamed"));
cl_assert_equal_i(0, problems.count);
git_strarray_free(&problems);
assert_config_entry_value(_repo, "remote.just/renamed.fetch", "+refs/heads/*:refs/remotes/just/renamed/*");
}
void test_network_remote_rename__renaming_a_remote_without_a_fetchrefspec_doesnt_create_one(void)
{
git_config *config;
git_remote *remote;
git_strarray problems = {0};
cl_git_pass(git_repository_config__weakptr(&config, _repo));
cl_git_pass(git_config_delete_entry(config, "remote.test.fetch"));
cl_git_pass(git_remote_lookup(&remote, _repo, "test"));
git_remote_free(remote);
assert_config_entry_existence(_repo, "remote.test.fetch", false);
cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "just/renamed"));
cl_assert_equal_i(0, problems.count);
git_strarray_free(&problems);
assert_config_entry_existence(_repo, "remote.just/renamed.fetch", false);
}
void test_network_remote_rename__renaming_a_remote_notifies_of_non_default_fetchrefspec(void)
{
git_config *config;
git_remote *remote;
git_strarray problems = {0};
cl_git_pass(git_repository_config__weakptr(&config, _repo));
cl_git_pass(git_config_set_string(config, "remote.test.fetch", "+refs/*:refs/*"));
cl_git_pass(git_remote_lookup(&remote, _repo, "test"));
git_remote_free(remote);
cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "just/renamed"));
cl_assert_equal_i(1, problems.count);
cl_assert_equal_s("+refs/*:refs/*", problems.strings[0]);
git_strarray_free(&problems);
assert_config_entry_value(_repo, "remote.just/renamed.fetch", "+refs/*:refs/*");
git_strarray_free(&problems);
}
void test_network_remote_rename__new_name_can_contain_dots(void)
{
git_strarray problems = {0};
cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "just.renamed"));
cl_assert_equal_i(0, problems.count);
git_strarray_free(&problems);
assert_config_entry_existence(_repo, "remote.just.renamed.fetch", true);
}
void test_network_remote_rename__new_name_must_conform_to_reference_naming_conventions(void)
{
git_strarray problems = {0};
cl_assert_equal_i(
GIT_EINVALIDSPEC,
git_remote_rename(&problems, _repo, _remote_name, "new@{name"));
}
void test_network_remote_rename__renamed_name_is_persisted(void)
{
git_remote *renamed;
git_repository *another_repo;
git_strarray problems = {0};
cl_git_fail(git_remote_lookup(&renamed, _repo, "just/renamed"));
cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "just/renamed"));
cl_assert_equal_i(0, problems.count);
git_strarray_free(&problems);
cl_git_pass(git_repository_open(&another_repo, "testrepo.git"));
cl_git_pass(git_remote_lookup(&renamed, _repo, "just/renamed"));
git_remote_free(renamed);
git_repository_free(another_repo);
}
void test_network_remote_rename__cannot_overwrite_an_existing_remote(void)
{
git_strarray problems = {0};
cl_assert_equal_i(GIT_EEXISTS, git_remote_rename(&problems, _repo, _remote_name, "test"));
cl_assert_equal_i(GIT_EEXISTS, git_remote_rename(&problems, _repo, _remote_name, "test_with_pushurl"));
}
void test_network_remote_rename__renaming_a_remote_moves_the_underlying_reference(void)
{
git_reference *underlying;
git_strarray problems = {0};
cl_assert_equal_i(GIT_ENOTFOUND, git_reference_lookup(&underlying, _repo, "refs/remotes/just/renamed"));
cl_git_pass(git_reference_lookup(&underlying, _repo, "refs/remotes/test/master"));
git_reference_free(underlying);
cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "just/renamed"));
cl_assert_equal_i(0, problems.count);
git_strarray_free(&problems);
cl_assert_equal_i(GIT_ENOTFOUND, git_reference_lookup(&underlying, _repo, "refs/remotes/test/master"));
cl_git_pass(git_reference_lookup(&underlying, _repo, "refs/remotes/just/renamed/master"));
git_reference_free(underlying);
}
void test_network_remote_rename__overwrite_ref_in_target(void)
{
git_oid id;
char idstr[GIT_OID_HEXSZ + 1] = {0};
git_reference *ref;
git_branch_t btype;
git_branch_iterator *iter;
git_strarray problems = {0};
cl_git_pass(git_oid_fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"));
cl_git_pass(git_reference_create(&ref, _repo, "refs/remotes/renamed/master", &id, 1, NULL));
git_reference_free(ref);
cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "renamed"));
cl_assert_equal_i(0, problems.count);
git_strarray_free(&problems);
/* make sure there's only one remote-tracking branch */
cl_git_pass(git_branch_iterator_new(&iter, _repo, GIT_BRANCH_REMOTE));
cl_git_pass(git_branch_next(&ref, &btype, iter));
cl_assert_equal_s("refs/remotes/renamed/master", git_reference_name(ref));
git_oid_fmt(idstr, git_reference_target(ref));
cl_assert_equal_s("be3563ae3f795b2b4353bcce3a527ad0a4f7f644", idstr);
git_reference_free(ref);
cl_git_fail_with(GIT_ITEROVER, git_branch_next(&ref, &btype, iter));
git_branch_iterator_free(iter);
}
void test_network_remote_rename__nonexistent_returns_enotfound(void)
{
git_strarray problems = {0};
int err = git_remote_rename(&problems, _repo, "nonexistent", "renamed");
cl_assert_equal_i(GIT_ENOTFOUND, err);
}
void test_network_remote_rename__symref_head(void)
{
int error;
git_reference *ref;
git_branch_t btype;
git_branch_iterator *iter;
git_strarray problems = {0};
char idstr[GIT_OID_HEXSZ + 1] = {0};
git_vector refs;
cl_git_pass(git_reference_symbolic_create(&ref, _repo, "refs/remotes/test/HEAD", "refs/remotes/test/master", 0, NULL));
git_reference_free(ref);
cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "renamed"));
cl_assert_equal_i(0, problems.count);
git_strarray_free(&problems);
cl_git_pass(git_vector_init(&refs, 2, (git_vector_cmp) git_reference_cmp));
cl_git_pass(git_branch_iterator_new(&iter, _repo, GIT_BRANCH_REMOTE));
while ((error = git_branch_next(&ref, &btype, iter)) == 0) {
cl_git_pass(git_vector_insert(&refs, ref));
}
cl_assert_equal_i(GIT_ITEROVER, error);
git_vector_sort(&refs);
cl_assert_equal_i(2, refs.length);
ref = git_vector_get(&refs, 0);
cl_assert_equal_s("refs/remotes/renamed/HEAD", git_reference_name(ref));
cl_assert_equal_s("refs/remotes/renamed/master", git_reference_symbolic_target(ref));
git_reference_free(ref);
ref = git_vector_get(&refs, 1);
cl_assert_equal_s("refs/remotes/renamed/master", git_reference_name(ref));
git_oid_fmt(idstr, git_reference_target(ref));
cl_assert_equal_s("be3563ae3f795b2b4353bcce3a527ad0a4f7f644", idstr);
git_reference_free(ref);
git_vector_free(&refs);
cl_git_fail_with(GIT_ITEROVER, git_branch_next(&ref, &btype, iter));
git_branch_iterator_free(iter);
}
+168
View File
@@ -0,0 +1,168 @@
#include "clar_libgit2.h"
#include "net.h"
static git_net_url conndata;
void test_network_urlparse__initialize(void)
{
memset(&conndata, 0, sizeof(conndata));
}
void test_network_urlparse__cleanup(void)
{
git_net_url_dispose(&conndata);
}
void test_network_urlparse__trivial(void)
{
cl_git_pass(git_net_url_parse(&conndata, "http://example.com/resource"));
cl_assert_equal_s(conndata.scheme, "http");
cl_assert_equal_s(conndata.host, "example.com");
cl_assert_equal_s(conndata.port, "80");
cl_assert_equal_s(conndata.path, "/resource");
cl_assert_equal_p(conndata.username, NULL);
cl_assert_equal_p(conndata.password, NULL);
cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1);
}
void test_network_urlparse__root(void)
{
cl_git_pass(git_net_url_parse(&conndata, "http://example.com/"));
cl_assert_equal_s(conndata.scheme, "http");
cl_assert_equal_s(conndata.host, "example.com");
cl_assert_equal_s(conndata.port, "80");
cl_assert_equal_s(conndata.path, "/");
cl_assert_equal_p(conndata.username, NULL);
cl_assert_equal_p(conndata.password, NULL);
cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1);
}
void test_network_urlparse__implied_root(void)
{
cl_git_pass(git_net_url_parse(&conndata, "http://example.com"));
cl_assert_equal_s(conndata.scheme, "http");
cl_assert_equal_s(conndata.host, "example.com");
cl_assert_equal_s(conndata.port, "80");
cl_assert_equal_s(conndata.path, "/");
cl_assert_equal_p(conndata.username, NULL);
cl_assert_equal_p(conndata.password, NULL);
cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1);
}
void test_network_urlparse__implied_root_custom_port(void)
{
cl_git_pass(git_net_url_parse(&conndata, "http://example.com:42"));
cl_assert_equal_s(conndata.scheme, "http");
cl_assert_equal_s(conndata.host, "example.com");
cl_assert_equal_s(conndata.port, "42");
cl_assert_equal_s(conndata.path, "/");
cl_assert_equal_p(conndata.username, NULL);
cl_assert_equal_p(conndata.password, NULL);
cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0);
}
void test_network_urlparse__implied_root_empty_port(void)
{
cl_git_pass(git_net_url_parse(&conndata, "http://example.com:"));
cl_assert_equal_s(conndata.scheme, "http");
cl_assert_equal_s(conndata.host, "example.com");
cl_assert_equal_s(conndata.port, "80");
cl_assert_equal_s(conndata.path, "/");
cl_assert_equal_p(conndata.username, NULL);
cl_assert_equal_p(conndata.password, NULL);
cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1);
}
void test_network_urlparse__encoded_password(void)
{
cl_git_pass(git_net_url_parse(&conndata,
"https://user:pass%2fis%40bad@hostname.com:1234/"));
cl_assert_equal_s(conndata.scheme, "https");
cl_assert_equal_s(conndata.host, "hostname.com");
cl_assert_equal_s(conndata.port, "1234");
cl_assert_equal_s(conndata.path, "/");
cl_assert_equal_s(conndata.username, "user");
cl_assert_equal_s(conndata.password, "pass/is@bad");
cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0);
}
void test_network_urlparse__user(void)
{
cl_git_pass(git_net_url_parse(&conndata,
"https://user@example.com/resource"));
cl_assert_equal_s(conndata.scheme, "https");
cl_assert_equal_s(conndata.host, "example.com");
cl_assert_equal_s(conndata.port, "443");
cl_assert_equal_s(conndata.path, "/resource");
cl_assert_equal_s(conndata.username, "user");
cl_assert_equal_p(conndata.password, NULL);
cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1);
}
void test_network_urlparse__user_pass(void)
{
/* user:pass@hostname.tld/resource */
cl_git_pass(git_net_url_parse(&conndata,
"https://user:pass@example.com/resource"));
cl_assert_equal_s(conndata.scheme, "https");
cl_assert_equal_s(conndata.host, "example.com");
cl_assert_equal_s(conndata.port, "443");
cl_assert_equal_s(conndata.path, "/resource");
cl_assert_equal_s(conndata.username, "user");
cl_assert_equal_s(conndata.password, "pass");
cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1);
}
void test_network_urlparse__port(void)
{
/* hostname.tld:port/resource */
cl_git_pass(git_net_url_parse(&conndata,
"https://example.com:9191/resource"));
cl_assert_equal_s(conndata.scheme, "https");
cl_assert_equal_s(conndata.host, "example.com");
cl_assert_equal_s(conndata.port, "9191");
cl_assert_equal_s(conndata.path, "/resource");
cl_assert_equal_p(conndata.username, NULL);
cl_assert_equal_p(conndata.password, NULL);
cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0);
}
void test_network_urlparse__empty_port(void)
{
cl_git_pass(git_net_url_parse(&conndata, "http://example.com:/resource"));
cl_assert_equal_s(conndata.scheme, "http");
cl_assert_equal_s(conndata.host, "example.com");
cl_assert_equal_s(conndata.port, "80");
cl_assert_equal_s(conndata.path, "/resource");
cl_assert_equal_p(conndata.username, NULL);
cl_assert_equal_p(conndata.password, NULL);
cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1);
}
void test_network_urlparse__user_port(void)
{
/* user@hostname.tld:port/resource */
cl_git_pass(git_net_url_parse(&conndata,
"https://user@example.com:9191/resource"));
cl_assert_equal_s(conndata.scheme, "https");
cl_assert_equal_s(conndata.host, "example.com");
cl_assert_equal_s(conndata.port, "9191");
cl_assert_equal_s(conndata.path, "/resource");
cl_assert_equal_s(conndata.username, "user");
cl_assert_equal_p(conndata.password, NULL);
cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0);
}
void test_network_urlparse__user_pass_port(void)
{
/* user:pass@hostname.tld:port/resource */
cl_git_pass(git_net_url_parse(&conndata,
"https://user:pass@example.com:9191/resource"));
cl_assert_equal_s(conndata.scheme, "https");
cl_assert_equal_s(conndata.host, "example.com");
cl_assert_equal_s(conndata.port, "9191");
cl_assert_equal_s(conndata.path, "/resource");
cl_assert_equal_s(conndata.username, "user");
cl_assert_equal_s(conndata.password, "pass");
cl_assert_equal_i(git_net_url_is_default_port(&conndata), 0);
}