diff --git a/src/transports/local.c b/src/transports/local.c index 550060958..a9da8146c 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 3cb8a25d6..d5d75fdc6 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;