summaryrefslogtreecommitdiff
path: root/refs
diff options
context:
space:
mode:
Diffstat (limited to 'refs')
-rw-r--r--refs/files-backend.c169
-rw-r--r--refs/packed-backend.c20
-rw-r--r--refs/packed-backend.h4
-rw-r--r--refs/ref-cache.c10
-rw-r--r--refs/ref-cache.h1
-rw-r--r--refs/refs-internal.h37
6 files changed, 157 insertions, 84 deletions
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 6a6ead0b99..4b14f30d48 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -79,13 +79,15 @@ static void clear_loose_ref_cache(struct files_ref_store *refs)
* Create a new submodule ref cache and add it to the internal
* set of caches.
*/
-static struct ref_store *files_ref_store_create(const char *gitdir,
+static struct ref_store *files_ref_store_create(struct repository *repo,
+ const char *gitdir,
unsigned int flags)
{
struct files_ref_store *refs = xcalloc(1, sizeof(*refs));
struct ref_store *ref_store = (struct ref_store *)refs;
struct strbuf sb = STRBUF_INIT;
+ ref_store->repo = repo;
ref_store->gitdir = xstrdup(gitdir);
base_ref_store_init(ref_store, &refs_be_files);
refs->store_flags = flags;
@@ -93,7 +95,7 @@ static struct ref_store *files_ref_store_create(const char *gitdir,
get_common_dir_noenv(&sb, gitdir);
refs->gitcommondir = strbuf_detach(&sb, NULL);
strbuf_addf(&sb, "%s/packed-refs", refs->gitcommondir);
- refs->packed_ref_store = packed_ref_store_create(sb.buf, flags);
+ refs->packed_ref_store = packed_ref_store_create(repo, sb.buf, flags);
strbuf_release(&sb);
chdir_notify_reparent("files-backend $GIT_DIR", &refs->base.gitdir);
@@ -280,10 +282,11 @@ static void loose_fill_ref_dir(struct ref_store *ref_store,
create_dir_entry(dir->cache, refname.buf,
refname.len));
} else {
+ int ignore_errno;
if (!refs_resolve_ref_unsafe(&refs->base,
refname.buf,
RESOLVE_REF_READING,
- &oid, &flag)) {
+ &oid, &flag, &ignore_errno)) {
oidclr(&oid);
flag |= REF_ISBROKEN;
} else if (is_null_oid(&oid)) {
@@ -355,6 +358,7 @@ static int files_read_raw_ref(struct ref_store *ref_store, const char *refname,
int fd;
int ret = -1;
int remaining_retries = 3;
+ int myerr = 0;
*type = 0;
strbuf_reset(&sb_path);
@@ -381,11 +385,14 @@ stat_ref:
goto out;
if (lstat(path, &st) < 0) {
- if (errno != ENOENT)
+ int ignore_errno;
+ myerr = errno;
+ errno = 0;
+ if (myerr != ENOENT)
goto out;
- if (refs_read_raw_ref(refs->packed_ref_store, refname,
- oid, referent, type)) {
- errno = ENOENT;
+ if (refs_read_raw_ref(refs->packed_ref_store, refname, oid,
+ referent, type, &ignore_errno)) {
+ myerr = ENOENT;
goto out;
}
ret = 0;
@@ -396,7 +403,9 @@ stat_ref:
if (S_ISLNK(st.st_mode)) {
strbuf_reset(&sb_contents);
if (strbuf_readlink(&sb_contents, path, st.st_size) < 0) {
- if (errno == ENOENT || errno == EINVAL)
+ myerr = errno;
+ errno = 0;
+ if (myerr == ENOENT || myerr == EINVAL)
/* inconsistent with lstat; retry */
goto stat_ref;
else
@@ -418,14 +427,15 @@ stat_ref:
/* Is it a directory? */
if (S_ISDIR(st.st_mode)) {
+ int ignore_errno;
/*
* Even though there is a directory where the loose
* ref is supposed to be, there could still be a
* packed ref:
*/
- if (refs_read_raw_ref(refs->packed_ref_store, refname,
- oid, referent, type)) {
- errno = EISDIR;
+ if (refs_read_raw_ref(refs->packed_ref_store, refname, oid,
+ referent, type, &ignore_errno)) {
+ myerr = EISDIR;
goto out;
}
ret = 0;
@@ -438,7 +448,8 @@ stat_ref:
*/
fd = open(path, O_RDONLY);
if (fd < 0) {
- if (errno == ENOENT && !S_ISLNK(st.st_mode))
+ myerr = errno;
+ if (myerr == ENOENT && !S_ISLNK(st.st_mode))
/* inconsistent with lstat; retry */
goto stat_ref;
else
@@ -446,26 +457,29 @@ stat_ref:
}
strbuf_reset(&sb_contents);
if (strbuf_read(&sb_contents, fd, 256) < 0) {
- int save_errno = errno;
+ myerr = errno;
close(fd);
- errno = save_errno;
goto out;
}
close(fd);
strbuf_rtrim(&sb_contents);
buf = sb_contents.buf;
- ret = parse_loose_ref_contents(buf, oid, referent, type);
+ ret = parse_loose_ref_contents(buf, oid, referent, type, &myerr);
out:
- *failure_errno = errno;
+ if (ret && !myerr)
+ BUG("returning non-zero %d, should have set myerr!", ret);
+ *failure_errno = myerr;
+
strbuf_release(&sb_path);
strbuf_release(&sb_contents);
return ret;
}
int parse_loose_ref_contents(const char *buf, struct object_id *oid,
- struct strbuf *referent, unsigned int *type)
+ struct strbuf *referent, unsigned int *type,
+ int *failure_errno)
{
const char *p;
if (skip_prefix(buf, "ref:", &buf)) {
@@ -484,7 +498,7 @@ int parse_loose_ref_contents(const char *buf, struct object_id *oid,
if (parse_oid_hex(buf, oid, &p) ||
(*p != '\0' && !isspace(*p))) {
*type |= REF_ISBROKEN;
- errno = EINVAL;
+ *failure_errno = EINVAL;
return -1;
}
return 0;
@@ -730,6 +744,7 @@ struct files_ref_iterator {
struct ref_iterator base;
struct ref_iterator *iter0;
+ struct repository *repo;
unsigned int flags;
};
@@ -751,6 +766,7 @@ static int files_ref_iterator_advance(struct ref_iterator *ref_iterator)
if (!(iter->flags & DO_FOR_EACH_INCLUDE_BROKEN) &&
!ref_resolves_to_object(iter->iter0->refname,
+ iter->repo,
iter->iter0->oid,
iter->iter0->flags))
continue;
@@ -829,7 +845,7 @@ static struct ref_iterator *files_ref_iterator_begin(
*/
loose_iter = cache_ref_iterator_begin(get_loose_ref_cache(refs),
- prefix, 1);
+ prefix, ref_store->repo, 1);
/*
* The packed-refs file might contain broken references, for
@@ -853,6 +869,7 @@ static struct ref_iterator *files_ref_iterator_begin(
base_ref_iterator_init(ref_iterator, &files_ref_iterator_vtable,
overlay_iter->ordered);
iter->iter0 = overlay_iter;
+ iter->repo = ref_store->repo;
iter->flags = flags;
return ref_iterator;
@@ -990,11 +1007,12 @@ static int create_reflock(const char *path, void *cb)
* Locks a ref returning the lock on success and NULL on failure.
*/
static struct ref_lock *lock_ref_oid_basic(struct files_ref_store *refs,
- const char *refname, int *type,
+ const char *refname,
struct strbuf *err)
{
struct strbuf ref_file = STRBUF_INIT;
struct ref_lock *lock;
+ int ignore_errno;
files_assert_main_repository(refs, "lock_ref_oid_basic");
assert(err);
@@ -1002,16 +1020,6 @@ static struct ref_lock *lock_ref_oid_basic(struct files_ref_store *refs,
CALLOC_ARRAY(lock, 1);
files_ref_path(refs, &ref_file, refname);
- if (!refs_resolve_ref_unsafe(&refs->base, refname,
- RESOLVE_REF_NO_RECURSE,
- &lock->old_oid, type)) {
- if (!refs_verify_refname_available(&refs->base, refname,
- NULL, NULL, err))
- strbuf_addf(err, "unable to resolve reference '%s': %s",
- refname, strerror(errno));
-
- goto error_return;
- }
/*
* If the ref did not exist and we are creating it, make sure
@@ -1031,9 +1039,8 @@ static struct ref_lock *lock_ref_oid_basic(struct files_ref_store *refs,
goto error_return;
}
- if (refs_read_ref_full(&refs->base, lock->ref_name,
- 0,
- &lock->old_oid, NULL))
+ if (!refs_resolve_ref_unsafe(&refs->base, lock->ref_name, 0,
+ &lock->old_oid, NULL, &ignore_errno))
oidclr(&lock->old_oid);
goto out;
@@ -1169,7 +1176,7 @@ static int should_pack_ref(const char *refname,
return 0;
/* Do not pack broken refs: */
- if (!ref_resolves_to_object(refname, oid, ref_flags))
+ if (!ref_resolves_to_object(refname, the_repository, oid, ref_flags))
return 0;
return 1;
@@ -1192,7 +1199,8 @@ static int files_pack_refs(struct ref_store *ref_store, unsigned int flags)
packed_refs_lock(refs->packed_ref_store, LOCK_DIE_ON_ERROR, &err);
- iter = cache_ref_iterator_begin(get_loose_ref_cache(refs), NULL, 0);
+ iter = cache_ref_iterator_begin(get_loose_ref_cache(refs), NULL,
+ the_repository, 0);
while ((ok = ref_iterator_advance(iter)) == ITER_OK) {
/*
* If the loose reference can be packed, add an entry
@@ -1352,6 +1360,35 @@ static int commit_ref_update(struct files_ref_store *refs,
const struct object_id *oid, const char *logmsg,
struct strbuf *err);
+/*
+ * Emit a better error message than lockfile.c's
+ * unable_to_lock_message() would in case there is a D/F conflict with
+ * another existing reference. If there would be a conflict, emit an error
+ * message and return false; otherwise, return true.
+ *
+ * Note that this function is not safe against all races with other
+ * processes, and that's not its job. We'll emit a more verbose error on D/f
+ * conflicts if we get past it into lock_ref_oid_basic().
+ */
+static int refs_rename_ref_available(struct ref_store *refs,
+ const char *old_refname,
+ const char *new_refname)
+{
+ struct string_list skip = STRING_LIST_INIT_NODUP;
+ struct strbuf err = STRBUF_INIT;
+ int ok;
+
+ string_list_insert(&skip, old_refname);
+ ok = !refs_verify_refname_available(refs, new_refname,
+ NULL, &skip, &err);
+ if (!ok)
+ error("%s", err.buf);
+
+ string_list_clear(&skip, 0);
+ strbuf_release(&err);
+ return ok;
+}
+
static int files_copy_or_rename_ref(struct ref_store *ref_store,
const char *oldrefname, const char *newrefname,
const char *logmsg, int copy)
@@ -1367,6 +1404,7 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store,
struct strbuf tmp_renamed_log = STRBUF_INIT;
int log, ret;
struct strbuf err = STRBUF_INIT;
+ int ignore_errno;
files_reflog_path(refs, &sb_oldref, oldrefname);
files_reflog_path(refs, &sb_newref, newrefname);
@@ -1380,7 +1418,7 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store,
if (!refs_resolve_ref_unsafe(&refs->base, oldrefname,
RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
- &orig_oid, &flag)) {
+ &orig_oid, &flag, &ignore_errno)) {
ret = error("refname %s not found", oldrefname);
goto out;
}
@@ -1424,9 +1462,9 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store,
* the safety anyway; we want to delete the reference whatever
* its current value.
*/
- if (!copy && !refs_read_ref_full(&refs->base, newrefname,
- RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
- NULL, NULL) &&
+ if (!copy && refs_resolve_ref_unsafe(&refs->base, newrefname,
+ RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
+ NULL, NULL, &ignore_errno) &&
refs_delete_ref(&refs->base, NULL, newrefname,
NULL, REF_NO_DEREF)) {
if (errno == EISDIR) {
@@ -1452,7 +1490,7 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store,
logmoved = log;
- lock = lock_ref_oid_basic(refs, newrefname, NULL, &err);
+ lock = lock_ref_oid_basic(refs, newrefname, &err);
if (!lock) {
if (copy)
error("unable to copy '%s' to '%s': %s", oldrefname, newrefname, err.buf);
@@ -1474,7 +1512,7 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store,
goto out;
rollback:
- lock = lock_ref_oid_basic(refs, oldrefname, NULL, &err);
+ lock = lock_ref_oid_basic(refs, oldrefname, &err);
if (!lock) {
error("unable to lock %s for rollback: %s", oldrefname, err.buf);
strbuf_release(&err);
@@ -1791,10 +1829,12 @@ static int commit_ref_update(struct files_ref_store *refs,
*/
int head_flag;
const char *head_ref;
+ int ignore_errno;
head_ref = refs_resolve_ref_unsafe(&refs->base, "HEAD",
RESOLVE_REF_READING,
- NULL, &head_flag);
+ NULL, &head_flag,
+ &ignore_errno);
if (head_ref && (head_flag & REF_ISSYMREF) &&
!strcmp(head_ref, lock->ref_name)) {
struct strbuf log_err = STRBUF_INIT;
@@ -1838,9 +1878,12 @@ static void update_symref_reflog(struct files_ref_store *refs,
{
struct strbuf err = STRBUF_INIT;
struct object_id new_oid;
+ int ignore_errno;
+
if (logmsg &&
- !refs_read_ref_full(&refs->base, target,
- RESOLVE_REF_READING, &new_oid, NULL) &&
+ refs_resolve_ref_unsafe(&refs->base, target,
+ RESOLVE_REF_READING, &new_oid, NULL,
+ &ignore_errno) &&
files_log_ref_write(refs, refname, &lock->old_oid,
&new_oid, logmsg, 0, &err)) {
error("%s", err.buf);
@@ -1881,7 +1924,7 @@ static int files_create_symref(struct ref_store *ref_store,
struct ref_lock *lock;
int ret;
- lock = lock_ref_oid_basic(refs, refname, NULL, &err);
+ lock = lock_ref_oid_basic(refs, refname, &err);
if (!lock) {
error("%s", err.buf);
strbuf_release(&err);
@@ -2114,6 +2157,7 @@ static int files_reflog_iterator_advance(struct ref_iterator *ref_iterator)
(struct files_reflog_iterator *)ref_iterator;
struct dir_iterator *diter = iter->dir_iterator;
int ok;
+ int ignore_errno;
while ((ok = dir_iterator_advance(diter)) == ITER_OK) {
int flags;
@@ -2125,9 +2169,10 @@ static int files_reflog_iterator_advance(struct ref_iterator *ref_iterator)
if (ends_with(diter->basename, ".lock"))
continue;
- if (refs_read_ref_full(iter->ref_store,
- diter->relative_path, 0,
- &iter->oid, &flags)) {
+ if (!refs_resolve_ref_unsafe(iter->ref_store,
+ diter->relative_path, 0,
+ &iter->oid, &flags,
+ &ignore_errno)) {
error("bad ref for %s", diter->path.buf);
continue;
}
@@ -2471,9 +2516,11 @@ static int lock_ref_for_update(struct files_ref_store *refs,
* the transaction, so we have to read it here
* to record and possibly check old_oid:
*/
- if (refs_read_ref_full(&refs->base,
- referent.buf, 0,
- &lock->old_oid, NULL)) {
+ int ignore_errno;
+ if (!refs_resolve_ref_unsafe(&refs->base,
+ referent.buf, 0,
+ &lock->old_oid, NULL,
+ &ignore_errno)) {
if (update->flags & REF_HAVE_OLD) {
strbuf_addf(err, "cannot lock ref '%s': "
"error reading reference",
@@ -3085,7 +3132,6 @@ static int files_reflog_expire(struct ref_store *ref_store,
struct strbuf log_file_sb = STRBUF_INIT;
char *log_file;
int status = 0;
- int type;
struct strbuf err = STRBUF_INIT;
const struct object_id *oid;
@@ -3099,7 +3145,7 @@ static int files_reflog_expire(struct ref_store *ref_store,
* reference itself, plus we might need to update the
* reference if --updateref was specified:
*/
- lock = lock_ref_oid_basic(refs, refname, &type, &err);
+ lock = lock_ref_oid_basic(refs, refname, &err);
if (!lock) {
error("cannot lock ref '%s': %s", refname, err.buf);
strbuf_release(&err);
@@ -3161,9 +3207,20 @@ static int files_reflog_expire(struct ref_store *ref_store,
* a reference if there are no remaining reflog
* entries.
*/
- int update = (flags & EXPIRE_REFLOGS_UPDATE_REF) &&
- !(type & REF_ISSYMREF) &&
- !is_null_oid(&cb.last_kept_oid);
+ int update = 0;
+
+ if ((flags & EXPIRE_REFLOGS_UPDATE_REF) &&
+ !is_null_oid(&cb.last_kept_oid)) {
+ int ignore_errno;
+ int type;
+ const char *ref;
+
+ ref = refs_resolve_ref_unsafe(&refs->base, refname,
+ RESOLVE_REF_NO_RECURSE,
+ NULL, &type,
+ &ignore_errno);
+ update = !!(ref && !(type & REF_ISSYMREF));
+ }
if (close_lock_file_gently(&reflog_lock)) {
status |= error("couldn't write %s: %s", log_file,
diff --git a/refs/packed-backend.c b/refs/packed-backend.c
index 47247a1491..9da932a540 100644
--- a/refs/packed-backend.c
+++ b/refs/packed-backend.c
@@ -193,13 +193,15 @@ static int release_snapshot(struct snapshot *snapshot)
}
}
-struct ref_store *packed_ref_store_create(const char *path,
+struct ref_store *packed_ref_store_create(struct repository *repo,
+ const char *path,
unsigned int store_flags)
{
struct packed_ref_store *refs = xcalloc(1, sizeof(*refs));
struct ref_store *ref_store = (struct ref_store *)refs;
base_ref_store_init(ref_store, &refs_be_packed);
+ ref_store->repo = repo;
ref_store->gitdir = xstrdup(path);
refs->store_flags = store_flags;
@@ -776,6 +778,7 @@ struct packed_ref_iterator {
struct object_id oid, peeled;
struct strbuf refname_buf;
+ struct repository *repo;
unsigned int flags;
};
@@ -864,8 +867,8 @@ static int packed_ref_iterator_advance(struct ref_iterator *ref_iterator)
continue;
if (!(iter->flags & DO_FOR_EACH_INCLUDE_BROKEN) &&
- !ref_resolves_to_object(iter->base.refname, &iter->oid,
- iter->flags))
+ !ref_resolves_to_object(iter->base.refname, iter->repo,
+ &iter->oid, iter->flags))
continue;
return ITER_OK;
@@ -883,6 +886,9 @@ static int packed_ref_iterator_peel(struct ref_iterator *ref_iterator,
struct packed_ref_iterator *iter =
(struct packed_ref_iterator *)ref_iterator;
+ if (iter->repo != the_repository)
+ BUG("peeling for non-the_repository is not supported");
+
if ((iter->base.flags & REF_KNOWS_PEELED)) {
oidcpy(peeled, &iter->peeled);
return is_null_oid(&iter->peeled) ? -1 : 0;
@@ -954,6 +960,7 @@ static struct ref_iterator *packed_ref_iterator_begin(
iter->base.oid = &iter->oid;
+ iter->repo = ref_store->repo;
iter->flags = flags;
if (prefix && *prefix)
@@ -1347,6 +1354,7 @@ int is_packed_transaction_needed(struct ref_store *ref_store,
ret = 0;
for (i = 0; i < transaction->nr; i++) {
struct ref_update *update = transaction->updates[i];
+ int failure_errno;
unsigned int type;
struct object_id oid;
@@ -1357,9 +1365,9 @@ int is_packed_transaction_needed(struct ref_store *ref_store,
*/
continue;
- if (!refs_read_raw_ref(ref_store, update->refname,
- &oid, &referent, &type) ||
- errno != ENOENT) {
+ if (!refs_read_raw_ref(ref_store, update->refname, &oid,
+ &referent, &type, &failure_errno) ||
+ failure_errno != ENOENT) {
/*
* We have to actually delete that reference
* -> this transaction is needed.
diff --git a/refs/packed-backend.h b/refs/packed-backend.h
index a01a0aff9c..f61a73ec25 100644
--- a/refs/packed-backend.h
+++ b/refs/packed-backend.h
@@ -1,6 +1,7 @@
#ifndef REFS_PACKED_BACKEND_H
#define REFS_PACKED_BACKEND_H
+struct repository;
struct ref_transaction;
/*
@@ -12,7 +13,8 @@ struct ref_transaction;
* even among packed refs.
*/
-struct ref_store *packed_ref_store_create(const char *path,
+struct ref_store *packed_ref_store_create(struct repository *repo,
+ const char *path,
unsigned int store_flags);
/*
diff --git a/refs/ref-cache.c b/refs/ref-cache.c
index a5ad8a39fb..be4aa5e098 100644
--- a/refs/ref-cache.c
+++ b/refs/ref-cache.c
@@ -378,6 +378,8 @@ struct cache_ref_iterator {
* on from there.)
*/
struct cache_ref_iterator_level *levels;
+
+ struct repository *repo;
};
static int cache_ref_iterator_advance(struct ref_iterator *ref_iterator)
@@ -434,6 +436,11 @@ static int cache_ref_iterator_advance(struct ref_iterator *ref_iterator)
static int cache_ref_iterator_peel(struct ref_iterator *ref_iterator,
struct object_id *peeled)
{
+ struct cache_ref_iterator *iter =
+ (struct cache_ref_iterator *)ref_iterator;
+
+ if (iter->repo != the_repository)
+ BUG("peeling for non-the_repository is not supported");
return peel_object(ref_iterator->oid, peeled) ? -1 : 0;
}
@@ -456,6 +463,7 @@ static struct ref_iterator_vtable cache_ref_iterator_vtable = {
struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache,
const char *prefix,
+ struct repository *repo,
int prime_dir)
{
struct ref_dir *dir;
@@ -490,5 +498,7 @@ struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache,
level->prefix_state = PREFIX_CONTAINS_DIR;
}
+ iter->repo = repo;
+
return ref_iterator;
}
diff --git a/refs/ref-cache.h b/refs/ref-cache.h
index 5c042ae718..850d9d3744 100644
--- a/refs/ref-cache.h
+++ b/refs/ref-cache.h
@@ -214,6 +214,7 @@ struct ref_entry *find_ref_entry(struct ref_dir *dir, const char *refname);
*/
struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache,
const char *prefix,
+ struct repository *repo,
int prime_dir);
#endif /* REFS_REF_CACHE_H */
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 72746407fc..fb2c58ce3b 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -66,6 +66,7 @@ int refname_is_safe(const char *refname);
* referred-to object does not exist, emit a warning and return false.
*/
int ref_resolves_to_object(const char *refname,
+ struct repository *repo,
const struct object_id *oid,
unsigned int flags);
@@ -149,9 +150,9 @@ struct ref_update {
const char refname[FLEX_ARRAY];
};
-int refs_read_raw_ref(struct ref_store *ref_store,
- const char *refname, struct object_id *oid,
- struct strbuf *referent, unsigned int *type);
+int refs_read_raw_ref(struct ref_store *ref_store, const char *refname,
+ struct object_id *oid, struct strbuf *referent,
+ unsigned int *type, int *failure_errno);
/*
* Write an error to `err` and return a nonzero value iff the same
@@ -228,20 +229,6 @@ const char *find_descendant_ref(const char *dirname,
const struct string_list *extras,
const struct string_list *skip);
-/*
- * Check whether an attempt to rename old_refname to new_refname would
- * cause a D/F conflict with any existing reference (other than
- * possibly old_refname). If there would be a conflict, emit an error
- * message and return false; otherwise, return true.
- *
- * Note that this function is not safe against all races with other
- * processes (though rename_ref() catches some races that might get by
- * this check).
- */
-int refs_rename_ref_available(struct ref_store *refs,
- const char *old_refname,
- const char *new_refname);
-
/* We allow "recursive" symbolic refs. Only within reason, though */
#define SYMREF_MAXDEPTH 5
@@ -539,7 +526,8 @@ struct ref_store;
* should call base_ref_store_init() to initialize the shared part of
* the ref_store and to record the ref_store for later lookup.
*/
-typedef struct ref_store *ref_store_init_fn(const char *gitdir,
+typedef struct ref_store *ref_store_init_fn(struct repository *repo,
+ const char *gitdir,
unsigned int flags);
typedef int ref_init_db_fn(struct ref_store *refs, struct strbuf *err);
@@ -701,15 +689,22 @@ struct ref_store {
/* The backend describing this ref_store's storage scheme: */
const struct ref_storage_be *be;
- /* The gitdir that this ref_store applies to: */
+ struct repository *repo;
+
+ /*
+ * The gitdir that this ref_store applies to. Note that this is not
+ * necessarily repo->gitdir if the repo has multiple worktrees.
+ */
char *gitdir;
};
/*
- * Parse contents of a loose ref file.
+ * Parse contents of a loose ref file. *failure_errno maybe be set to EINVAL for
+ * invalid contents.
*/
int parse_loose_ref_contents(const char *buf, struct object_id *oid,
- struct strbuf *referent, unsigned int *type);
+ struct strbuf *referent, unsigned int *type,
+ int *failure_errno);
/*
* Fill in the generic part of refs and add it to our collection of