@@ -1675,13 +1675,16 @@ int refs_read_raw_ref(struct ref_store *ref_store,
const char *refname, struct object_id *oid,
struct strbuf *referent, unsigned int *type)
{
+ int result, failure;
if (!strcmp(refname, "FETCH_HEAD") || !strcmp(refname, "MERGE_HEAD")) {
return refs_read_special_head(ref_store, refname, oid, referent,
type);
}
- return ref_store->be->read_raw_ref(ref_store, refname, oid, referent,
- type);
+ result = ref_store->be->read_raw_ref(ref_store, refname, oid, referent,
+ type, &failure);
+ errno = failure;
+ return result;
}
/* This function needs to return a meaningful errno on failure */
@@ -238,14 +238,14 @@ debug_ref_iterator_begin(struct ref_store *ref_store, const char *prefix,
static int debug_read_raw_ref(struct ref_store *ref_store, const char *refname,
struct object_id *oid, struct strbuf *referent,
- unsigned int *type)
+ unsigned int *type, int *failure_errno)
{
struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store;
int res = 0;
oidcpy(oid, &null_oid);
res = drefs->refs->be->read_raw_ref(drefs->refs, refname, oid, referent,
- type);
+ type, failure_errno);
if (res == 0) {
trace_printf_key(&trace_refs, "read_raw_ref: %s: %s (=> %s) type %x: %d\n",
@@ -343,7 +343,7 @@ static struct ref_cache *get_loose_ref_cache(struct files_ref_store *refs)
static int files_read_raw_ref(struct ref_store *ref_store,
const char *refname, struct object_id *oid,
- struct strbuf *referent, unsigned int *type)
+ struct strbuf *referent, unsigned int *type, int *failure_errno)
{
struct files_ref_store *refs =
files_downcast(ref_store, REF_STORE_READ, "read_raw_ref");
@@ -354,7 +354,6 @@ static int files_read_raw_ref(struct ref_store *ref_store,
struct stat st;
int fd;
int ret = -1;
- int save_errno;
int remaining_retries = 3;
*type = 0;
@@ -459,10 +458,9 @@ static int files_read_raw_ref(struct ref_store *ref_store,
ret = parse_loose_ref_contents(buf, oid, referent, type);
out:
- save_errno = errno;
+ *failure_errno = errno;
strbuf_release(&sb_path);
strbuf_release(&sb_contents);
- errno = save_errno;
return ret;
}
@@ -541,6 +539,7 @@ static int lock_raw_ref(struct files_ref_store *refs,
struct strbuf ref_file = STRBUF_INIT;
int attempts_remaining = 3;
int ret = TRANSACTION_GENERIC_ERROR;
+ int failure_errno = 0;
assert(err);
files_assert_main_repository(refs, "lock_raw_ref");
@@ -630,8 +629,8 @@ static int lock_raw_ref(struct files_ref_store *refs,
*/
if (files_read_raw_ref(&refs->base, refname,
- &lock->old_oid, referent, type)) {
- if (errno == ENOENT) {
+ &lock->old_oid, referent, type, &failure_errno)) {
+ if (failure_errno == ENOENT) {
if (mustexist) {
/* Garden variety missing reference. */
strbuf_addf(err, "unable to resolve reference '%s'",
@@ -655,7 +654,7 @@ static int lock_raw_ref(struct files_ref_store *refs,
* reference named "refs/foo/bar/baz".
*/
}
- } else if (errno == EISDIR) {
+ } else if (failure_errno == EISDIR) {
/*
* There is a directory in the way. It might have
* contained references that have been deleted. If
@@ -693,13 +692,13 @@ static int lock_raw_ref(struct files_ref_store *refs,
goto error_return;
}
}
- } else if (errno == EINVAL && (*type & REF_ISBROKEN)) {
+ } else if (failure_errno == EINVAL && (*type & REF_ISBROKEN)) {
strbuf_addf(err, "unable to resolve reference '%s': "
"reference broken", refname);
goto error_return;
} else {
strbuf_addf(err, "unable to resolve reference '%s': %s",
- refname, strerror(errno));
+ refname, strerror(failure_errno));
goto error_return;
}
@@ -726,7 +726,8 @@ static struct snapshot *get_snapshot(struct packed_ref_store *refs)
static int packed_read_raw_ref(struct ref_store *ref_store,
const char *refname, struct object_id *oid,
- struct strbuf *referent, unsigned int *type)
+ struct strbuf *referent, unsigned int *type,
+ int *failure_errno)
{
struct packed_ref_store *refs =
packed_downcast(ref_store, REF_STORE_READ, "read_raw_ref");
@@ -739,7 +740,7 @@ static int packed_read_raw_ref(struct ref_store *ref_store,
if (!rec) {
/* refname is not a packed reference. */
- errno = ENOENT;
+ *failure_errno = ENOENT;
return -1;
}
@@ -617,9 +617,11 @@ typedef int reflog_expire_fn(struct ref_store *ref_store,
* properly-formatted or even safe reference name. NEITHER INPUT NOR
* OUTPUT REFERENCE NAMES ARE VALIDATED WITHIN THIS FUNCTION.
*
- * Return 0 on success. If the ref doesn't exist, set errno to ENOENT and return
+ * Return 0 on success. If the ref doesn't exist, set failure_errno to ENOENT and return
* -1. If the ref exists but is neither a symbolic ref nor an object ID, it is
- * broken; set REF_ISBROKEN in type, and return -1. If there is another error
+ * broken; set REF_ISBROKEN in type, and return -1. For the files backend, EISDIR and ENOTDIR
+ * may be set if the ref name is a directory
+ * If there is another error
* reading the ref, set errno appropriately and return -1.
*
* Backend-specific flags might be set in type as well, regardless of
@@ -636,7 +638,8 @@ typedef int reflog_expire_fn(struct ref_store *ref_store,
*/
typedef int read_raw_ref_fn(struct ref_store *ref_store,
const char *refname, struct object_id *oid,
- struct strbuf *referent, unsigned int *type);
+ struct strbuf *referent, unsigned int *type,
+ int *failure_errno);
struct ref_storage_be {
struct ref_storage_be *next;