diff --git a/include/git2/refspec.h b/include/git2/refspec.h index 3e1b502ef..c0b410cbf 100644 --- a/include/git2/refspec.h +++ b/include/git2/refspec.h @@ -9,6 +9,7 @@ #include "common.h" #include "types.h" +#include "net.h" /** * @file git2/refspec.h @@ -51,6 +52,14 @@ GIT_EXTERN(const char *) git_refspec_string(const git_refspec *refspec); */ GIT_EXTERN(int) git_refspec_force(const git_refspec *refspec); +/** + * Get the refspec's direction. + * + * @param the refspec + * @return GIT_DIRECTION_FETCH or GIT_DIRECTION_PUSH + */ +GIT_EXTERN(git_direction) git_refspec_direction(const git_refspec *spec); + /** * Check if a refspec's source descriptor matches a reference * diff --git a/include/git2/remote.h b/include/git2/remote.h index f02b95678..2aa384a54 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -190,6 +190,32 @@ GIT_EXTERN(int) git_remote_get_push_refspecs(git_strarray *array, git_remote *re */ GIT_EXTERN(void) git_remote_clear_refspecs(git_remote *remote); +/** + * Get the number of refspecs for a remote + * + * @param remote the remote + * @return the amount of refspecs configured in this remote + */ +GIT_EXTERN(size_t) git_remote_refspec_count(git_remote *remote); + +/** + * Get a refspec from the remote + * + * @param remote the remote to query + * @param n the refspec to get + * @return the nth refspec + */ +GIT_EXTERN(const git_refspec *)git_remote_get_refspec(git_remote *remote, size_t n); + +/** + * Remove a refspec from the remote + * + * @param remote the remote to query + * @param n the refspec to remove + * @return 0 or GIT_ENOTFOUND + */ +GIT_EXTERN(int) git_remote_remove_refspec(git_remote *remote, size_t n); + /** * Open a connection to a remote * diff --git a/src/refspec.c b/src/refspec.c index 256540819..a907df84c 100644 --- a/src/refspec.c +++ b/src/refspec.c @@ -274,3 +274,10 @@ int git_refspec_is_wildcard(const git_refspec *spec) return (spec->src[strlen(spec->src) - 1] == '*'); } + +git_direction git_refspec_direction(const git_refspec *spec) +{ + assert(spec); + + return spec->push; +} diff --git a/src/remote.c b/src/remote.c index 1183137a6..08f56cd51 100644 --- a/src/remote.c +++ b/src/remote.c @@ -8,6 +8,7 @@ #include "git2/config.h" #include "git2/types.h" #include "git2/oid.h" +#include "git2/net.h" #include "config.h" #include "repository.h" @@ -691,6 +692,7 @@ static int dwim_refspecs(git_vector *refspecs, git_vector *refs) spec->dwim = 1; } + git_buf_free(&buf); return 0; } @@ -1574,3 +1576,28 @@ int git_remote_get_push_refspecs(git_strarray *array, git_remote *remote) { return copy_refspecs(array, remote, true); } + +size_t git_remote_refspec_count(git_remote *remote) +{ + return remote->refspecs.length; +} + +const git_refspec *git_remote_get_refspec(git_remote *remote, size_t n) +{ + return git_vector_get(&remote->refspecs, n); +} + +int git_remote_remove_refspec(git_remote *remote, size_t n) +{ + git_refspec *spec; + + assert(remote); + + spec = git_vector_get(&remote->refspecs, n); + if (spec) { + git_refspec__free(spec); + git__free(spec); + } + + return git_vector_remove(&remote->refspecs, n); +} diff --git a/tests-clar/clone/nonetwork.c b/tests-clar/clone/nonetwork.c index 02066e07d..545fe3a06 100644 --- a/tests-clar/clone/nonetwork.c +++ b/tests-clar/clone/nonetwork.c @@ -149,7 +149,7 @@ void test_clone_nonetwork__custom_fetch_spec(void) cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); cl_git_pass(git_remote_load(&g_remote, g_repo, "origin")); - actual_fs = git_vector_get(&g_remote->refspecs, 0); + actual_fs = git_remote_get_refspec(g_remote, 0); cl_assert_equal_s("refs/heads/master", git_refspec_src(actual_fs)); cl_assert_equal_s("refs/heads/foo", git_refspec_dst(actual_fs)); @@ -165,7 +165,7 @@ void test_clone_nonetwork__custom_push_spec(void) cl_git_pass(git_clone(&g_repo, cl_git_fixture_url("testrepo.git"), "./foo", &g_options)); cl_git_pass(git_remote_load(&g_remote, g_repo, "origin")); - actual_fs = git_vector_get(&g_remote->refspecs, g_remote->refspecs.length - 1); + actual_fs = git_remote_get_refspec(g_remote, git_remote_refspec_count(g_remote) - 1); cl_assert_equal_s("refs/heads/master", git_refspec_src(actual_fs)); cl_assert_equal_s("refs/heads/foo", git_refspec_dst(actual_fs)); } diff --git a/tests-clar/network/remote/remotes.c b/tests-clar/network/remote/remotes.c index 908e17d96..4c24db8eb 100644 --- a/tests-clar/network/remote/remotes.c +++ b/tests-clar/network/remote/remotes.c @@ -13,7 +13,7 @@ void test_network_remote_remotes__initialize(void) cl_git_pass(git_remote_load(&_remote, _repo, "test")); - _refspec = git_vector_get(&_remote->refspecs, 0); + _refspec = git_remote_get_refspec(_remote, 0); cl_assert(_refspec != NULL); } @@ -113,15 +113,14 @@ void test_network_remote_remotes__add_fetchspec(void) { size_t size; - size = _remote->refspecs.length; - cl_assert_equal_i(size, _remote->refspecs.length); + size = git_remote_refspec_count(_remote); cl_git_pass(git_remote_add_fetch(_remote, "refs/*:refs/*")); size++; - cl_assert_equal_i(size, _remote->refspecs.length); + cl_assert_equal_i(size, git_remote_refspec_count(_remote)); - _refspec = git_vector_get(&_remote->refspecs, size-1); + _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/*"); @@ -132,13 +131,13 @@ void test_network_remote_remotes__add_pushspec(void) { size_t size; - size = _remote->refspecs.length; + size = git_remote_refspec_count(_remote); cl_git_pass(git_remote_add_push(_remote, "refs/*:refs/*")); size++; - cl_assert_equal_i(size, _remote->refspecs.length); + cl_assert_equal_i(size, git_remote_refspec_count(_remote)); - _refspec = git_vector_get(&_remote->refspecs, size-1); + _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/*");