Commit f7fcb18f8a7541bfc0228967fcbd916a9f515638

Carlos Martín Nieto 2014-11-23T14:12:54

Plug leaks Valgrind is now clean except for libssl and libgcrypt.

diff --git a/src/diff.c b/src/diff.c
index 89b3b77..1f3ee63 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -1234,7 +1234,7 @@ int git_diff_tree_to_workdir(
 
 	assert(diff && repo);
 
-	if ((error = git_repository_index(&index, repo)))
+	if ((error = git_repository_index__weakptr(&index, repo)))
 		return error;
 
 	DIFF_FROM_ITERATORS(
@@ -1243,7 +1243,6 @@ int git_diff_tree_to_workdir(
 			&b, repo, index, old_tree, GIT_ITERATOR_DONT_AUTOEXPAND, pfx, pfx)
 	);
 
-	git_index_free(index);
 	return error;
 }
 
diff --git a/src/iterator.c b/src/iterator.c
index d8a17a7..196addd 100644
--- a/src/iterator.c
+++ b/src/iterator.c
@@ -1418,6 +1418,7 @@ static void workdir_iterator__free(git_iterator *self)
 	workdir_iterator *wi = (workdir_iterator *)self;
 	if (wi->index)
 		git_index_snapshot_release(&wi->index_snapshot, wi->index);
+	git_tree_free(wi->tree);
 	fs_iterator__free(self);
 	git_ignore__free(&wi->ignores);
 }
diff --git a/src/remote.c b/src/remote.c
index b1a8407..0b00733 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -995,6 +995,7 @@ static int remote_head_for_ref(git_remote_head **out, git_remote *remote, git_re
 		error = remote_head_for_fetchspec_src(out, update_heads, git_buf_cstr(&remote_name));
 
 cleanup:
+	git_buf_free(&remote_name);
 	git_reference_free(resolved_ref);
 	git_config_free(config);
 	return error;
diff --git a/src/transports/local.c b/src/transports/local.c
index 05302a1..c544fa9 100644
--- a/src/transports/local.c
+++ b/src/transports/local.c
@@ -47,6 +47,17 @@ static void free_head(git_remote_head *head)
 	git__free(head);
 }
 
+static void free_heads(git_vector *heads)
+{
+	git_remote_head *head;
+	size_t i;
+
+	git_vector_foreach(heads, i, head)
+		free_head(head);
+
+	git_vector_free(heads);
+}
+
 static int add_ref(transport_local *t, const char *name)
 {
 	const char peeled[] = "^{}";
@@ -198,6 +209,8 @@ static int local_connect(
 	if (t->connected)
 		return 0;
 
+	free_heads(&t->refs);
+
 	t->url = git__strdup(url);
 	GITERR_CHECK_ALLOC(t->url);
 	t->direction = direction;
@@ -624,13 +637,8 @@ static int local_close(git_transport *transport)
 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)
-		free_head(head);
-
-	git_vector_free(&t->refs);
+	free_heads(&t->refs);
 
 	/* Close the transport, if it's still open. */
 	local_close(transport);
diff --git a/tests/checkout/tree.c b/tests/checkout/tree.c
index 3212d65..1d65527 100644
--- a/tests/checkout/tree.c
+++ b/tests/checkout/tree.c
@@ -986,6 +986,7 @@ void test_checkout_tree__removes_conflicts(void)
 
 	cl_assert(!git_path_exists("testrepo/other.txt"));
 
+	git_commit_free(commit);
 	git_index_free(index);
 }
 
@@ -1030,5 +1031,6 @@ void test_checkout_tree__removes_conflicts_only_by_pathscope(void)
 
 	cl_assert(git_path_exists("testrepo/other.txt"));
 
+	git_commit_free(commit);
 	git_index_free(index);
 }
diff --git a/tests/diff/diff_helpers.c b/tests/diff/diff_helpers.c
index 279cb20..47e06f0 100644
--- a/tests/diff/diff_helpers.c
+++ b/tests/diff/diff_helpers.c
@@ -12,12 +12,9 @@ git_tree *resolve_commit_oid_to_tree(
 	git_tree *tree = NULL;
 
 	if (git_oid_fromstrn(&oid, partial_oid, len) == 0)
-		git_object_lookup_prefix(&obj, repo, &oid, len, GIT_OBJ_ANY);
-	cl_assert(obj);
-	if (git_object_type(obj) == GIT_OBJ_TREE)
-		return (git_tree *)obj;
-	cl_assert(git_object_type(obj) == GIT_OBJ_COMMIT);
-	cl_git_pass(git_commit_tree(&tree, (git_commit *)obj));
+		cl_git_pass(git_object_lookup_prefix(&obj, repo, &oid, len, GIT_OBJ_ANY));
+
+	cl_git_pass(git_object_peel((git_object **) &tree, obj, GIT_OBJ_TREE));
 	git_object_free(obj);
 	return tree;
 }
diff --git a/tests/network/remote/local.c b/tests/network/remote/local.c
index b4a68e5..fd755b8 100644
--- a/tests/network/remote/local.c
+++ b/tests/network/remote/local.c
@@ -172,12 +172,14 @@ void test_network_remote_local__tagopt(void)
 	cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL));
 
 	cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/tagopt/master"));
+	git_reference_free(ref);
 	cl_git_pass(git_reference_lookup(&ref, repo, "refs/tags/hard_tag"));
 	git_reference_free(ref);
 
 	git_remote_set_autotag(remote, GIT_REMOTE_DOWNLOAD_TAGS_AUTO);
 	cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL));
 	cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/tagopt/master"));
+	git_reference_free(ref);
 }
 
 void test_network_remote_local__push_to_bare_remote(void)
diff --git a/tests/status/ignore.c b/tests/status/ignore.c
index 6b31e77..ea4376c 100644
--- a/tests/status/ignore.c
+++ b/tests/status/ignore.c
@@ -925,6 +925,7 @@ void test_status_ignore__subdir_doesnt_match_above(void)
 
 	cl_git_pass(git_repository_config_snapshot(&cfg, g_repo));
 	error = git_config_get_bool(&icase, cfg, "core.ignorecase");
+	git_config_free(cfg);
 	if (error == GIT_ENOTFOUND)
 		error = 0;