Merge branch 'sv/doc-stripspace'
[gitweb.git] / refs.c
diff --git a/refs.c b/refs.c
index 0368ed461f3ef913a60da322247bca0f9d121a82..898d3c2ca4685a7ea47fbd3e34a384a77a1dea8a 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -2318,6 +2318,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
 
        lock->lock_fd = hold_lock_file_for_update(lock->lk, ref_file, lflags);
        if (lock->lock_fd < 0) {
+               last_errno = errno;
                if (errno == ENOENT && --attempts_remaining > 0)
                        /*
                         * Maybe somebody just deleted one of the
@@ -2325,8 +2326,13 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
                         * again:
                         */
                        goto retry;
-               else
-                       unable_to_lock_die(ref_file, errno);
+               else {
+                       struct strbuf err = STRBUF_INIT;
+                       unable_to_lock_message(ref_file, errno, &err);
+                       error("%s", err.buf);
+                       strbuf_reset(&err);
+                       goto error_return;
+               }
        }
        return old_sha1 ? verify_lock(lock, old_sha1, mustexist) : lock;
 
@@ -2639,22 +2645,25 @@ static int curate_packed_ref_fn(struct ref_entry *entry, void *cb_data)
        return 0;
 }
 
-int repack_without_refs(const char **refnames, int n, struct strbuf *err)
+int repack_without_refs(struct string_list *refnames, struct strbuf *err)
 {
        struct ref_dir *packed;
        struct string_list refs_to_delete = STRING_LIST_INIT_DUP;
-       struct string_list_item *ref_to_delete;
-       int i, ret, removed = 0;
+       struct string_list_item *refname, *ref_to_delete;
+       int ret, needs_repacking = 0, removed = 0;
 
        assert(err);
 
        /* Look for a packed ref */
-       for (i = 0; i < n; i++)
-               if (get_packed_ref(refnames[i]))
+       for_each_string_list_item(refname, refnames) {
+               if (get_packed_ref(refname->string)) {
+                       needs_repacking = 1;
                        break;
+               }
+       }
 
        /* Avoid locking if we have nothing to do */
-       if (i == n)
+       if (!needs_repacking)
                return 0; /* no refname exists in packed refs */
 
        if (lock_packed_refs(0)) {
@@ -2664,8 +2673,8 @@ int repack_without_refs(const char **refnames, int n, struct strbuf *err)
        packed = get_packed_refs(&ref_cache);
 
        /* Remove refnames from the cache */
-       for (i = 0; i < n; i++)
-               if (remove_entry(packed, refnames[i]) != -1)
+       for_each_string_list_item(refname, refnames)
+               if (remove_entry(packed, refname->string) != -1)
                        removed = 1;
        if (!removed) {
                /*
@@ -2962,10 +2971,10 @@ int log_ref_setup(const char *refname, char *logfile, int bufsize)
 
        logfd = open(logfile, oflags, 0666);
        if (logfd < 0) {
-               if (!(oflags & O_CREAT) && errno == ENOENT)
+               if (!(oflags & O_CREAT) && (errno == ENOENT || errno == EISDIR))
                        return 0;
 
-               if ((oflags & O_CREAT) && errno == EISDIR) {
+               if (errno == EISDIR) {
                        if (remove_empty_directories(logfile)) {
                                int save_errno = errno;
                                error("There are still logs under '%s'",
@@ -3738,10 +3747,11 @@ static int ref_update_reject_duplicates(struct ref_update **updates, int n,
 int ref_transaction_commit(struct ref_transaction *transaction,
                           struct strbuf *err)
 {
-       int ret = 0, delnum = 0, i;
-       const char **delnames;
+       int ret = 0, i;
        int n = transaction->nr;
        struct ref_update **updates = transaction->updates;
+       struct string_list refs_to_delete = STRING_LIST_INIT_NODUP;
+       struct string_list_item *ref_to_delete;
 
        assert(err);
 
@@ -3753,9 +3763,6 @@ int ref_transaction_commit(struct ref_transaction *transaction,
                return 0;
        }
 
-       /* Allocate work space */
-       delnames = xmalloc(sizeof(*delnames) * n);
-
        /* Copy, sort, and reject duplicate refs */
        qsort(updates, n, sizeof(*updates), ref_update_compare);
        if (ref_update_reject_duplicates(updates, n, err)) {
@@ -3815,16 +3822,17 @@ int ref_transaction_commit(struct ref_transaction *transaction,
                        }
 
                        if (!(update->flags & REF_ISPRUNING))
-                               delnames[delnum++] = update->lock->ref_name;
+                               string_list_append(&refs_to_delete,
+                                                  update->lock->ref_name);
                }
        }
 
-       if (repack_without_refs(delnames, delnum, err)) {
+       if (repack_without_refs(&refs_to_delete, err)) {
                ret = TRANSACTION_GENERIC_ERROR;
                goto cleanup;
        }
-       for (i = 0; i < delnum; i++)
-               unlink_or_warn(git_path("logs/%s", delnames[i]));
+       for_each_string_list_item(ref_to_delete, &refs_to_delete)
+               unlink_or_warn(git_path("logs/%s", ref_to_delete->string));
        clear_loose_ref_cache(&ref_cache);
 
 cleanup:
@@ -3833,7 +3841,7 @@ int ref_transaction_commit(struct ref_transaction *transaction,
        for (i = 0; i < n; i++)
                if (updates[i]->lock)
                        unlock_ref(updates[i]->lock);
-       free(delnames);
+       string_list_clear(&refs_to_delete, 0);
        return ret;
 }