clone: release strbuf after use in remove_junk()
[gitweb.git] / refs / files-backend.c
index 7df974779858db1e6182ebf01f8e9621dece14a1..fccbc24ac4ad3631b96a4796f4b1f89913fa0ea3 100644 (file)
@@ -1,4 +1,5 @@
 #include "../cache.h"
+#include "../config.h"
 #include "../refs.h"
 #include "refs-internal.h"
 #include "ref-cache.h"
@@ -28,7 +29,7 @@ struct files_ref_store {
 
        struct ref_cache *loose;
 
-       struct packed_ref_store *packed_ref_store;
+       struct ref_store *packed_ref_store;
 };
 
 static void clear_loose_ref_cache(struct files_ref_store *refs)
@@ -311,8 +312,8 @@ static int files_read_raw_ref(struct ref_store *ref_store,
        if (lstat(path, &st) < 0) {
                if (errno != ENOENT)
                        goto out;
-               if (packed_read_raw_ref(refs->packed_ref_store, refname,
-                                       sha1, referent, type)) {
+               if (refs_read_raw_ref(refs->packed_ref_store, refname,
+                                     sha1, referent, type)) {
                        errno = ENOENT;
                        goto out;
                }
@@ -351,8 +352,8 @@ static int files_read_raw_ref(struct ref_store *ref_store,
                 * ref is supposed to be, there could still be a
                 * packed ref:
                 */
-               if (packed_read_raw_ref(refs->packed_ref_store, refname,
-                                       sha1, referent, type)) {
+               if (refs_read_raw_ref(refs->packed_ref_store, refname,
+                                     sha1, referent, type)) {
                        errno = EISDIR;
                        goto out;
                }
@@ -536,7 +537,9 @@ static int lock_raw_ref(struct files_ref_store *refs,
        if (!lock->lk)
                lock->lk = xcalloc(1, sizeof(struct lock_file));
 
-       if (hold_lock_file_for_update(lock->lk, ref_file.buf, LOCK_NO_DEREF) < 0) {
+       if (hold_lock_file_for_update_timeout(
+                           lock->lk, ref_file.buf, LOCK_NO_DEREF,
+                           get_files_ref_lock_timeout_ms()) < 0) {
                if (errno == ENOENT && --attempts_remaining > 0) {
                        /*
                         * Maybe somebody just deleted one of the
@@ -631,11 +634,11 @@ static int lock_raw_ref(struct files_ref_store *refs,
 
                /*
                 * If the ref did not exist and we are creating it,
-                * make sure there is no existing ref that conflicts
-                * with refname:
+                * make sure there is no existing packed ref that
+                * conflicts with refname:
                 */
                if (refs_verify_refname_available(
-                                   &refs->base, refname,
+                                   refs->packed_ref_store, refname,
                                    extras, skip, err))
                        goto error_return;
        }
@@ -683,7 +686,7 @@ static int files_peel_ref(struct ref_store *ref_store,
         * have REF_KNOWS_PEELED.
         */
        if (flag & REF_ISPACKED &&
-           !packed_peel_ref(refs->packed_ref_store, refname, sha1))
+           !refs_peel_ref(refs->packed_ref_store, refname, sha1))
                return 0;
 
        return peel_object(base, sha1);
@@ -804,8 +807,8 @@ static struct ref_iterator *files_ref_iterator_begin(
         * ones in files_ref_iterator_advance(), after we have merged
         * the packed and loose references.
         */
-       packed_iter = packed_ref_iterator_begin(
-                       refs->packed_ref_store, prefix,
+       packed_iter = refs_ref_iterator_begin(
+                       refs->packed_ref_store, prefix, 0,
                        DO_FOR_EACH_INCLUDE_BROKEN);
 
        iter->iter0 = overlay_ref_iterator_begin(loose_iter, packed_iter);
@@ -864,7 +867,9 @@ static int create_reflock(const char *path, void *cb)
 {
        struct lock_file *lk = cb;
 
-       return hold_lock_file_for_update(lk, path, LOCK_NO_DEREF) < 0 ? -1 : 0;
+       return hold_lock_file_for_update_timeout(
+                       lk, path, LOCK_NO_DEREF,
+                       get_files_ref_lock_timeout_ms()) < 0 ? -1 : 0;
 }
 
 /*
@@ -938,7 +943,7 @@ static struct ref_lock *lock_ref_sha1_basic(struct files_ref_store *refs,
         * our refname.
         */
        if (is_null_oid(&lock->old_oid) &&
-           refs_verify_refname_available(&refs->base, refname,
+           refs_verify_refname_available(refs->packed_ref_store, refname,
                                          extras, skip, err)) {
                last_errno = ENOTDIR;
                goto error_return;
@@ -1094,8 +1099,9 @@ static int files_pack_refs(struct ref_store *ref_store, unsigned int flags)
        struct ref_iterator *iter;
        int ok;
        struct ref_to_prune *refs_to_prune = NULL;
+       struct strbuf err = STRBUF_INIT;
 
-       lock_packed_refs(refs->packed_ref_store, LOCK_DIE_ON_ERROR);
+       packed_refs_lock(refs->packed_ref_store, LOCK_DIE_ON_ERROR, &err);
 
        iter = cache_ref_iterator_begin(get_loose_ref_cache(refs), NULL, 0);
        while ((ok = ref_iterator_advance(iter)) == ITER_OK) {
@@ -1128,10 +1134,12 @@ static int files_pack_refs(struct ref_store *ref_store, unsigned int flags)
        if (ok != ITER_DONE)
                die("error while iterating over references");
 
-       if (commit_packed_refs(refs->packed_ref_store))
-               die_errno("unable to overwrite old ref-pack file");
+       if (commit_packed_refs(refs->packed_ref_store, &err))
+               die("unable to overwrite old ref-pack file: %s", err.buf);
+       packed_refs_unlock(refs->packed_ref_store);
 
        prune_refs(refs, refs_to_prune);
+       strbuf_release(&err);
        return 0;
 }
 
@@ -1146,24 +1154,16 @@ static int files_delete_refs(struct ref_store *ref_store, const char *msg,
        if (!refnames->nr)
                return 0;
 
-       result = repack_without_refs(refs->packed_ref_store, refnames, &err);
-       if (result) {
-               /*
-                * If we failed to rewrite the packed-refs file, then
-                * it is unsafe to try to remove loose refs, because
-                * doing so might expose an obsolete packed value for
-                * a reference that might even point at an object that
-                * has been garbage collected.
-                */
-               if (refnames->nr == 1)
-                       error(_("could not delete reference %s: %s"),
-                             refnames->items[0].string, err.buf);
-               else
-                       error(_("could not delete references: %s"), err.buf);
+       if (packed_refs_lock(refs->packed_ref_store, 0, &err))
+               goto error;
 
-               goto out;
+       if (repack_without_refs(refs->packed_ref_store, refnames, &err)) {
+               packed_refs_unlock(refs->packed_ref_store);
+               goto error;
        }
 
+       packed_refs_unlock(refs->packed_ref_store);
+
        for (i = 0; i < refnames->nr; i++) {
                const char *refname = refnames->items[i].string;
 
@@ -1171,9 +1171,24 @@ static int files_delete_refs(struct ref_store *ref_store, const char *msg,
                        result |= error(_("could not remove reference %s"), refname);
        }
 
-out:
        strbuf_release(&err);
        return result;
+
+error:
+       /*
+        * If we failed to rewrite the packed-refs file, then it is
+        * unsafe to try to remove loose refs, because doing so might
+        * expose an obsolete packed value for a reference that might
+        * even point at an object that has been garbage collected.
+        */
+       if (refnames->nr == 1)
+               error(_("could not delete reference %s: %s"),
+                     refnames->items[0].string, err.buf);
+       else
+               error(_("could not delete references: %s"), err.buf);
+
+       strbuf_release(&err);
+       return -1;
 }
 
 /*
@@ -2454,8 +2469,7 @@ static int files_transaction_prepare(struct ref_store *ref_store,
                                       head_oid.hash, &head_type);
 
        if (head_ref && !(head_type & REF_ISSYMREF)) {
-               free(head_ref);
-               head_ref = NULL;
+               FREE_AND_NULL(head_ref);
        }
 
        /*
@@ -2566,11 +2580,19 @@ static int files_transaction_finish(struct ref_store *ref_store,
                }
        }
 
+       if (packed_refs_lock(refs->packed_ref_store, 0, err)) {
+               ret = TRANSACTION_GENERIC_ERROR;
+               goto cleanup;
+       }
+
        if (repack_without_refs(refs->packed_ref_store, &refs_to_delete, err)) {
                ret = TRANSACTION_GENERIC_ERROR;
+               packed_refs_unlock(refs->packed_ref_store);
                goto cleanup;
        }
 
+       packed_refs_unlock(refs->packed_ref_store);
+
        /* Delete the reflogs of any references that were deleted: */
        for_each_string_list_item(ref_to_delete, &refs_to_delete) {
                strbuf_reset(&sb);
@@ -2677,9 +2699,7 @@ static int files_initial_transaction_commit(struct ref_store *ref_store,
                }
        }
 
-       if (lock_packed_refs(refs->packed_ref_store, 0)) {
-               strbuf_addf(err, "unable to lock packed-refs file: %s",
-                           strerror(errno));
+       if (packed_refs_lock(refs->packed_ref_store, 0, err)) {
                ret = TRANSACTION_GENERIC_ERROR;
                goto cleanup;
        }
@@ -2693,14 +2713,13 @@ static int files_initial_transaction_commit(struct ref_store *ref_store,
                                       &update->new_oid);
        }
 
-       if (commit_packed_refs(refs->packed_ref_store)) {
-               strbuf_addf(err, "unable to commit packed-refs file: %s",
-                           strerror(errno));
+       if (commit_packed_refs(refs->packed_ref_store, err)) {
                ret = TRANSACTION_GENERIC_ERROR;
                goto cleanup;
        }
 
 cleanup:
+       packed_refs_unlock(refs->packed_ref_store);
        transaction->state = REF_TRANSACTION_CLOSED;
        string_list_clear(&affected_refnames, 0);
        return ret;