Commit 75abd2b9 by schu Committed by Vicent Marti

Free all used references in the source tree

Since references are not owned by the repository anymore we have to free
them manually now.

Signed-off-by: schu <schu-github@schulog.org>
parent 4fd89fa0
......@@ -145,8 +145,10 @@ int git_commit_create(
error = git_reference_resolve(&target, head);
if (error < GIT_SUCCESS) {
if (error != GIT_ENOTFOUND)
if (error != GIT_ENOTFOUND) {
git_reference_free(head);
return git__rethrow(error, "Failed to create commit");
}
/*
* The target of the reference was not found. This can happen
* just after a repository has been initialized (the master
......@@ -154,10 +156,19 @@ int git_commit_create(
* point to) or after an orphan checkout, so if the target
* branch doesn't exist yet, create it and return.
*/
return git_reference_create_oid(&head, repo, git_reference_target(head), oid, 1);
error = git_reference_create_oid(&target, repo, git_reference_target(head), oid, 1);
git_reference_free(head);
if (error == GIT_SUCCESS)
git_reference_free(target);
return error;
}
error = git_reference_set_oid(target, oid);
git_reference_free(head);
git_reference_free(target);
}
if (error < GIT_SUCCESS)
......
......@@ -218,8 +218,12 @@ int git_reflog_write(git_reference *ref, const git_oid *oid_old,
return git__rethrow(error, "Failed to write reflog. Cannot resolve reference `%s`", ref->name);
oid = git_reference_oid(r);
if (oid == NULL)
if (oid == NULL) {
git_reference_free(r);
return git__throw(GIT_ERROR, "Failed to write reflog. Cannot resolve reference `%s`", r->name);
}
git_reference_free(r);
git_oid_to_string(new, GIT_OID_HEXSZ+1, oid);
......
......@@ -603,8 +603,14 @@ static int repo_init_reinit(const char *repository_path, int is_bare)
static int repo_init_createhead(git_repository *repo)
{
int error;
git_reference *head_reference;
return git_reference_create_symbolic(&head_reference, repo, GIT_HEAD_FILE, GIT_REFS_HEADS_MASTER_FILE, 0);
error = git_reference_create_symbolic(&head_reference, repo, GIT_HEAD_FILE, GIT_REFS_HEADS_MASTER_FILE, 0);
git_reference_free(head_reference);
return error;
}
static int repo_init_structure(const char *git_dir, int is_bare)
......@@ -715,10 +721,15 @@ int git_repository_head_detached(git_repository *repo)
if (error < GIT_SUCCESS)
return error;
if (git_reference_type(ref) == GIT_REF_SYMBOLIC)
if (git_reference_type(ref) == GIT_REF_SYMBOLIC) {
git_reference_free(ref);
return 0;
}
error = git_odb_read_header(&_size, &type, repo->db, git_reference_oid(ref));
git_reference_free(ref);
if (error < GIT_SUCCESS)
return error;
......@@ -730,7 +741,7 @@ int git_repository_head_detached(git_repository *repo)
int git_repository_head(git_reference **head_out, git_repository *repo)
{
git_reference *ref;
git_reference *ref, *resolved_ref;
int error;
*head_out = NULL;
......@@ -739,11 +750,15 @@ int git_repository_head(git_reference **head_out, git_repository *repo)
if (error < GIT_SUCCESS)
return git__rethrow(GIT_ENOTAREPO, "Failed to locate the HEAD");
error = git_reference_resolve(&ref, ref);
if (error < GIT_SUCCESS)
error = git_reference_resolve(&resolved_ref, ref);
if (error < GIT_SUCCESS) {
git_reference_free(ref);
return git__rethrow(error, "Failed to resolve the HEAD");
}
*head_out = ref;
git_reference_free(ref);
*head_out = resolved_ref;
return GIT_SUCCESS;
}
......@@ -754,6 +769,9 @@ int git_repository_head_orphan(git_repository *repo)
error = git_repository_head(&ref, repo);
if (error == GIT_SUCCESS)
git_reference_free(ref);
return error == GIT_ENOTFOUND ? 1 : error;
}
......@@ -766,13 +784,21 @@ int git_repository_is_empty(git_repository *repo)
if (error < GIT_SUCCESS)
return git__throw(error, "Corrupted repository. HEAD does not exist");
if (git_reference_type(head) != GIT_REF_SYMBOLIC)
if (git_reference_type(head) != GIT_REF_SYMBOLIC) {
git_reference_free(head);
return 0;
}
if (strcmp(git_reference_target(head), "refs/heads/master") != 0)
if (strcmp(git_reference_target(head), "refs/heads/master") != 0) {
git_reference_free(head);
return 0;
}
error = git_reference_resolve(&branch, head);
git_reference_free(head);
git_reference_free(branch);
return error == GIT_ENOTFOUND ? 1 : error;
}
......
......@@ -153,6 +153,8 @@ static int retrieve_tag_reference(git_reference **tag_reference_out, char *ref_n
git_reference *tag_ref;
int error;
*tag_reference_out = NULL;
git_path_join(ref_name_out, GIT_REFS_TAGS_DIR, tag_name);
error = git_reference_lookup(&tag_ref, repo, ref_name_out);
if (error < GIT_SUCCESS)
......@@ -224,6 +226,7 @@ static int git_tag_create__internal(
break;
default:
git_reference_free(new_ref);
return git__rethrow(error, "Failed to create tag");
}
......@@ -232,6 +235,7 @@ static int git_tag_create__internal(
if (new_ref != NULL) {
if (!allow_ref_overwrite) {
git_oid_cpy(oid, git_reference_oid(new_ref));
git_reference_free(new_ref);
return git__throw(GIT_EEXISTS, "Tag already exists");
} else {
should_update_ref = 1;
......@@ -239,8 +243,10 @@ static int git_tag_create__internal(
}
if (create_tag_annotation) {
if ((error = write_tag_annotation(oid, repo, tag_name, target, tagger, message)) < GIT_SUCCESS)
if ((error = write_tag_annotation(oid, repo, tag_name, target, tagger, message)) < GIT_SUCCESS) {
git_reference_free(new_ref);
return error;
}
} else
git_oid_cpy(oid, git_object_id(target));
......@@ -249,6 +255,8 @@ static int git_tag_create__internal(
else
error = git_reference_set_oid(new_ref, oid);
git_reference_free(new_ref);
return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "Failed to create tag");
}
......@@ -281,7 +289,7 @@ int git_tag_create_frombuffer(git_oid *oid, git_repository *repo, const char *bu
git_odb_stream *stream;
git_odb_object *target_obj;
git_reference *new_ref;
git_reference *new_ref = NULL;
char ref_name[GIT_REFNAME_MAX];
assert(oid && buffer);
......@@ -309,6 +317,7 @@ int git_tag_create_frombuffer(git_oid *oid, git_repository *repo, const char *bu
break;
default:
git_reference_free(new_ref);
return git__rethrow(error, "Failed to create tag");
}
......@@ -317,6 +326,7 @@ int git_tag_create_frombuffer(git_oid *oid, git_repository *repo, const char *bu
if (new_ref != NULL) {
if (!allow_ref_overwrite) {
git_oid_cpy(oid, git_reference_oid(new_ref));
git_reference_free(new_ref);
return git__throw(GIT_EEXISTS, "Tag already exists");
} else {
should_update_ref = 1;
......@@ -324,22 +334,28 @@ int git_tag_create_frombuffer(git_oid *oid, git_repository *repo, const char *bu
}
/* write the buffer */
if ((error = git_odb_open_wstream(&stream, repo->db, strlen(buffer), GIT_OBJ_TAG)) < GIT_SUCCESS)
if ((error = git_odb_open_wstream(&stream, repo->db, strlen(buffer), GIT_OBJ_TAG)) < GIT_SUCCESS) {
git_reference_free(new_ref);
return git__rethrow(error, "Failed to create tag");
}
stream->write(stream, buffer, strlen(buffer));
error = stream->finalize_write(oid, stream);
stream->free(stream);
if (error < GIT_SUCCESS)
if (error < GIT_SUCCESS) {
git_reference_free(new_ref);
return git__rethrow(error, "Failed to create tag");
}
if (!should_update_ref)
error = git_reference_create_oid(&new_ref, repo, ref_name, oid, 0);
else
error = git_reference_set_oid(new_ref, oid);
git_reference_free(new_ref);
git_signature_free(tag.tagger);
git__free(tag.tag_name);
git__free(tag.message);
......
......@@ -54,7 +54,7 @@ static int add_ref(const char *name, git_repository *repo, git_vector *vec)
{
const char peeled[] = "^{}";
git_remote_head *head;
git_reference *ref;
git_reference *ref, *resolved_ref;
git_object *obj = NULL;
int error = GIT_SUCCESS, peel_len, ret;
......@@ -72,7 +72,7 @@ static int add_ref(const char *name, git_repository *repo, git_vector *vec)
if (error < GIT_SUCCESS)
goto out;
error = git_reference_resolve(&ref, ref);
error = git_reference_resolve(&resolved_ref, ref);
if (error < GIT_SUCCESS)
goto out;
......@@ -111,6 +111,9 @@ static int add_ref(const char *name, git_repository *repo, git_vector *vec)
goto out;
out:
git_reference_free(ref);
git_reference_free(resolved_ref);
git_object_close(obj);
if (error < GIT_SUCCESS) {
git__free(head->name);
......
......@@ -766,6 +766,8 @@ BEGIN_TEST(root0, "create a root commit")
git__free(head_old);
git_commit_close(commit);
git_repository_free(repo);
git_reference_free(head);
END_TEST
BEGIN_SUITE(commit)
......
......@@ -197,7 +197,6 @@ BEGIN_TEST(write0, "write a tag to the repository and read it again")
git_tag_close(tag);
git_repository_free(repo);
END_TEST
BEGIN_TEST(write2, "Attempt to write a tag bearing the same name than an already existing tag")
......@@ -266,6 +265,7 @@ BEGIN_TEST(write3, "Replace an already existing tag")
close_temp_repo(repo);
git_reference_free(ref_tag);
END_TEST
BEGIN_TEST(write4, "write a lightweight tag to the repository and read it again")
......@@ -296,6 +296,8 @@ BEGIN_TEST(write4, "write a lightweight tag to the repository and read it again"
must_pass(git_tag_delete(repo, "light-tag"));
git_repository_free(repo);
git_reference_free(ref_tag);
END_TEST
BEGIN_TEST(write5, "Attempt to write a lightweight tag bearing the same name than an already existing tag")
......@@ -334,6 +336,8 @@ BEGIN_TEST(delete0, "Delete an already existing tag")
must_fail(git_reference_lookup(&ref_tag, repo, "refs/tags/e90810b"));
close_temp_repo(repo);
git_reference_free(ref_tag);
END_TEST
BEGIN_SUITE(tag)
......
......@@ -56,6 +56,8 @@ BEGIN_TEST(readtag0, "lookup a loose tag reference")
git_object_close(object);
git_repository_free(repo);
git_reference_free(reference);
END_TEST
BEGIN_TEST(readtag1, "lookup a loose tag reference that doesn't exist")
......@@ -66,6 +68,8 @@ BEGIN_TEST(readtag1, "lookup a loose tag reference that doesn't exist")
must_fail(git_reference_lookup(&reference, repo, non_existing_tag_ref_name));
git_repository_free(repo);
git_reference_free(reference);
END_TEST
static const char *head_tracker_sym_ref_name = "head-tracker";
......@@ -97,6 +101,9 @@ BEGIN_TEST(readsym0, "lookup a symbolic reference")
git_object_close(object);
git_repository_free(repo);
git_reference_free(reference);
git_reference_free(resolved_ref);
END_TEST
BEGIN_TEST(readsym1, "lookup a nested symbolic reference")
......@@ -124,6 +131,9 @@ BEGIN_TEST(readsym1, "lookup a nested symbolic reference")
git_object_close(object);
git_repository_free(repo);
git_reference_free(reference);
git_reference_free(resolved_ref);
END_TEST
BEGIN_TEST(readsym2, "lookup the HEAD and resolve the master branch")
......@@ -145,6 +155,10 @@ BEGIN_TEST(readsym2, "lookup the HEAD and resolve the master branch")
must_pass(git_oid_cmp(git_reference_oid(comp_base_ref), git_reference_oid(resolved_ref)));
git_repository_free(repo);
git_reference_free(reference);
git_reference_free(resolved_ref);
git_reference_free(comp_base_ref);
END_TEST
BEGIN_TEST(readsym3, "lookup the master branch and then the HEAD")
......@@ -160,6 +174,10 @@ BEGIN_TEST(readsym3, "lookup the master branch and then the HEAD")
must_pass(git_oid_cmp(git_reference_oid(master_ref), git_reference_oid(resolved_ref)));
git_repository_free(repo);
git_reference_free(reference);
git_reference_free(resolved_ref);
git_reference_free(master_ref);
END_TEST
static const char *packed_head_name = "refs/heads/packed";
......@@ -183,6 +201,8 @@ BEGIN_TEST(readpacked0, "lookup a packed reference")
git_object_close(object);
git_repository_free(repo);
git_reference_free(reference);
END_TEST
BEGIN_TEST(readpacked1, "assure that a loose reference is looked up before a packed reference")
......@@ -197,6 +217,8 @@ BEGIN_TEST(readpacked1, "assure that a loose reference is looked up before a pac
must_be_true(strcmp(reference->name, packed_test_head_name) == 0);
git_repository_free(repo);
git_reference_free(reference);
END_TEST
BEGIN_TEST(create0, "create a new symbolic reference")
......@@ -240,6 +262,10 @@ BEGIN_TEST(create0, "create a new symbolic reference")
must_be_true(git_oid_cmp(&id, git_reference_oid(resolved_ref)) == 0);
close_temp_repo(repo2);
git_reference_free(new_reference);
git_reference_free(looked_up_ref);
git_reference_free(resolved_ref);
END_TEST
BEGIN_TEST(create1, "create a deep symbolic reference")
......@@ -261,6 +287,10 @@ BEGIN_TEST(create1, "create a deep symbolic reference")
must_be_true(git_oid_cmp(&id, git_reference_oid(resolved_ref)) == 0);
close_temp_repo(repo);
git_reference_free(new_reference);
git_reference_free(looked_up_ref);
git_reference_free(resolved_ref);
END_TEST
BEGIN_TEST(create2, "create a new OID reference")
......@@ -299,6 +329,9 @@ BEGIN_TEST(create2, "create a new OID reference")
must_be_true(git_oid_cmp(&id, git_reference_oid(looked_up_ref)) == 0);
close_temp_repo(repo2);
git_reference_free(new_reference);
git_reference_free(looked_up_ref);
END_TEST
BEGIN_TEST(create3, "Can not create a new OID reference which targets at an unknown id")
......@@ -349,6 +382,9 @@ BEGIN_TEST(overwrite0, "Overwrite an existing symbolic reference")
must_be_true(!strcmp(git_reference_target(ref), ref_master_name));
close_temp_repo(repo);
git_reference_free(ref);
git_reference_free(branch_ref);
END_TEST
BEGIN_TEST(overwrite1, "Overwrite an existing object id reference")
......@@ -378,6 +414,8 @@ BEGIN_TEST(overwrite1, "Overwrite an existing object id reference")
must_be_true(!git_oid_cmp(&id, git_reference_oid(ref)));
close_temp_repo(repo);
git_reference_free(ref);
END_TEST
BEGIN_TEST(overwrite2, "Overwrite an existing object id reference with a symbolic one")
......@@ -401,6 +439,8 @@ BEGIN_TEST(overwrite2, "Overwrite an existing object id reference with a symboli
must_be_true(!strcmp(git_reference_target(ref), ref_master_name));
close_temp_repo(repo);
git_reference_free(ref);
END_TEST
BEGIN_TEST(overwrite3, "Overwrite an existing symbolic reference with an object id one")
......@@ -426,6 +466,8 @@ BEGIN_TEST(overwrite3, "Overwrite an existing symbolic reference with an object
must_be_true(!git_oid_cmp(git_reference_oid(ref), &id));
close_temp_repo(repo);
git_reference_free(ref);
END_TEST
BEGIN_TEST(pack0, "create a packfile for an empty folder")
......@@ -475,6 +517,8 @@ BEGIN_TEST(pack1, "create a packfile from all the loose rn a repo")
must_pass(!git_futils_exists(temp_path));
close_temp_repo(repo);
git_reference_free(reference);
END_TEST
BEGIN_TEST(rename0, "rename a loose reference")
......@@ -515,6 +559,9 @@ BEGIN_TEST(rename0, "rename a loose reference")
must_pass(git_futils_exists(temp_path));
close_temp_repo(repo);
git_reference_free(looked_up_ref);
git_reference_free(another_looked_up_ref);
END_TEST
BEGIN_TEST(rename1, "rename a packed reference (should make it loose)")
......@@ -555,6 +602,9 @@ BEGIN_TEST(rename1, "rename a packed reference (should make it loose)")
must_pass(git_futils_exists(temp_path));
close_temp_repo(repo);
git_reference_free(looked_up_ref);
git_reference_free(another_looked_up_ref);
END_TEST
BEGIN_TEST(rename2, "renaming a packed reference does not pack another reference which happens to be in both loose and pack state")
......@@ -594,6 +644,9 @@ BEGIN_TEST(rename2, "renaming a packed reference does not pack another reference
must_pass(git_futils_exists(temp_path));
close_temp_repo(repo);
git_reference_free(looked_up_ref);
git_reference_free(another_looked_up_ref);
END_TEST
BEGIN_TEST(rename3, "can not rename a reference with the name of an existing reference")
......@@ -613,6 +666,8 @@ BEGIN_TEST(rename3, "can not rename a reference with the name of an existing ref
must_be_true(!strcmp(looked_up_ref->name, packed_head_name));
close_temp_repo(repo);
git_reference_free(looked_up_ref);
END_TEST
BEGIN_TEST(rename4, "can not rename a reference with an invalid name")
......@@ -635,6 +690,8 @@ BEGIN_TEST(rename4, "can not rename a reference with an invalid name")
must_be_true(!strcmp(looked_up_ref->name, packed_test_head_name));
close_temp_repo(repo);
git_reference_free(looked_up_ref);
END_TEST
BEGIN_TEST(rename5, "can force-rename a packed reference with the name of an existing loose and packed reference")
......@@ -660,6 +717,8 @@ BEGIN_TEST(rename5, "can force-rename a packed reference with the name of an exi
must_fail(git_reference_lookup(&looked_up_ref, repo, packed_head_name));
close_temp_repo(repo);
git_reference_free(looked_up_ref);
END_TEST
BEGIN_TEST(rename6, "can force-rename a loose reference with the name of an existing loose reference")
......@@ -685,6 +744,8 @@ BEGIN_TEST(rename6, "can force-rename a loose reference with the name of an exis
must_fail(git_reference_lookup(&looked_up_ref, repo, "refs/heads/br2"));
close_temp_repo(repo);
git_reference_free(looked_up_ref);
END_TEST
static const char *ref_one_name = "refs/heads/one/branch";
......@@ -717,6 +778,11 @@ BEGIN_TEST(rename7, "can not overwrite name of existing reference")
must_fail(git_reference_lookup(&ref_one_new, repo, ref_one_name_new));
close_temp_repo(repo);
git_reference_free(ref);
git_reference_free(ref_one);
git_reference_free(ref_one_new);
git_reference_free(ref_two);
END_TEST
static const char *ref_two_name_new = "refs/heads/two/two";
......@@ -748,6 +814,10 @@ BEGIN_TEST(rename8, "can be renamed to a new name prefixed with the old name")
must_fail(git_reference_lookup(&looked_up_ref, repo, ref_two_name));
close_temp_repo(repo);
git_reference_free(ref);
git_reference_free(ref_two);
git_reference_free(looked_up_ref);
END_TEST
BEGIN_TEST(rename9, "can move a reference to a upper reference hierarchy")
......@@ -806,6 +876,8 @@ BEGIN_TEST(delete0, "deleting a ref which is both packed and loose should remove
must_pass(!git_futils_exists(temp_path));
close_temp_repo(repo);
git_reference_free(another_looked_up_ref);
END_TEST
BEGIN_TEST(delete1, "can delete a just packed reference")
......@@ -1132,6 +1204,9 @@ BEGIN_TEST(reflog0, "write a reflog for a given reference and ensure it can be r
git_signature_free(committer);
git_reflog_free(reflog);
close_temp_repo(repo2);
git_reference_free(ref);
git_reference_free(lookedup_ref);
END_TEST
BEGIN_TEST(reflog1, "avoid writing an obviously wrong reflog")
......@@ -1160,6 +1235,8 @@ BEGIN_TEST(reflog1, "avoid writing an obviously wrong reflog")
git_signature_free(committer);
close_temp_repo(repo);
git_reference_free(ref);
END_TEST
BEGIN_SUITE(refs)
......
......@@ -286,6 +286,8 @@ BEGIN_TEST(detached0, "test if HEAD is detached")
must_be_true(git_repository_head_detached(repo) == 0);
git_repository_free(repo);
git_reference_free(ref);
END_TEST
BEGIN_TEST(orphan0, "test if HEAD is orphan")
......@@ -305,6 +307,8 @@ BEGIN_TEST(orphan0, "test if HEAD is orphan")
must_be_true(git_repository_head_orphan(repo) == 0);
git_repository_free(repo);
git_reference_free(ref);
END_TEST
#define DISCOVER_FOLDER TEMP_REPO_FOLDER "discover.git"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment