Commit bc6374ea by Carlos Martín Nieto

remote: allow querying for refspecs

Introduce git_remote_{fetch,push}_refspecs() to get a list of refspecs
from the remote and rename the refspec-adding functions to a less
silly name.

Use this instead of the vector index hacks in the tests.
parent 4330ab26
......@@ -148,7 +148,18 @@ GIT_EXTERN(int) git_remote_set_pushurl(git_remote *remote, const char* url);
* @apram refspec the new fetch refspec
* @return 0 or an error value
*/
GIT_EXTERN(int) git_remote_add_fetchspec(git_remote *remote, const char *refspec);
GIT_EXTERN(int) git_remote_add_fetch(git_remote *remote, const char *refspec);
/**
* Get the remote's list of fetch refspecs
*
* The memory is owned by the user and should be freed with
* `git_strarray_free`.
*
* @param array pointer to the array in which to store the strings
* @param remote the remote to query
*/
GIT_EXTERN(int) git_remote_get_fetch_refspecs(git_strarray *array, git_remote *remote);
/**
* Add a push refspec to the remote
......@@ -157,7 +168,18 @@ GIT_EXTERN(int) git_remote_add_fetchspec(git_remote *remote, const char *refspec
* @param refspec the new push refspec
* @return 0 or an error value
*/
GIT_EXTERN(int) git_remote_add_pushspec(git_remote *remote, const char *refspec);
GIT_EXTERN(int) git_remote_add_push(git_remote *remote, const char *refspec);
/**
* Get the remote's list of push refspecs
*
* The memory is owned by the user and should be freed with
* `git_strarray_free`.
*
* @param array pointer to the array in which to store the strings
* @param remote the remote to query
*/
GIT_EXTERN(int) git_remote_get_push_refspecs(git_strarray *array, git_remote *remote);
/**
* Get the push refspec
......
......@@ -324,11 +324,11 @@ static int create_and_configure_origin(
goto on_error;
if (options->fetch_spec &&
(error = git_remote_add_fetchspec(origin, options->fetch_spec)) < 0)
(error = git_remote_add_fetch(origin, options->fetch_spec)) < 0)
goto on_error;
if (options->push_spec &&
(error = git_remote_add_pushspec(origin, options->push_spec)) < 0)
(error = git_remote_add_push(origin, options->push_spec)) < 0)
goto on_error;
if (options->pushurl &&
......
......@@ -1467,12 +1467,60 @@ void git_remote_clear_refspecs(git_remote *remote)
git_vector_clear(&remote->refspec_strings);
}
int git_remote_add_fetchspec(git_remote *remote, const char *refspec)
int git_remote_add_fetch(git_remote *remote, const char *refspec)
{
return add_refspec(remote, refspec, true);
}
int git_remote_add_pushspec(git_remote *remote, const char *refspec)
int git_remote_add_push(git_remote *remote, const char *refspec)
{
return add_refspec(remote, refspec, false);
}
static int copy_refspecs(git_strarray *array, git_remote *remote, int push)
{
size_t i;
git_vector refspecs;
git_refspec *spec;
char *dup;
if (git_vector_init(&refspecs, remote->refspecs.length, NULL) < 0)
return -1;
git_vector_foreach(&remote->refspecs, i, spec) {
if (spec->push != push)
continue;
dup = git__strdup(git_vector_get(&remote->refspec_strings, i));
if (!dup) {
goto on_error;
}
if (git_vector_insert(&refspecs, dup) < 0) {
git__free(dup);
goto on_error;
}
}
array->strings = (char **)refspecs.contents;
array->count = refspecs.length;
return 0;
on_error:
git_vector_foreach(&refspecs, i, dup)
git__free(dup);
git_vector_free(&refspecs);
return -1;
}
int git_remote_get_fetch_refspecs(git_strarray *array, git_remote *remote)
{
return copy_refspecs(array, remote, false);
}
int git_remote_get_push_refspecs(git_strarray *array, git_remote *remote)
{
return copy_refspecs(array, remote, true);
}
......@@ -116,7 +116,7 @@ void test_network_remote_remotes__add_fetchspec(void)
size = _remote->refspecs.length;
cl_assert_equal_i(size, _remote->refspec_strings.length);
cl_git_pass(git_remote_add_fetchspec(_remote, "refs/*:refs/*"));
cl_git_pass(git_remote_add_fetch(_remote, "refs/*:refs/*"));
size++;
cl_assert_equal_i(size, _remote->refspec_strings.length);
......@@ -134,7 +134,7 @@ void test_network_remote_remotes__add_pushspec(void)
size = _remote->refspecs.length;
cl_git_pass(git_remote_add_pushspec(_remote, "refs/*:refs/*"));
cl_git_pass(git_remote_add_push(_remote, "refs/*:refs/*"));
size++;
cl_assert_equal_i(size, _remote->refspec_strings.length);
cl_assert_equal_i(size, _remote->refspecs.length);
......@@ -148,23 +148,19 @@ void test_network_remote_remotes__add_pushspec(void)
void test_network_remote_remotes__save(void)
{
git_strarray array;
const char *fetch_refspec = "refs/heads/*:refs/remotes/upstream/*";
const char *push_refspec = "refs/heads/*:refs/heads/*";
git_remote_free(_remote);
_remote = NULL;
/* Set up the remote and save it to config */
cl_git_pass(git_remote_create(&_remote, _repo, "upstream", "git://github.com/libgit2/libgit2"));
git_remote_clear_refspecs(_remote);
cl_assert_equal_i(0, _remote->refspecs.length);
cl_assert_equal_i(0, _remote->refspec_strings.length);
cl_git_pass(git_remote_add_fetchspec(_remote, "refs/heads/*:refs/remotes/upstream/*"));
cl_assert_equal_i(1, _remote->refspecs.length);
cl_assert_equal_i(1, _remote->refspec_strings.length);
cl_git_pass(git_remote_add_pushspec(_remote, "refs/heads/*:refs/heads/*"));
cl_assert_equal_i(2, _remote->refspecs.length);
cl_assert_equal_i(2, _remote->refspec_strings.length);
cl_git_pass(git_remote_add_fetch(_remote, fetch_refspec));
cl_git_pass(git_remote_add_push(_remote, push_refspec));
cl_git_pass(git_remote_set_pushurl(_remote, "git://github.com/libgit2/libgit2_push"));
cl_git_pass(git_remote_save(_remote));
git_remote_free(_remote);
......@@ -173,20 +169,17 @@ void test_network_remote_remotes__save(void)
/* Load it from config and make sure everything matches */
cl_git_pass(git_remote_load(&_remote, _repo, "upstream"));
_refspec = git_vector_get(&_remote->refspecs, 0);
cl_assert(_refspec != NULL);
cl_assert_equal_s(git_refspec_src(_refspec), "refs/heads/*");
cl_assert_equal_s(git_refspec_dst(_refspec), "refs/remotes/upstream/*");
cl_assert_equal_i(0, git_refspec_force(_refspec));
cl_assert(_refspec != git_vector_get(&_remote->refspecs, 1));
_refspec = git_vector_get(&_remote->refspecs, 1);
cl_assert(_refspec != NULL);
cl_assert_equal_s(git_refspec_src(_refspec), "refs/heads/*");
cl_assert_equal_s(git_refspec_dst(_refspec), "refs/heads/*");
cl_git_pass(git_remote_get_fetch_refspecs(&array, _remote));
cl_assert_equal_i(1, array.count);
cl_assert_equal_s(fetch_refspec, array.strings[0]);
git_strarray_free(&array);
cl_git_pass(git_remote_get_push_refspecs(&array, _remote));
cl_assert_equal_i(1, array.count);
cl_assert_equal_s(push_refspec, array.strings[0]);
cl_assert_equal_s(git_remote_url(_remote), "git://github.com/libgit2/libgit2");
cl_assert_equal_s(git_remote_pushurl(_remote), "git://github.com/libgit2/libgit2_push");
git_strarray_free(&array);
/* remove the pushurl again and see if we can save that too */
cl_git_pass(git_remote_set_pushurl(_remote, NULL));
......@@ -418,3 +411,43 @@ void test_network_remote_remotes__cannot_create_a_remote_which_name_is_invalid(v
assert_cannot_create_remote(".lock", GIT_EINVALIDSPEC);
assert_cannot_create_remote("a.lock", GIT_EINVALIDSPEC);
}
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_inmemory(&remote, _repo, NULL, "git://github.com/libgit2/libgit2"));
for (i = 0; i < 3; i++) {
cl_git_pass(git_remote_add_fetch(remote, fetch_refspecs[i]));
cl_git_pass(git_remote_add_push(remote, push_refspecs[i]));
}
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);
}
......@@ -44,7 +44,7 @@ static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fet
if(fetchspec != NULL) {
git_remote_clear_refspecs(remote);
git_remote_add_fetchspec(remote, fetchspec);
git_remote_add_fetch(remote, fetchspec);
}
cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH));
......
......@@ -70,7 +70,7 @@ void test_refs_branches_remote__ambiguous_remote_returns_error(void)
/* Update the remote fetch spec */
git_remote_clear_refspecs(remote);
cl_git_pass(git_remote_add_fetchspec(remote, "refs/heads/*:refs/remotes/test/*"));
cl_git_pass(git_remote_add_fetch(remote, "refs/heads/*:refs/remotes/test/*"));
cl_git_pass(git_remote_save(remote));
git_remote_free(remote);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment