diff options
| author | nulltoken <emeric.fermas@gmail.com> | 2011-03-03 19:58:07 +0200 |
|---|---|---|
| committer | Vicent Marti <tanoku@gmail.com> | 2011-03-03 20:23:52 +0200 |
| commit | 5ad0351db1cf4344e0bbf23e27cfb40a5c1d6310 (patch) | |
| tree | afc70c67bf62454bf91947581df2dfbde4210c61 /src/refs.c | |
| parent | d561403f08ccf792ed457638bf5c4c9638dc7699 (diff) | |
| download | libgit2-5ad0351db1cf4344e0bbf23e27cfb40a5c1d6310.tar.gz | |
Fix reference removal: remove packed refs together with loose ones
Diffstat (limited to 'src/refs.c')
| -rw-r--r-- | src/refs.c | 18 |
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; } |
