summaryrefslogtreecommitdiff
path: root/src/refs.c
diff options
context:
space:
mode:
authornulltoken <emeric.fermas@gmail.com>2011-03-03 19:58:07 +0200
committerVicent Marti <tanoku@gmail.com>2011-03-03 20:23:52 +0200
commit5ad0351db1cf4344e0bbf23e27cfb40a5c1d6310 (patch)
treeafc70c67bf62454bf91947581df2dfbde4210c61 /src/refs.c
parentd561403f08ccf792ed457638bf5c4c9638dc7699 (diff)
downloadlibgit2-5ad0351db1cf4344e0bbf23e27cfb40a5c1d6310.tar.gz
Fix reference removal: remove packed refs together with loose ones
Diffstat (limited to 'src/refs.c')
-rw-r--r--src/refs.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/refs.c b/src/refs.c
index 8e24ba80e..90123f1bb 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -1089,15 +1089,18 @@ int git_reference_set_target(git_reference *ref, const char *target)
* operation. We need to remove the reference from
* the memory cache and then rewrite the whole pack
*
- * If the reference is loose, we just remove it on
+ * If the reference is loose, we remove it on
* the filesystem and update the in-memory cache
- * accordingly.
+ * accordingly. We also make sure that an older version
+ * of it doesn't exist as a packed reference. If this
+ * is the case, this packed reference is removed as well.
*
* This obviously invalidates the `ref` pointer.
*/
int git_reference_delete(git_reference *ref)
{
int error;
+ git_reference *reference;
assert(ref);
@@ -1109,8 +1112,19 @@ int git_reference_delete(git_reference *ref)
git__joinpath(full_path, ref->owner->path_repository, ref->name);
git_hashtable_remove(ref->owner->references.loose_cache, ref->name);
error = gitfo_unlink(full_path);
+ if (error < GIT_SUCCESS)
+ goto cleanup;
+
+ /* When deleting a loose reference, we have to ensure that an older
+ * packed version of it doesn't exist
+ */
+ if (!git_repository_lookup_ref(&reference, ref->owner, ref->name)) {
+ assert((reference->type & GIT_REF_PACKED) != 0);
+ error = git_reference_delete(reference);
+ }
}
+cleanup:
reference_free(ref);
return error;
}