Commit d0c36a0baf42d751c23e13df08c7ec9f800dd40f

Russell Belfer 2013-06-25T10:42:38

Merge pull request #1678 from arthurschreiber/unbreak-local-ls-after-disconnect Unbreak git_remote_ls on a local transport after disconnecting.

diff --git a/src/transports/local.c b/src/transports/local.c
index 5500609..a9da814 100644
--- a/src/transports/local.c
+++ b/src/transports/local.c
@@ -119,15 +119,24 @@ on_error:
 
 static int store_refs(transport_local *t)
 {
-	unsigned int i;
+	size_t i;
+	git_remote_head *head;
 	git_strarray ref_names = {0};
 
 	assert(t);
 
-	if (git_reference_list(&ref_names, t->repo) < 0 ||
-		git_vector_init(&t->refs, ref_names.count, NULL) < 0)
+	if (git_reference_list(&ref_names, t->repo) < 0)
 		goto on_error;
 
+	/* Clear all heads we might have fetched in a previous connect */
+	git_vector_foreach(&t->refs, i, head) {
+		git__free(head->name);
+		git__free(head);
+	}
+
+	/* Clear the vector so we can reuse it */
+	git_vector_clear(&t->refs);
+
 	/* Sort the references first */
 	git__tsort((void **)ref_names.strings, ref_names.count, &git__strcmp_cb);
 
@@ -571,8 +580,6 @@ static void local_cancel(git_transport *transport)
 static int local_close(git_transport *transport)
 {
 	transport_local *t = (transport_local *)transport;
-	size_t i;
-	git_remote_head *head;
 
 	t->connected = 0;
 
@@ -586,19 +593,21 @@ static int local_close(git_transport *transport)
 		t->url = NULL;
 	}
 
-	git_vector_foreach(&t->refs, i, head) {
-		git__free(head->name);
-		git__free(head);
-	}
-
-	git_vector_free(&t->refs);
-
 	return 0;
 }
 
 static void local_free(git_transport *transport)
 {
 	transport_local *t = (transport_local *)transport;
+	size_t i;
+	git_remote_head *head;
+
+	git_vector_foreach(&t->refs, i, head) {
+		git__free(head->name);
+		git__free(head);
+	}
+
+	git_vector_free(&t->refs);
 
 	/* Close the transport, if it's still open. */
 	local_close(transport);
@@ -632,6 +641,7 @@ int git_transport_local(git_transport **out, git_remote *owner, void *param)
 	t->parent.read_flags = local_read_flags;
 	t->parent.cancel = local_cancel;
 
+	git_vector_init(&t->refs, 0, NULL);
 	t->owner = owner;
 
 	*out = (git_transport *) t;
diff --git a/tests-clar/network/remote/local.c b/tests-clar/network/remote/local.c
index 3cb8a25..d5d75fd 100644
--- a/tests-clar/network/remote/local.c
+++ b/tests-clar/network/remote/local.c
@@ -75,6 +75,18 @@ void test_network_remote_local__retrieve_advertised_references(void)
 	cl_assert_equal_i(how_many_refs, 28);
 }
 
+void test_network_remote_local__retrieve_advertised_references_after_disconnect(void)
+{
+	int how_many_refs = 0;
+
+	connect_to_local_repository(cl_fixture("testrepo.git"));
+	git_remote_disconnect(remote);
+
+	cl_git_pass(git_remote_ls(remote, &count_ref__cb, &how_many_refs));
+
+	cl_assert_equal_i(how_many_refs, 28);
+}
+
 void test_network_remote_local__retrieve_advertised_references_from_spaced_repository(void)
 {
 	int how_many_refs = 0;