All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>, "Jeff King" <peff@peff.net>,
	"Han-Wen Nienhuys" <hanwen@google.com>,
	"Jonathan Tan" <jonathantanmy@google.com>,
	"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Subject: [PATCH v6? 00/17] refs API: get rid of errno setting entirely
Date: Sun, 11 Jul 2021 18:30:24 +0200	[thread overview]
Message-ID: <cover-00.17-00000000000-20210711T162803Z-avarab@gmail.com> (raw)
In-Reply-To: <pull.1012.v5.git.git.1625684869.gitgitgadget@gmail.com>

After starting a review of v5 of Han-Wen's where I was coming up with
squashes-on-top I continued with it and saw if I could get rid of
errno setting entirely in refs.

The end-state of that is that we do that:
	
	$ git -P grep -w errno refs.c
	refs.c:                 if (errno != EPIPE) {
	refs.c:                         /* Don't leak errno outside this API */
	refs.c:                         errno = 0;

The rest has various bugfixes etc. to Han-Wen's version.

I'm not sure about:

    refs: make errno ignoring explicit in lock_ref_oid_basic()

But it's an edge case that's present in Han-Wen's, but just
ignored/skipped past. Now it's a BUG(), I haven't been able to hit it
in testing, but maybe we do hit it somehow.

My amendmend of:

    refs: explicitly return failure_errno from parse_loose_ref_contents

Has it calling BUG() to assert that whenever we return non-zero we set
errno as expected, there were a few cases where functions omitted one
errno case, but set another.

Arguably everything as of 08/17 should be its follow-up series. I've
included it because I think looking at those patches assures the
reader that we didn't miss any subtle errno edge cases.

(I removed my Reviewed-by trailer because it seemed redundant to SOB,
and if I have SOB already on something saying I reviewed it seemed
odd...)

1. https://lore.kernel.org/git/pull.1012.v5.git.git.1625684869.gitgitgadget@gmail.com/

Han-Wen Nienhuys (6):
  refs: remove EINVAL errno output from specification of read_raw_ref_fn
  refs/files-backend: stop setting errno from lock_ref_oid_basic
  refs: make errno output explicit for read_raw_ref_fn
  refs: add failure_errno to refs_read_raw_ref() signature
  refs: explicitly return failure_errno from parse_loose_ref_contents
  refs: make errno output explicit for refs_resolve_ref_unsafe

Ævar Arnfjörð Bjarmason (11):
  refs: make errno ignoring explicit in lock_ref_oid_basic()
  refs file-backend.c: stop setting "EBUSY" in verify_lock()
  refs file-backend.c: deal with errno directly in verify_lock()
  refs API: remove refs_read_ref_full() wrapper
  refs API: make resolve_gitlink_ref() not set errno
  refs API: make refs_resolve_ref_unsafe() static
  refs API: make refs_resolve_refdup() not set errno
  refs API: make refs_ref_exists() not set errno
  refs API: make resolve_ref_unsafe() not set errno
  refs API: make expand_ref() and repo_dwim_log() not set errno
  refs API: don't leak "errno" in run_transaction_hook()

 refs.c                    | 122 ++++++++++++++++----------
 refs.h                    |  17 ++--
 refs/debug.c              |   4 +-
 refs/files-backend.c      | 180 +++++++++++++++++++++-----------------
 refs/packed-backend.c     |  15 ++--
 refs/refs-internal.h      |  32 ++++---
 sequencer.c               |  10 ++-
 t/helper/test-ref-store.c |   5 +-
 worktree.c                |  27 +++---
 9 files changed, 244 insertions(+), 168 deletions(-)

Range-diff:
 1:  d6a41c3c0cb !  1:  57517368c34 refs: remove EINVAL errno output from specification of read_raw_ref_fn
    @@ Commit message
         Spotted by Ævar Arnfjörð Bjarmason <avarab@gmail.com>.
     
         Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
    +    Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## refs/refs-internal.h ##
     @@ refs/refs-internal.h: typedef int reflog_expire_fn(struct ref_store *ref_store,
 2:  95025080c16 !  2:  61cf7611473 refs/files-backend: stop setting errno from lock_ref_oid_basic
    @@ Commit message
         refs_reflog_exists() (which calls a function in a vtable that is not
         documented to use and/or preserve errno)
     
    +    In the case of the "errno != ENOTDIR" case that originates in 5b2d8d6f218
    +    (lock_ref_sha1_basic(): improve diagnostics for ref D/F conflicts,
    +    2015-05-11), there the "last_errno" was saved away to return it from
    +    lock_ref_oid_basic(), now that we're no longer doing that we can skip
    +    that entirely and use "errno" directly. A follow-up change will
    +    extract the specific errno we want earlier in this function.
    +
         Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
    -    Reviewed-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
    +    Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## refs/files-backend.c ##
     @@ refs/files-backend.c: static int create_reflock(const char *path, void *cb)
    @@ refs/files-backend.c: static struct ref_lock *lock_ref_oid_basic(struct files_re
      					    &refs->base,
      					    refname, extras, skip, err))
     @@ refs/files-backend.c: static struct ref_lock *lock_ref_oid_basic(struct files_ref_store *refs,
    + 						     refname, resolve_flags,
      						     &lock->old_oid, type);
      	}
    - 	if (!resolved) {
    +-	if (!resolved) {
     -		last_errno = errno;
    -+		int last_errno = errno;
    - 		if (last_errno != ENOTDIR ||
    +-		if (last_errno != ENOTDIR ||
     -		    !refs_verify_refname_available(&refs->base, refname,
     -						   extras, skip, err))
    -+		    /* in case of D/F conflict, try to generate a better error
    -+		     * message. If that fails, fall back to strerror(ENOTDIR).
    -+		     */
    -+		    !refs_verify_refname_available(&refs->base, refname, extras,
    -+						   skip, err))
    - 			strbuf_addf(err, "unable to resolve reference '%s': %s",
    - 				    refname, strerror(last_errno));
    +-			strbuf_addf(err, "unable to resolve reference '%s': %s",
    +-				    refname, strerror(last_errno));
    +-
    ++	if (!resolved &&
    ++	    (errno != ENOTDIR ||
    ++	     /* in case of D/F conflict, try to generate a better error
    ++	      * message. If that fails, fall back to strerror(ENOTDIR).
    ++	      */
    ++	     !refs_verify_refname_available(&refs->base, refname, extras,
    ++					    skip, err))) {
    ++		strbuf_addf(err, "unable to resolve reference '%s': %s",
    ++			    refname, strerror(errno));
    + 		goto error_return;
    + 	}
      
     @@ refs/files-backend.c: static struct ref_lock *lock_ref_oid_basic(struct files_ref_store *refs,
      	if (is_null_oid(&lock->old_oid) &&
 3:  7feedb97201 !  3:  a4e5f2d02fb refs: make errno output explicit for read_raw_ref_fn
    @@ Commit message
         relevant.
     
         Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
    -    Reviewed-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
    +    Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## refs.c ##
     @@ refs.c: 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;
    -+	int failure_errno;
    - 	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,
    + 	return ref_store->be->read_raw_ref(ref_store, refname, oid, referent,
     -					   type);
    -+	failure_errno = 0;
    -+	result = ref_store->be->read_raw_ref(ref_store, refname, oid, referent,
    -+					     type, &failure_errno);
    -+	if (failure_errno)
    -+		errno = failure_errno;
    -+	return result;
    ++					   type, &errno);
      }
      
      /* This function needs to return a meaningful errno on failure */
    @@ refs/files-backend.c: 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;
    ++	int failure_errno;
      
      	assert(err);
      	files_assert_main_repository(refs, "lock_raw_ref");
    +@@ refs/files-backend.c: static int lock_raw_ref(struct files_ref_store *refs,
    + 	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) {
    ++		int myerr = errno;
    ++		errno = 0;
    ++		if (myerr == ENOENT && --attempts_remaining > 0) {
    + 			/*
    + 			 * Maybe somebody just deleted one of the
    + 			 * directories leading to ref_file.  Try
    +@@ refs/files-backend.c: static int lock_raw_ref(struct files_ref_store *refs,
    + 			 */
    + 			goto retry;
    + 		} else {
    +-			unable_to_lock_message(ref_file.buf, errno, err);
    ++			unable_to_lock_message(ref_file.buf, myerr, err);
    + 			goto error_return;
    + 		}
    + 	}
     @@ refs/files-backend.c: static int lock_raw_ref(struct files_ref_store *refs,
      	 * fear that its value will change.
      	 */
 4:  ef91f5cee13 !  4:  270cda29c3a refs: add failure_errno to refs_read_raw_ref() signature
    @@ Commit message
     
         This lets us use the explicit errno output parameter in refs_resolve_ref_unsafe.
     
    +    Some of our callers explicitly do not care about the errno, rather
    +    than understanding NULL let's have them declare that they don't care
    +    by passing in an "ignore_errno". There's only three of them, and using
    +    that pattern will make it more obvious that they want to throw away
    +    data, let's also add a comment to one of the callers about why we'd
    +    like to ignore the errno.
    +
    +    Let's not extend that to refs_resolve_ref_unsafe() itself for now, it
    +    has a large set of legacy callers, so we're faking up the old "errno"
    +    behavior for it. We can convert those callers to
    +    refs_resolve_ref_unsafe_with_errno() later.
    +
    +    We are leaving out out the refs_read_special_head() in
    +    refs_read_raw_ref() for now, as noted in the next commit moving it to
    +    "failure_errno" will require some special consideration.
    +
    +    We're intentionally mis-indenting the argument list of the new
    +    refs_resolve_ref_unsafe_with_errno(), it will be non-static in a
    +    subsequent commit, doing it this way makes that diff smaller.
    +
         Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
    -    Reviewed-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
    +    Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## refs.c ##
     @@ refs.c: static int refs_read_special_head(struct ref_store *ref_store,
    @@ refs.c: static int refs_read_special_head(struct ref_store *ref_store,
     -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;
    --	int failure_errno;
     +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)
    -+{
    -+	int unused_errno;
    -+	if (!failure_errno)
    -+		failure_errno = &unused_errno;
    -+	*failure_errno = 0;
    + {
    ++	assert(failure_errno);
      	if (!strcmp(refname, "FETCH_HEAD") || !strcmp(refname, "MERGE_HEAD")) {
      		return refs_read_special_head(ref_store, refname, oid, referent,
      					      type);
      	}
      
    --	failure_errno = 0;
    --	result = ref_store->be->read_raw_ref(ref_store, refname, oid, referent,
    --					     type, &failure_errno);
    --	if (failure_errno)
    --		errno = failure_errno;
    --	return result;
    -+	return ref_store->be->read_raw_ref(ref_store, refname, oid, referent,
    + 	return ref_store->be->read_raw_ref(ref_store, refname, oid, referent,
    +-					   type, &errno);
     +					   type, failure_errno);
      }
      
    @@ refs.c: static int refs_read_special_head(struct ref_store *ref_store,
     -				    const char *refname,
     -				    int resolve_flags,
     -				    struct object_id *oid, int *flags)
    -+const char *refs_resolve_ref_unsafe_with_errno(struct ref_store *refs,
    ++static const char *refs_resolve_ref_unsafe_with_errno(struct ref_store *refs,
     +					       const char *refname,
     +					       int resolve_flags,
     +					       struct object_id *oid,
    @@ refs.c: static int refs_read_special_head(struct ref_store *ref_store,
      	static struct strbuf sb_refname = STRBUF_INIT;
      	struct object_id unused_oid;
      	int unused_flags;
    -+	int unused_errno;
      	int symref_count;
      
    ++	assert(failure_errno);
    ++
      	if (!oid)
    + 		oid = &unused_oid;
    + 	if (!flags)
     @@ refs.c: const char *refs_resolve_ref_unsafe(struct ref_store *refs,
    - 		flags = &unused_flags;
    - 
    - 	*flags = 0;
    -+	if (!failure_errno)
    -+		failure_errno = &unused_errno;
    -+	*failure_errno = 0;
    - 
      	if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
      		if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
    -@@ refs.c: const char *refs_resolve_ref_unsafe(struct ref_store *refs,
    + 		    !refname_is_safe(refname)) {
    +-			errno = EINVAL;
    ++			*failure_errno = EINVAL;
    + 			return NULL;
    + 		}
      
    +@@ refs.c: const char *refs_resolve_ref_unsafe(struct ref_store *refs,
      	for (symref_count = 0; symref_count < SYMREF_MAXDEPTH; symref_count++) {
      		unsigned int read_flags = 0;
    -+		int read_failure = 0;
      
     -		if (refs_read_raw_ref(refs, refname,
     -				      oid, &sb_refname, &read_flags)) {
     +		if (refs_read_raw_ref(refs, refname, oid, &sb_refname,
    -+				      &read_flags, &read_failure)) {
    ++				      &read_flags, failure_errno)) {
      			*flags |= read_flags;
      
    -+			*failure_errno = read_failure;
    -+
      			/* In reading mode, refs must eventually resolve */
    - 			if (resolve_flags & RESOLVE_REF_READING)
    - 				return NULL;
     @@ refs.c: const char *refs_resolve_ref_unsafe(struct ref_store *refs,
      			 * may show errors besides ENOENT if there are
      			 * similarly-named refs.
    @@ refs.c: const char *refs_resolve_ref_unsafe(struct ref_store *refs,
     -			if (errno != ENOENT &&
     -			    errno != EISDIR &&
     -			    errno != ENOTDIR)
    -+			if (read_failure != ENOENT && read_failure != EISDIR &&
    -+			    read_failure != ENOTDIR)
    ++			if (*failure_errno != ENOENT &&
    ++			    *failure_errno != EISDIR &&
    ++			    *failure_errno != ENOTDIR)
      				return NULL;
      
      			oidclr(oid);
     @@ refs.c: const char *refs_resolve_ref_unsafe(struct ref_store *refs,
    + 		if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
    + 			if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
    + 			    !refname_is_safe(refname)) {
    +-				errno = EINVAL;
    ++				*failure_errno = EINVAL;
    + 				return NULL;
    + 			}
    + 
    +@@ refs.c: const char *refs_resolve_ref_unsafe(struct ref_store *refs,
    + 		}
    + 	}
    + 
    +-	errno = ELOOP;
    ++	*failure_errno = ELOOP;
      	return NULL;
      }
      
    @@ refs.c: const char *refs_resolve_ref_unsafe(struct ref_store *refs,
     +				    int resolve_flags, struct object_id *oid,
     +				    int *flags)
     +{
    -+	int ignore = 0;
    -+	return refs_resolve_ref_unsafe_with_errno(refs, refname, resolve_flags,
    -+						  oid, flags, &ignore);
    ++	int failure_errno = 0;
    ++	const char *refn;
    ++	refn = refs_resolve_ref_unsafe_with_errno(refs, refname, resolve_flags,
    ++						  oid, flags, &failure_errno);
    ++	if (!refn)
    ++		/* For unmigrated legacy callers */
    ++		errno = failure_errno;
    ++	return refn;
     +}
     +
      /* backend functions */
      int refs_init_db(struct strbuf *err)
      {
    +@@ refs.c: int refs_verify_refname_available(struct ref_store *refs,
    + 
    + 	strbuf_grow(&dirname, strlen(refname) + 1);
    + 	for (slash = strchr(refname, '/'); slash; slash = strchr(slash + 1, '/')) {
    ++		/*
    ++		 * Just saying "Is a directory" when we e.g. can't
    ++		 * lock some multi-level ref isn't very informative,
    ++		 * the user won't be told *what* is a directory, so
    ++		 * let's not use strerror() below.
    ++		 */
    ++		int ignore_errno;
    + 		/* Expand dirname to the new prefix, not including the trailing slash: */
    + 		strbuf_add(&dirname, refname + dirname.len, slash - refname - dirname.len);
    + 
     @@ refs.c: int refs_verify_refname_available(struct ref_store *refs,
      		if (skip && string_list_has_string(skip, dirname.buf))
      			continue;
      
     -		if (!refs_read_raw_ref(refs, dirname.buf, &oid, &referent, &type)) {
     +		if (!refs_read_raw_ref(refs, dirname.buf, &oid, &referent,
    -+				       &type, NULL)) {
    ++				       &type, &ignore_errno)) {
      			strbuf_addf(err, _("'%s' exists; cannot create '%s'"),
      				    dirname.buf, refname);
      			goto cleanup;
     
      ## refs/files-backend.c ##
     @@ refs/files-backend.c: static int files_read_raw_ref(struct ref_store *ref_store, const char *refname,
    + 		goto out;
    + 
      	if (lstat(path, &st) < 0) {
    ++		int ignore_errno;
      		if (errno != ENOENT)
      			goto out;
     -		if (refs_read_raw_ref(refs->packed_ref_store, refname,
     -				      oid, referent, type)) {
     +		if (refs_read_raw_ref(refs->packed_ref_store, refname, oid,
    -+				      referent, type, NULL)) {
    ++				      referent, type, &ignore_errno)) {
      			errno = ENOENT;
      			goto out;
      		}
     @@ refs/files-backend.c: static int files_read_raw_ref(struct ref_store *ref_store, const char *refname,
    + 
    + 	/* 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)) {
     +		if (refs_read_raw_ref(refs->packed_ref_store, refname, oid,
    -+				      referent, type, NULL)) {
    ++				      referent, type, &ignore_errno)) {
      			errno = EISDIR;
      			goto out;
      		}
    @@ refs/packed-backend.c: int is_packed_transaction_needed(struct ref_store *ref_st
      	ret = 0;
      	for (i = 0; i < transaction->nr; i++) {
      		struct ref_update *update = transaction->updates[i];
    -+		int failure_errno = 0;
    ++		int failure_errno;
      		unsigned int type;
      		struct object_id oid;
      
 5:  6918c214d1b !  5:  f5197cdc0b8 refs: explicitly return failure_errno from parse_loose_ref_contents
    @@ Commit message
         The EINVAL error from parse_loose_ref_contents is used in files-backend
         to create a custom error message.
     
    +    In untangling this we discovered a tricky edge case. The
    +    refs_read_special_head() function was relying on
    +    parse_loose_ref_contents() setting EINVAL.
    +
    +    By converting it to use "saved_errno" we can migrate away from "errno"
    +    in this part of the code entirely, and do away with an existing
    +    "save_errno" pattern, its only purpose was to not clobber the "errno"
    +    we previously needed at the end of files_read_raw_ref().
    +
    +    Let's assert that we can do that by not having files_read_raw_ref()
    +    itself operate on *failure_errno in addition to passing it on. Instead
    +    we'll assert that if we return non-zero we actually do set errno, thus
    +    assuring ourselves and callers that they can trust the resulting
    +    "failure_errno".
    +
         Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
    -    Reviewed-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
    +    Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## refs.c ##
     @@ refs.c: int for_each_fullref_in_prefixes(const char *namespace,
    @@ refs.c: static int refs_read_special_head(struct ref_store *ref_store,
      done:
      	strbuf_release(&full_path);
     @@ refs.c: int refs_read_raw_ref(struct ref_store *ref_store, const char *refname,
    - 	*failure_errno = 0;
    + 	assert(failure_errno);
      	if (!strcmp(refname, "FETCH_HEAD") || !strcmp(refname, "MERGE_HEAD")) {
      		return refs_read_special_head(ref_store, refname, oid, referent,
     -					      type);
    @@ refs.c: int refs_read_raw_ref(struct ref_store *ref_store, const char *refname,
     
      ## refs/files-backend.c ##
     @@ refs/files-backend.c: 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);
    +@@ refs/files-backend.c: static int files_read_raw_ref(struct ref_store *ref_store, const char *refname,
    + 
    + 	if (lstat(path, &st) < 0) {
    + 		int ignore_errno;
    +-		if (errno != ENOENT)
    ++		myerr = errno;
    ++		errno = 0;
    ++		if (myerr != ENOENT)
    + 			goto out;
    + 		if (refs_read_raw_ref(refs->packed_ref_store, refname, oid,
    + 				      referent, type, &ignore_errno)) {
    +-			errno = ENOENT;
    ++			myerr = ENOENT;
    + 			goto out;
    + 		}
    + 		ret = 0;
    +@@ refs/files-backend.c: static int files_read_raw_ref(struct ref_store *ref_store, const char *refname,
    + 	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
    +@@ refs/files-backend.c: static int files_read_raw_ref(struct ref_store *ref_store, const char *refname,
    + 		 */
    + 		if (refs_read_raw_ref(refs->packed_ref_store, refname, oid,
    + 				      referent, type, &ignore_errno)) {
    +-			errno = EISDIR;
    ++			myerr = EISDIR;
    + 			goto out;
    + 		}
    + 		ret = 0;
    +@@ refs/files-backend.c: static int files_read_raw_ref(struct ref_store *ref_store, const char *refname,
    + 	 */
    + 	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
    +@@ refs/files-backend.c: static int files_read_raw_ref(struct ref_store *ref_store, const char *refname,
    + 	}
    + 	strbuf_reset(&sb_contents);
    + 	if (strbuf_read(&sb_contents, fd, 256) < 0) {
    +-		int save_errno = 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, failure_errno);
    -+	errno = *failure_errno;
    ++	ret = parse_loose_ref_contents(buf, oid, referent, type, &myerr);
    + 
      out:
    -+	/*
    -+	 * Many system calls in this function can fail with ENOTDIR/EISDIR, and
    -+	 * we want to collect all of them, so simply copy the error out from
    -+	 * errno.
    -+	 */
    - 	*failure_errno = errno;
    +-	*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);
    -@@ refs/files-backend.c: static int files_read_raw_ref(struct ref_store *ref_store, const char *refname,
    + 	return ret;
      }
      
      int parse_loose_ref_contents(const char *buf, struct object_id *oid,
 6:  85a14bde904 !  6:  96689e523f1 refs: make errno output explicit for refs_resolve_ref_unsafe
    @@ Commit message
         that needs error information to make logic decisions, so update that caller
     
         Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
    -    Reviewed-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
    +    Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
    +
    + ## refs.c ##
    +@@ refs.c: int refs_read_raw_ref(struct ref_store *ref_store, const char *refname,
    + 					   type, failure_errno);
    + }
    + 
    +-static const char *refs_resolve_ref_unsafe_with_errno(struct ref_store *refs,
    ++const char *refs_resolve_ref_unsafe_with_errno(struct ref_store *refs,
    + 					       const char *refname,
    + 					       int resolve_flags,
    + 					       struct object_id *oid,
    +
    + ## refs.h ##
    +@@ refs.h: const char *refs_resolve_ref_unsafe(struct ref_store *refs,
    + 				    int resolve_flags,
    + 				    struct object_id *oid,
    + 				    int *flags);
    ++/**
    ++ * refs_resolve_ref_unsafe_with_errno() is like
    ++ * refs_resolve_ref_unsafe(), but provide access to errno code that
    ++ * lead to a failure. We guarantee that errno is set to a meaningful
    ++ * value on non-zero return.
    ++ */
    ++const char *refs_resolve_ref_unsafe_with_errno(struct ref_store *refs,
    ++					       const char *refname,
    ++					       int resolve_flags,
    ++					       struct object_id *oid,
    ++					       int *flags, int *failure_errno);
    + const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
    + 			       struct object_id *oid, int *flags);
    + 
     
      ## refs/files-backend.c ##
     @@ refs/files-backend.c: static struct ref_lock *lock_ref_oid_basic(struct files_ref_store *refs,
    @@ refs/files-backend.c: static struct ref_lock *lock_ref_oid_basic(struct files_re
     @@ refs/files-backend.c: static struct ref_lock *lock_ref_oid_basic(struct files_ref_store *refs,
      						     &lock->old_oid, type);
      	}
    - 	if (!resolved) {
    --		int last_errno = errno;
    --		if (last_errno != ENOTDIR ||
    -+		if (resolve_errno != ENOTDIR ||
    - 		    /* in case of D/F conflict, try to generate a better error
    - 		     * message. If that fails, fall back to strerror(ENOTDIR).
    - 		     */
    - 		    !refs_verify_refname_available(&refs->base, refname, extras,
    - 						   skip, err))
    - 			strbuf_addf(err, "unable to resolve reference '%s': %s",
    --				    refname, strerror(last_errno));
    -+				    refname, strerror(resolve_errno));
    - 
    + 	if (!resolved &&
    +-	    (errno != ENOTDIR ||
    ++	    (resolve_errno != ENOTDIR ||
    + 	     /* in case of D/F conflict, try to generate a better error
    + 	      * message. If that fails, fall back to strerror(ENOTDIR).
    + 	      */
    + 	     !refs_verify_refname_available(&refs->base, refname, extras,
    + 					    skip, err))) {
    + 		strbuf_addf(err, "unable to resolve reference '%s': %s",
    +-			    refname, strerror(errno));
    ++			    refname, strerror(resolve_errno));
      		goto error_return;
      	}
    -
    - ## refs/refs-internal.h ##
    -@@ refs/refs-internal.h: 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);
      
    -+/* Like refs_resolve_ref_unsafe, but provide access to errno code that lead to a
    -+ * failure. */
    -+const char *refs_resolve_ref_unsafe_with_errno(struct ref_store *refs,
    -+					       const char *refname,
    -+					       int resolve_flags,
    -+					       struct object_id *oid,
    -+					       int *flags, int *failure_errno);
    -+
    - /*
    -  * Write an error to `err` and return a nonzero value iff the same
    -  * refname appears multiple times in `refnames`. `refnames` must be
 -:  ----------- >  7:  10a40c9244e refs: make errno ignoring explicit in lock_ref_oid_basic()
 -:  ----------- >  8:  ff38a3f1936 refs file-backend.c: stop setting "EBUSY" in verify_lock()
 -:  ----------- >  9:  cdec272f06f refs file-backend.c: deal with errno directly in verify_lock()
 -:  ----------- > 10:  bd0639945a4 refs API: remove refs_read_ref_full() wrapper
 -:  ----------- > 11:  a359d1533bd refs API: make resolve_gitlink_ref() not set errno
 -:  ----------- > 12:  07d550015ac refs API: make refs_resolve_ref_unsafe() static
 -:  ----------- > 13:  73b70491515 refs API: make refs_resolve_refdup() not set errno
 -:  ----------- > 14:  1e9de48d850 refs API: make refs_ref_exists() not set errno
 -:  ----------- > 15:  446b50280be refs API: make resolve_ref_unsafe() not set errno
 -:  ----------- > 16:  37c5b88d7d8 refs API: make expand_ref() and repo_dwim_log() not set errno
 -:  ----------- > 17:  f914df0bb25 refs API: don't leak "errno" in run_transaction_hook()
-- 
2.32.0-dev


  parent reply	other threads:[~2021-07-11 16:30 UTC|newest]

Thread overview: 148+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-29 15:32 [PATCH 0/8] refs: cleanup errno sideband ref related functions Han-Wen Nienhuys via GitGitGadget
2021-04-29 15:32 ` [PATCH 1/8] refs: remove EINVAL specification from the errno sideband in read_raw_ref_fn Han-Wen Nienhuys via GitGitGadget
2021-04-30  2:38   ` Junio C Hamano
2021-05-19 12:25     ` Han-Wen Nienhuys
2021-06-03  2:19   ` Jonathan Tan
2021-06-09 11:28     ` Han-Wen Nienhuys
2021-04-29 15:32 ` [PATCH 2/8] refs/files-backend: stop setting errno from lock_ref_oid_basic Han-Wen Nienhuys via GitGitGadget
2021-04-30  3:10   ` Junio C Hamano
2021-05-19 12:29     ` Han-Wen Nienhuys
2021-06-03  2:33   ` Jonathan Tan
2021-06-10 10:02     ` Han-Wen Nienhuys
2021-04-29 15:32 ` [PATCH 3/8] refs: make errno output explicit for read_raw_ref_fn Han-Wen Nienhuys via GitGitGadget
2021-04-30  3:34   ` Junio C Hamano
2021-04-30  6:02     ` Junio C Hamano
2021-05-19 12:33       ` Han-Wen Nienhuys
2021-06-03  2:37   ` Jonathan Tan
2021-06-10 10:05     ` Han-Wen Nienhuys
2021-04-29 15:32 ` [PATCH 4/8] refs: make errno output explicit for refs_resolve_ref_unsafe Han-Wen Nienhuys via GitGitGadget
2021-06-03  2:51   ` Jonathan Tan
2021-06-10 11:27     ` Han-Wen Nienhuys
2021-04-29 15:32 ` [PATCH 5/8] refs: add failure_errno to refs_read_raw_ref() signature Han-Wen Nienhuys via GitGitGadget
2021-04-29 15:32 ` [PATCH 6/8] refs: clear errno return in refs_resolve_ref_unsafe() Han-Wen Nienhuys via GitGitGadget
2021-06-03  2:53   ` Jonathan Tan
2021-06-10 11:45     ` Han-Wen Nienhuys
2021-04-29 15:32 ` [PATCH 7/8] refs: stop setting EINVAL and ELOOP in symref resolution Han-Wen Nienhuys via GitGitGadget
2021-06-03  2:55   ` Jonathan Tan
2021-06-10 11:58     ` Han-Wen Nienhuys
2021-04-29 15:32 ` [PATCH 8/8] refs: explicitly propagate errno from refs_read_raw_ref Han-Wen Nienhuys via GitGitGadget
2021-06-03  2:13 ` [PATCH 0/8] refs: cleanup errno sideband ref related functions Jonathan Tan
2021-06-09 11:29   ` Han-Wen Nienhuys
2021-06-10 12:57 ` [PATCH v2 " Han-Wen Nienhuys via GitGitGadget
2021-06-10 12:57   ` [PATCH v2 1/8] refs: remove EINVAL errno output from specification of read_raw_ref_fn Han-Wen Nienhuys via GitGitGadget
2021-06-10 12:57   ` [PATCH v2 2/8] refs/files-backend: stop setting errno from lock_ref_oid_basic Han-Wen Nienhuys via GitGitGadget
2021-07-01 11:13     ` Ævar Arnfjörð Bjarmason
2021-07-05 14:16       ` Han-Wen Nienhuys
2021-06-10 12:57   ` [PATCH v2 3/8] refs: make errno output explicit for read_raw_ref_fn Han-Wen Nienhuys via GitGitGadget
2021-07-01 11:34     ` Ævar Arnfjörð Bjarmason
2021-07-05 14:34       ` Han-Wen Nienhuys
2021-06-10 12:57   ` [PATCH v2 4/8] refs: make errno output explicit for refs_resolve_ref_unsafe Han-Wen Nienhuys via GitGitGadget
2021-07-01 11:56     ` Ævar Arnfjörð Bjarmason
2021-06-10 12:57   ` [PATCH v2 5/8] refs: use refs_resolve_ref_unsafe_with_errno() where needed Han-Wen Nienhuys via GitGitGadget
2021-07-01 11:58     ` Ævar Arnfjörð Bjarmason
2021-06-10 12:57   ` [PATCH v2 6/8] refs: add failure_errno to refs_read_raw_ref() signature Han-Wen Nienhuys via GitGitGadget
2021-07-01 12:06     ` Ævar Arnfjörð Bjarmason
2021-06-10 12:57   ` [PATCH v2 7/8] refs: clear errno return in refs_resolve_ref_unsafe() Han-Wen Nienhuys via GitGitGadget
2021-07-01 12:19     ` Ævar Arnfjörð Bjarmason
2021-06-10 12:57   ` [PATCH v2 8/8] refs: explicitly propagate errno from refs_read_raw_ref Han-Wen Nienhuys via GitGitGadget
2021-07-01 12:26     ` Ævar Arnfjörð Bjarmason
2021-07-05 16:09       ` Han-Wen Nienhuys
2021-07-05 19:08         ` Ævar Arnfjörð Bjarmason
2021-07-05 19:39           ` Han-Wen Nienhuys
2021-06-14 10:10   ` [PATCH v2 0/8] refs: cleanup errno sideband ref related functions Han-Wen Nienhuys
2021-07-05 20:56   ` [PATCH v3 0/5] " Han-Wen Nienhuys via GitGitGadget
2021-07-05 20:56     ` [PATCH v3 1/5] refs: remove EINVAL errno output from specification of read_raw_ref_fn Han-Wen Nienhuys via GitGitGadget
2021-07-05 20:56     ` [PATCH v3 2/5] refs/files-backend: stop setting errno from lock_ref_oid_basic Han-Wen Nienhuys via GitGitGadget
2021-07-05 20:56     ` [PATCH v3 3/5] refs: make errno output explicit for read_raw_ref_fn Han-Wen Nienhuys via GitGitGadget
2021-07-05 20:56     ` [PATCH v3 4/5] refs: add failure_errno to refs_read_raw_ref() signature Han-Wen Nienhuys via GitGitGadget
2021-07-06 19:28       ` Junio C Hamano
2021-07-05 20:56     ` [PATCH v3 5/5] refs: make errno output explicit for refs_resolve_ref_unsafe Han-Wen Nienhuys via GitGitGadget
2021-07-06  0:38     ` [PATCH v3 0/5] refs: cleanup errno sideband ref related functions Ævar Arnfjörð Bjarmason
2021-07-06  9:53       ` Han-Wen Nienhuys
2021-07-06 14:27         ` Ævar Arnfjörð Bjarmason
2021-07-06 18:36           ` Han-Wen Nienhuys
2021-07-06 18:55     ` [PATCH v4 0/6] " Han-Wen Nienhuys via GitGitGadget
2021-07-06 18:55       ` [PATCH v4 1/6] refs: remove EINVAL errno output from specification of read_raw_ref_fn Han-Wen Nienhuys via GitGitGadget
2021-07-06 18:55       ` [PATCH v4 2/6] refs/files-backend: stop setting errno from lock_ref_oid_basic Han-Wen Nienhuys via GitGitGadget
2021-07-06 18:55       ` [PATCH v4 3/6] refs: make errno output explicit for read_raw_ref_fn Han-Wen Nienhuys via GitGitGadget
2021-07-06 18:55       ` [PATCH v4 4/6] refs: add failure_errno to refs_read_raw_ref() signature Han-Wen Nienhuys via GitGitGadget
2021-07-06 19:39         ` Junio C Hamano
2021-07-06 18:55       ` [PATCH v4 5/6] refs: explicitly return failure_errno from parse_loose_ref_contents Han-Wen Nienhuys via GitGitGadget
2021-07-06 19:37         ` Junio C Hamano
2021-07-07  8:20           ` Han-Wen Nienhuys
2021-07-06 18:55       ` [PATCH v4 6/6] refs: make errno output explicit for refs_resolve_ref_unsafe Han-Wen Nienhuys via GitGitGadget
2021-07-07 19:07       ` [PATCH v5 0/6] refs: cleanup errno sideband ref related functions Han-Wen Nienhuys via GitGitGadget
2021-07-07 19:07         ` [PATCH v5 1/6] refs: remove EINVAL errno output from specification of read_raw_ref_fn Han-Wen Nienhuys via GitGitGadget
2021-07-07 19:07         ` [PATCH v5 2/6] refs/files-backend: stop setting errno from lock_ref_oid_basic Han-Wen Nienhuys via GitGitGadget
2021-07-11 11:38           ` Ævar Arnfjörð Bjarmason
2021-07-13  8:00             ` Han-Wen Nienhuys
2021-07-07 19:07         ` [PATCH v5 3/6] refs: make errno output explicit for read_raw_ref_fn Han-Wen Nienhuys via GitGitGadget
2021-07-11 11:52           ` Ævar Arnfjörð Bjarmason
2021-07-07 19:07         ` [PATCH v5 4/6] refs: add failure_errno to refs_read_raw_ref() signature Han-Wen Nienhuys via GitGitGadget
2021-07-11 11:59           ` Ævar Arnfjörð Bjarmason
2021-07-13  8:02             ` Han-Wen Nienhuys
2021-07-07 19:07         ` [PATCH v5 5/6] refs: explicitly return failure_errno from parse_loose_ref_contents Han-Wen Nienhuys via GitGitGadget
2021-07-11 12:41           ` Ævar Arnfjörð Bjarmason
2021-07-07 19:07         ` [PATCH v5 6/6] refs: make errno output explicit for refs_resolve_ref_unsafe Han-Wen Nienhuys via GitGitGadget
2021-07-07 20:44         ` [PATCH v5 0/6] refs: cleanup errno sideband ref related functions Junio C Hamano
2021-07-11 16:30         ` Ævar Arnfjörð Bjarmason [this message]
2021-07-11 16:30           ` [PATCH v6? 01/17] refs: remove EINVAL errno output from specification of read_raw_ref_fn Ævar Arnfjörð Bjarmason
2021-07-11 16:30           ` [PATCH v6? 02/17] refs/files-backend: stop setting errno from lock_ref_oid_basic Ævar Arnfjörð Bjarmason
2021-07-11 16:30           ` [PATCH v6? 03/17] refs: make errno output explicit for read_raw_ref_fn Ævar Arnfjörð Bjarmason
2021-07-11 16:30           ` [PATCH v6? 04/17] refs: add failure_errno to refs_read_raw_ref() signature Ævar Arnfjörð Bjarmason
2021-07-11 16:30           ` [PATCH v6? 05/17] refs: explicitly return failure_errno from parse_loose_ref_contents Ævar Arnfjörð Bjarmason
2021-07-11 16:30           ` [PATCH v6? 06/17] refs: make errno output explicit for refs_resolve_ref_unsafe Ævar Arnfjörð Bjarmason
2021-07-11 16:30           ` [PATCH v6? 07/17] refs: make errno ignoring explicit in lock_ref_oid_basic() Ævar Arnfjörð Bjarmason
2021-07-11 16:30           ` [PATCH v6? 08/17] refs file-backend.c: stop setting "EBUSY" in verify_lock() Ævar Arnfjörð Bjarmason
2021-07-13  8:08             ` Han-Wen Nienhuys
2021-07-11 16:30           ` [PATCH v6? 09/17] refs file-backend.c: deal with errno directly " Ævar Arnfjörð Bjarmason
2021-07-11 16:30           ` [PATCH v6? 10/17] refs API: remove refs_read_ref_full() wrapper Ævar Arnfjörð Bjarmason
2021-07-11 16:30           ` [PATCH v6? 11/17] refs API: make resolve_gitlink_ref() not set errno Ævar Arnfjörð Bjarmason
2021-07-11 16:30           ` [PATCH v6? 12/17] refs API: make refs_resolve_ref_unsafe() static Ævar Arnfjörð Bjarmason
2021-07-11 16:30           ` [PATCH v6? 13/17] refs API: make refs_resolve_refdup() not set errno Ævar Arnfjörð Bjarmason
2021-07-11 16:30           ` [PATCH v6? 14/17] refs API: make refs_ref_exists() " Ævar Arnfjörð Bjarmason
2021-07-11 16:30           ` [PATCH v6? 15/17] refs API: make resolve_ref_unsafe() " Ævar Arnfjörð Bjarmason
2021-07-13  8:13             ` Han-Wen Nienhuys
2021-07-14  8:32               ` Ævar Arnfjörð Bjarmason
2021-07-11 16:30           ` [PATCH v6? 16/17] refs API: make expand_ref() and repo_dwim_log() " Ævar Arnfjörð Bjarmason
2021-07-11 16:30           ` [PATCH v6? 17/17] refs API: don't leak "errno" in run_transaction_hook() Ævar Arnfjörð Bjarmason
2021-07-13  8:28           ` [PATCH v6? 00/17] refs API: get rid of errno setting entirely Han-Wen Nienhuys
2021-07-13 18:26             ` Ævar Arnfjörð Bjarmason
2021-07-14  8:38               ` Ævar Arnfjörð Bjarmason
2021-07-14  8:43                 ` Han-Wen Nienhuys
2021-07-14 11:43           ` [PATCH v7 0/6] refs: cleanup errno sideband ref related functions Ævar Arnfjörð Bjarmason
2021-07-14 11:43             ` [PATCH v7 1/6] refs: remove EINVAL errno output from specification of read_raw_ref_fn Ævar Arnfjörð Bjarmason
2021-07-14 11:43             ` [PATCH v7 2/6] refs/files-backend: stop setting errno from lock_ref_oid_basic Ævar Arnfjörð Bjarmason
2021-07-14 11:43             ` [PATCH v7 3/6] refs: make errno output explicit for read_raw_ref_fn Ævar Arnfjörð Bjarmason
2021-07-14 11:43             ` [PATCH v7 4/6] refs: add failure_errno to refs_read_raw_ref() signature Ævar Arnfjörð Bjarmason
2021-07-14 11:43             ` [PATCH v7 5/6] refs: explicitly return failure_errno from parse_loose_ref_contents Ævar Arnfjörð Bjarmason
2021-07-14 11:43             ` [PATCH v7 6/6] refs: make errno output explicit for refs_resolve_ref_unsafe Ævar Arnfjörð Bjarmason
2021-07-16 14:22             ` [PATCH v8 0/7] refs: cleanup errno sideband ref related functions Ævar Arnfjörð Bjarmason
2021-07-16 14:22               ` [PATCH v8 1/7] refs file backend: move raceproof_create_file() here Ævar Arnfjörð Bjarmason
2021-07-16 14:22               ` [PATCH v8 2/7] refs: remove EINVAL errno output from specification of read_raw_ref_fn Ævar Arnfjörð Bjarmason
2021-07-16 14:22               ` [PATCH v8 3/7] refs/files-backend: stop setting errno from lock_ref_oid_basic Ævar Arnfjörð Bjarmason
2021-07-16 14:22               ` [PATCH v8 4/7] refs: make errno output explicit for read_raw_ref_fn Ævar Arnfjörð Bjarmason
2021-07-16 14:22               ` [PATCH v8 5/7] refs: add failure_errno to refs_read_raw_ref() signature Ævar Arnfjörð Bjarmason
2021-07-16 14:22               ` [PATCH v8 6/7] refs: explicitly return failure_errno from parse_loose_ref_contents Ævar Arnfjörð Bjarmason
2021-07-16 14:22               ` [PATCH v8 7/7] refs: make errno output explicit for refs_resolve_ref_unsafe Ævar Arnfjörð Bjarmason
2021-07-20 10:33               ` [PATCH v9 0/7] refs: cleanup errno sideband ref related functions Ævar Arnfjörð Bjarmason
2021-07-20 10:33                 ` [PATCH v9 1/7] refs file backend: move raceproof_create_file() here Ævar Arnfjörð Bjarmason
2021-07-20 10:33                 ` [PATCH v9 2/7] refs: remove EINVAL errno output from specification of read_raw_ref_fn Ævar Arnfjörð Bjarmason
2021-07-20 10:33                 ` [PATCH v9 3/7] refs/files-backend: stop setting errno from lock_ref_oid_basic Ævar Arnfjörð Bjarmason
2021-07-20 10:33                 ` [PATCH v9 4/7] refs: make errno output explicit for read_raw_ref_fn Ævar Arnfjörð Bjarmason
2021-08-16 13:00                   ` Han-Wen Nienhuys
2021-07-20 10:33                 ` [PATCH v9 5/7] refs: add failure_errno to refs_read_raw_ref() signature Ævar Arnfjörð Bjarmason
2021-07-20 10:33                 ` [PATCH v9 6/7] refs: explicitly return failure_errno from parse_loose_ref_contents Ævar Arnfjörð Bjarmason
2021-08-13 20:54                   ` Jonathan Tan
2021-07-20 10:33                 ` [PATCH v9 7/7] refs: make errno output explicit for refs_resolve_ref_unsafe Ævar Arnfjörð Bjarmason
2021-07-26 23:49                 ` [PATCH v9 0/7] refs: cleanup errno sideband ref related functions Ævar Arnfjörð Bjarmason
2021-07-27  0:18                   ` Junio C Hamano
2021-08-23 11:52                 ` [PATCH v10 0/8] " Ævar Arnfjörð Bjarmason
2021-08-23 11:52                   ` [PATCH v10 1/8] refs file backend: move raceproof_create_file() here Ævar Arnfjörð Bjarmason
2021-08-23 11:52                   ` [PATCH v10 2/8] refs: remove EINVAL errno output from specification of read_raw_ref_fn Ævar Arnfjörð Bjarmason
2021-08-23 11:52                   ` [PATCH v10 3/8] refs/files-backend: stop setting errno from lock_ref_oid_basic Ævar Arnfjörð Bjarmason
2021-08-23 11:52                   ` [PATCH v10 4/8] refs: make errno output explicit for read_raw_ref_fn Ævar Arnfjörð Bjarmason
2021-08-23 11:52                   ` [PATCH v10 5/8] refs: add failure_errno to refs_read_raw_ref() signature Ævar Arnfjörð Bjarmason
2021-08-23 11:52                   ` [PATCH v10 6/8] branch tests: test for errno propagating on failing read Ævar Arnfjörð Bjarmason
2021-08-23 11:52                   ` [PATCH v10 7/8] refs: explicitly return failure_errno from parse_loose_ref_contents Ævar Arnfjörð Bjarmason
2021-08-23 11:52                   ` [PATCH v10 8/8] refs: make errno output explicit for refs_resolve_ref_unsafe Ævar Arnfjörð Bjarmason

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=cover-00.17-00000000000-20210711T162803Z-avarab@gmail.com \
    --to=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=hanwen@google.com \
    --cc=jonathantanmy@google.com \
    --cc=peff@peff.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.