Commit d76fb20ebce03b2fd87c2472d556bf9b64894efd

Vicent Martí 2013-04-30T03:29:48

Merge pull request #1520 from carlosmn/nth-refspec Add refspec list accessors

diff --git a/include/git2/refspec.h b/include/git2/refspec.h
index 3e1b502..c0b410c 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
@@ -52,6 +53,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 
  *
  * @param refspec the refspec
diff --git a/include/git2/remote.h b/include/git2/remote.h
index f02b956..2aa384a 100644
--- a/include/git2/remote.h
+++ b/include/git2/remote.h
@@ -191,6 +191,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
  *
  * The transport is selected based on the URL. The direction argument
diff --git a/src/refspec.c b/src/refspec.c
index 2565408..a907df8 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 1183137..08f56cd 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 02066e0..545fe3a 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 908e17d..4c24db8 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/*");