summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2013-04-20 18:49:11 +0200
committerCarlos Martín Nieto <cmn@dwim.me>2013-04-20 19:45:40 +0200
commitbc6374eac485ab9ad9cfd7165b6d071c3dcb673a (patch)
tree8ba82d9d64953384895afb1e26a33c3c7d5c6832
parent4330ab26b53c0e1bf8cbb5e65704f65e3d116eba (diff)
downloadlibgit2-bc6374eac485ab9ad9cfd7165b6d071c3dcb673a.tar.gz
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.
-rw-r--r--include/git2/remote.h26
-rw-r--r--src/clone.c4
-rw-r--r--src/remote.c52
-rw-r--r--tests-clar/network/remote/remotes.c79
-rw-r--r--tests-clar/online/fetchhead.c2
-rw-r--r--tests-clar/refs/branches/remote.c2
6 files changed, 134 insertions, 31 deletions
diff --git a/include/git2/remote.h b/include/git2/remote.h
index 7a161796f..5dcd93099 100644
--- a/include/git2/remote.h
+++ b/include/git2/remote.h
@@ -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
diff --git a/src/clone.c b/src/clone.c
index cb4053736..8f10ca819 100644
--- a/src/clone.c
+++ b/src/clone.c
@@ -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 &&
diff --git a/src/remote.c b/src/remote.c
index 1c4b22bb9..8b7e66e53 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -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);
+}
diff --git a/tests-clar/network/remote/remotes.c b/tests-clar/network/remote/remotes.c
index 92c9d8ac1..7b6e6aa85 100644
--- a/tests-clar/network/remote/remotes.c
+++ b/tests-clar/network/remote/remotes.c
@@ -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);
+}
diff --git a/tests-clar/online/fetchhead.c b/tests-clar/online/fetchhead.c
index 3cbdc7e93..e14ae0926 100644
--- a/tests-clar/online/fetchhead.c
+++ b/tests-clar/online/fetchhead.c
@@ -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));
diff --git a/tests-clar/refs/branches/remote.c b/tests-clar/refs/branches/remote.c
index 475fa54a8..6043828b3 100644
--- a/tests-clar/refs/branches/remote.c
+++ b/tests-clar/refs/branches/remote.c
@@ -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);