Merge branch 'ma/lockfile-cleanup'
[gitweb.git] / refs.c
diff --git a/refs.c b/refs.c
index 10f69da2b859140e5d9bc61b395f737b2458dc6b..7013363a902a4e4aebf6a4cbb2cd4e565230eb93 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -14,6 +14,7 @@
 #include "submodule.h"
 #include "worktree.h"
 #include "argv-array.h"
+#include "repository.h"
 
 /*
  * List of all available backends
@@ -207,7 +208,7 @@ char *refs_resolve_refdup(struct ref_store *refs,
 char *resolve_refdup(const char *refname, int resolve_flags,
                     struct object_id *oid, int *flags)
 {
-       return refs_resolve_refdup(get_main_ref_store(),
+       return refs_resolve_refdup(get_main_ref_store(the_repository),
                                   refname, resolve_flags,
                                   oid, flags);
 }
@@ -229,7 +230,7 @@ int refs_read_ref_full(struct ref_store *refs, const char *refname,
 
 int read_ref_full(const char *refname, int resolve_flags, struct object_id *oid, int *flags)
 {
-       return refs_read_ref_full(get_main_ref_store(), refname,
+       return refs_read_ref_full(get_main_ref_store(the_repository), refname,
                                  resolve_flags, oid, flags);
 }
 
@@ -302,7 +303,7 @@ enum peel_status peel_object(const struct object_id *name, struct object_id *oid
        struct object *o = lookup_unknown_object(name->hash);
 
        if (o->type == OBJ_NONE) {
-               int type = oid_object_info(name, NULL);
+               int type = oid_object_info(the_repository, name, NULL);
                if (type < 0 || !object_as_type(o, type, 0))
                        return PEEL_INVALID;
        }
@@ -376,7 +377,7 @@ int refs_for_each_tag_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
 
 int for_each_tag_ref(each_ref_fn fn, void *cb_data)
 {
-       return refs_for_each_tag_ref(get_main_ref_store(), fn, cb_data);
+       return refs_for_each_tag_ref(get_main_ref_store(the_repository), fn, cb_data);
 }
 
 int refs_for_each_branch_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
@@ -386,7 +387,7 @@ int refs_for_each_branch_ref(struct ref_store *refs, each_ref_fn fn, void *cb_da
 
 int for_each_branch_ref(each_ref_fn fn, void *cb_data)
 {
-       return refs_for_each_branch_ref(get_main_ref_store(), fn, cb_data);
+       return refs_for_each_branch_ref(get_main_ref_store(the_repository), fn, cb_data);
 }
 
 int refs_for_each_remote_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
@@ -396,7 +397,7 @@ int refs_for_each_remote_ref(struct ref_store *refs, each_ref_fn fn, void *cb_da
 
 int for_each_remote_ref(each_ref_fn fn, void *cb_data)
 {
-       return refs_for_each_remote_ref(get_main_ref_store(), fn, cb_data);
+       return refs_for_each_remote_ref(get_main_ref_store(the_repository), fn, cb_data);
 }
 
 int head_ref_namespaced(each_ref_fn fn, void *cb_data)
@@ -614,7 +615,8 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **log)
 static int is_per_worktree_ref(const char *refname)
 {
        return !strcmp(refname, "HEAD") ||
-               starts_with(refname, "refs/bisect/");
+               starts_with(refname, "refs/bisect/") ||
+               starts_with(refname, "refs/rewritten/");
 }
 
 static int is_pseudoref_syntax(const char *refname)
@@ -658,7 +660,7 @@ static int write_pseudoref(const char *pseudoref, const struct object_id *oid,
 {
        const char *filename;
        int fd;
-       static struct lock_file lock;
+       struct lock_file lock = LOCK_INIT;
        struct strbuf buf = STRBUF_INIT;
        int ret = -1;
 
@@ -668,8 +670,7 @@ static int write_pseudoref(const char *pseudoref, const struct object_id *oid,
        strbuf_addf(&buf, "%s\n", oid_to_hex(oid));
 
        filename = git_path("%s", pseudoref);
-       fd = hold_lock_file_for_update_timeout(&lock, filename,
-                                              LOCK_DIE_ON_ERROR,
+       fd = hold_lock_file_for_update_timeout(&lock, filename, 0,
                                               get_files_ref_lock_timeout_ms());
        if (fd < 0) {
                strbuf_addf(err, "could not open '%s' for writing: %s",
@@ -704,20 +705,23 @@ static int write_pseudoref(const char *pseudoref, const struct object_id *oid,
 
 static int delete_pseudoref(const char *pseudoref, const struct object_id *old_oid)
 {
-       static struct lock_file lock;
        const char *filename;
 
        filename = git_path("%s", pseudoref);
 
        if (old_oid && !is_null_oid(old_oid)) {
+               struct lock_file lock = LOCK_INIT;
                int fd;
                struct object_id actual_old_oid;
 
                fd = hold_lock_file_for_update_timeout(
-                               &lock, filename, LOCK_DIE_ON_ERROR,
+                               &lock, filename, 0,
                                get_files_ref_lock_timeout_ms());
-               if (fd < 0)
-                       die_errno(_("Could not open '%s' for writing"), filename);
+               if (fd < 0) {
+                       error_errno(_("could not open '%s' for writing"),
+                                   filename);
+                       return -1;
+               }
                if (read_ref(pseudoref, &actual_old_oid))
                        die("could not read ref '%s'", pseudoref);
                if (oidcmp(&actual_old_oid, old_oid)) {
@@ -744,7 +748,7 @@ int refs_delete_ref(struct ref_store *refs, const char *msg,
        struct strbuf err = STRBUF_INIT;
 
        if (ref_type(refname) == REF_TYPE_PSEUDOREF) {
-               assert(refs == get_main_ref_store());
+               assert(refs == get_main_ref_store(the_repository));
                return delete_pseudoref(refname, old_oid);
        }
 
@@ -766,7 +770,7 @@ int refs_delete_ref(struct ref_store *refs, const char *msg,
 int delete_ref(const char *msg, const char *refname,
               const struct object_id *old_oid, unsigned int flags)
 {
-       return refs_delete_ref(get_main_ref_store(), msg, refname,
+       return refs_delete_ref(get_main_ref_store(the_repository), msg, refname,
                               old_oid, flags);
 }
 
@@ -942,7 +946,7 @@ struct ref_transaction *ref_store_transaction_begin(struct ref_store *refs,
 
 struct ref_transaction *ref_transaction_begin(struct strbuf *err)
 {
-       return ref_store_transaction_begin(get_main_ref_store(), err);
+       return ref_store_transaction_begin(get_main_ref_store(the_repository), err);
 }
 
 void ref_transaction_free(struct ref_transaction *transaction)
@@ -1074,7 +1078,7 @@ int refs_update_ref(struct ref_store *refs, const char *msg,
        int ret = 0;
 
        if (ref_type(refname) == REF_TYPE_PSEUDOREF) {
-               assert(refs == get_main_ref_store());
+               assert(refs == get_main_ref_store(the_repository));
                ret = write_pseudoref(refname, new_oid, old_oid, &err);
        } else {
                t = ref_store_transaction_begin(refs, &err);
@@ -1113,7 +1117,7 @@ int update_ref(const char *msg, const char *refname,
               const struct object_id *old_oid,
               unsigned int flags, enum action_on_err onerr)
 {
-       return refs_update_ref(get_main_ref_store(), msg, refname, new_oid,
+       return refs_update_ref(get_main_ref_store(the_repository), msg, refname, new_oid,
                               old_oid, flags, onerr);
 }
 
@@ -1334,7 +1338,7 @@ int refs_head_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
 
 int head_ref(each_ref_fn fn, void *cb_data)
 {
-       return refs_head_ref(get_main_ref_store(), fn, cb_data);
+       return refs_head_ref(get_main_ref_store(the_repository), fn, cb_data);
 }
 
 struct ref_iterator *refs_ref_iterator_begin(
@@ -1393,7 +1397,7 @@ int refs_for_each_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
 
 int for_each_ref(each_ref_fn fn, void *cb_data)
 {
-       return refs_for_each_ref(get_main_ref_store(), fn, cb_data);
+       return refs_for_each_ref(get_main_ref_store(the_repository), fn, cb_data);
 }
 
 int refs_for_each_ref_in(struct ref_store *refs, const char *prefix,
@@ -1404,7 +1408,7 @@ int refs_for_each_ref_in(struct ref_store *refs, const char *prefix,
 
 int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)
 {
-       return refs_for_each_ref_in(get_main_ref_store(), prefix, fn, cb_data);
+       return refs_for_each_ref_in(get_main_ref_store(the_repository), prefix, fn, cb_data);
 }
 
 int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsigned int broken)
@@ -1413,7 +1417,7 @@ int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsig
 
        if (broken)
                flag = DO_FOR_EACH_INCLUDE_BROKEN;
-       return do_for_each_ref(get_main_ref_store(),
+       return do_for_each_ref(get_main_ref_store(the_repository),
                               prefix, fn, 0, flag, cb_data);
 }
 
@@ -1428,9 +1432,9 @@ int refs_for_each_fullref_in(struct ref_store *refs, const char *prefix,
        return do_for_each_ref(refs, prefix, fn, 0, flag, cb_data);
 }
 
-int for_each_replace_ref(each_ref_fn fn, void *cb_data)
+int for_each_replace_ref(struct repository *r, each_ref_fn fn, void *cb_data)
 {
-       return do_for_each_ref(get_main_ref_store(),
+       return do_for_each_ref(get_main_ref_store(r),
                               git_replace_ref_base, fn,
                               strlen(git_replace_ref_base),
                               DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
@@ -1441,7 +1445,7 @@ int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)
        struct strbuf buf = STRBUF_INIT;
        int ret;
        strbuf_addf(&buf, "%srefs/", get_git_namespace());
-       ret = do_for_each_ref(get_main_ref_store(),
+       ret = do_for_each_ref(get_main_ref_store(the_repository),
                              buf.buf, fn, 0, 0, cb_data);
        strbuf_release(&buf);
        return ret;
@@ -1455,7 +1459,7 @@ int refs_for_each_rawref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
 
 int for_each_rawref(each_ref_fn fn, void *cb_data)
 {
-       return refs_for_each_rawref(get_main_ref_store(), fn, cb_data);
+       return refs_for_each_rawref(get_main_ref_store(the_repository), fn, cb_data);
 }
 
 int refs_read_raw_ref(struct ref_store *ref_store,
@@ -1561,7 +1565,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,
 /* backend functions */
 int refs_init_db(struct strbuf *err)
 {
-       struct ref_store *refs = get_main_ref_store();
+       struct ref_store *refs = get_main_ref_store(the_repository);
 
        return refs->be->init_db(refs, err);
 }
@@ -1569,7 +1573,7 @@ int refs_init_db(struct strbuf *err)
 const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
                               struct object_id *oid, int *flags)
 {
-       return refs_resolve_ref_unsafe(get_main_ref_store(), refname,
+       return refs_resolve_ref_unsafe(get_main_ref_store(the_repository), refname,
                                       resolve_flags, oid, flags);
 }
 
@@ -1621,9 +1625,6 @@ static struct ref_store_hash_entry *alloc_ref_store_hash_entry(
        return entry;
 }
 
-/* A pointer to the ref_store for the main repository: */
-static struct ref_store *main_ref_store;
-
 /* A hashmap of ref_stores, stored by submodule name: */
 static struct hashmap submodule_ref_stores;
 
@@ -1665,13 +1666,16 @@ static struct ref_store *ref_store_init(const char *gitdir,
        return refs;
 }
 
-struct ref_store *get_main_ref_store(void)
+struct ref_store *get_main_ref_store(struct repository *r)
 {
-       if (main_ref_store)
-               return main_ref_store;
+       if (r->refs)
+               return r->refs;
+
+       if (!r->gitdir)
+               BUG("attempting to get main_ref_store outside of repository");
 
-       main_ref_store = ref_store_init(get_git_dir(), REF_STORE_ALL_CAPS);
-       return main_ref_store;
+       r->refs = ref_store_init(r->gitdir, REF_STORE_ALL_CAPS);
+       return r->refs;
 }
 
 /*
@@ -1740,7 +1744,7 @@ struct ref_store *get_worktree_ref_store(const struct worktree *wt)
        const char *id;
 
        if (wt->is_current)
-               return get_main_ref_store();
+               return get_main_ref_store(the_repository);
 
        id = wt->id ? wt->id : "/";
        refs = lookup_ref_store_map(&worktree_ref_stores, id);
@@ -1796,7 +1800,7 @@ int refs_peel_ref(struct ref_store *refs, const char *refname,
 
 int peel_ref(const char *refname, struct object_id *oid)
 {
-       return refs_peel_ref(get_main_ref_store(), refname, oid);
+       return refs_peel_ref(get_main_ref_store(the_repository), refname, oid);
 }
 
 int refs_create_symref(struct ref_store *refs,
@@ -1812,7 +1816,7 @@ int refs_create_symref(struct ref_store *refs,
 int create_symref(const char *ref_target, const char *refs_heads_master,
                  const char *logmsg)
 {
-       return refs_create_symref(get_main_ref_store(), ref_target,
+       return refs_create_symref(get_main_ref_store(the_repository), ref_target,
                                  refs_heads_master, logmsg);
 }
 
@@ -2020,7 +2024,7 @@ int refs_for_each_reflog(struct ref_store *refs, each_ref_fn fn, void *cb_data)
 
 int for_each_reflog(each_ref_fn fn, void *cb_data)
 {
-       return refs_for_each_reflog(get_main_ref_store(), fn, cb_data);
+       return refs_for_each_reflog(get_main_ref_store(the_repository), fn, cb_data);
 }
 
 int refs_for_each_reflog_ent_reverse(struct ref_store *refs,
@@ -2035,7 +2039,7 @@ int refs_for_each_reflog_ent_reverse(struct ref_store *refs,
 int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn,
                                void *cb_data)
 {
-       return refs_for_each_reflog_ent_reverse(get_main_ref_store(),
+       return refs_for_each_reflog_ent_reverse(get_main_ref_store(the_repository),
                                                refname, fn, cb_data);
 }
 
@@ -2048,7 +2052,7 @@ int refs_for_each_reflog_ent(struct ref_store *refs, const char *refname,
 int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn,
                        void *cb_data)
 {
-       return refs_for_each_reflog_ent(get_main_ref_store(), refname,
+       return refs_for_each_reflog_ent(get_main_ref_store(the_repository), refname,
                                        fn, cb_data);
 }
 
@@ -2059,7 +2063,7 @@ int refs_reflog_exists(struct ref_store *refs, const char *refname)
 
 int reflog_exists(const char *refname)
 {
-       return refs_reflog_exists(get_main_ref_store(), refname);
+       return refs_reflog_exists(get_main_ref_store(the_repository), refname);
 }
 
 int refs_create_reflog(struct ref_store *refs, const char *refname,
@@ -2071,7 +2075,7 @@ int refs_create_reflog(struct ref_store *refs, const char *refname,
 int safe_create_reflog(const char *refname, int force_create,
                       struct strbuf *err)
 {
-       return refs_create_reflog(get_main_ref_store(), refname,
+       return refs_create_reflog(get_main_ref_store(the_repository), refname,
                                  force_create, err);
 }
 
@@ -2082,7 +2086,7 @@ int refs_delete_reflog(struct ref_store *refs, const char *refname)
 
 int delete_reflog(const char *refname)
 {
-       return refs_delete_reflog(get_main_ref_store(), refname);
+       return refs_delete_reflog(get_main_ref_store(the_repository), refname);
 }
 
 int refs_reflog_expire(struct ref_store *refs,
@@ -2105,7 +2109,7 @@ int reflog_expire(const char *refname, const struct object_id *oid,
                  reflog_expiry_cleanup_fn cleanup_fn,
                  void *policy_cb_data)
 {
-       return refs_reflog_expire(get_main_ref_store(),
+       return refs_reflog_expire(get_main_ref_store(the_repository),
                                  refname, oid, flags,
                                  prepare_fn, should_prune_fn,
                                  cleanup_fn, policy_cb_data);
@@ -2128,7 +2132,7 @@ int refs_delete_refs(struct ref_store *refs, const char *msg,
 int delete_refs(const char *msg, struct string_list *refnames,
                unsigned int flags)
 {
-       return refs_delete_refs(get_main_ref_store(), msg, refnames, flags);
+       return refs_delete_refs(get_main_ref_store(the_repository), msg, refnames, flags);
 }
 
 int refs_rename_ref(struct ref_store *refs, const char *oldref,
@@ -2139,7 +2143,7 @@ int refs_rename_ref(struct ref_store *refs, const char *oldref,
 
 int rename_ref(const char *oldref, const char *newref, const char *logmsg)
 {
-       return refs_rename_ref(get_main_ref_store(), oldref, newref, logmsg);
+       return refs_rename_ref(get_main_ref_store(the_repository), oldref, newref, logmsg);
 }
 
 int refs_copy_existing_ref(struct ref_store *refs, const char *oldref,
@@ -2150,5 +2154,5 @@ int refs_copy_existing_ref(struct ref_store *refs, const char *oldref,
 
 int copy_existing_ref(const char *oldref, const char *newref, const char *logmsg)
 {
-       return refs_copy_existing_ref(get_main_ref_store(), oldref, newref, logmsg);
+       return refs_copy_existing_ref(get_main_ref_store(the_repository), oldref, newref, logmsg);
 }