git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2 8/8] refs: explicitly propagate errno from refs_read_raw_ref

From
Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Date
Jul 1, 2021, 12:26 UTC
Message-ID
<8735sydvzs.fsf@evledraar.gmail.com>
In-Reply-To
<2a9ebe43deac3da9baf241ff1e494f8210c27981.1623329869.git.gitgitgadget@gmail.com>
On Thu, Jun 10 2021, Han-Wen Nienhuys via GitGitGadget wrote:
Show 32 quoted lines
> From: Han-Wen Nienhuys <hanwen@google.com>
>
> The function refs_resolve_ref_unsafe_with_errno should produce an errno output.
> Rather than taking the value from the errno (which might contain garbage
> beforehand), explicitly propagate the failure_errno coming out of
> refs_read_raw_ref().
>
> Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
> Reviewed-by: Jonathan Tan <jonathantanmy@google.com>
> ---
>  refs.c | 38 ++++++++++++++------------------------
>  1 file changed, 14 insertions(+), 24 deletions(-)
>
> diff --git a/refs.c b/refs.c
> index 191cbf5a330f..92c4796078bb 100644
> --- a/refs.c
> +++ b/refs.c
> @@ -1686,11 +1686,11 @@ int refs_read_raw_ref(struct ref_store *ref_store, const char *refname,
>  					   type, failure_errno);
>  }
>  
> -/* This function needs to return a meaningful errno on failure */
> -static const char *
> -refs_resolve_ref_unsafe_implicit_errno(struct ref_store *refs,
> -				       const char *refname, int resolve_flags,
> -				       struct object_id *oid, int *flags)
> +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)
>  {

At this point I'm lost. We just introduced this function two commits ago, and now it's gone again. I guess the "we should update the comment" from an earlier reply of mine is addressed in some way here...

>  	static struct strbuf sb_refname = STRBUF_INIT;
>  	struct object_id unused_oid;
> @@ -1703,11 +1703,12 @@ refs_resolve_ref_unsafe_implicit_errno(struct ref_store *refs,

As an aside I really wish our hunk title detection would spot the rename & use the new name...

Show 64 quoted lines
>  		flags = &unused_flags;
>  
>  	*flags = 0;
> +	*failure_errno = 0;
>  
>  	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;
>  		}
>  
> @@ -1730,6 +1731,8 @@ refs_resolve_ref_unsafe_implicit_errno(struct ref_store *refs,
>  				      &read_flags, &read_failure)) {
>  			*flags |= read_flags;
>  
> +			*failure_errno = read_failure;
> +
>  			/* In reading mode, refs must eventually resolve */
>  			if (resolve_flags & RESOLVE_REF_READING)
>  				return NULL;
> @@ -1767,7 +1770,7 @@ refs_resolve_ref_unsafe_implicit_errno(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;
>  			}
>  
> @@ -1775,7 +1778,7 @@ refs_resolve_ref_unsafe_implicit_errno(struct ref_store *refs,
>  		}
>  	}
>  
> -	errno = ELOOP;
> +	*failure_errno = ELOOP;
>  	return NULL;
>  }
>  
> @@ -1783,22 +1786,9 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs, const char *refname,
>  				    int resolve_flags, struct object_id *oid,
>  				    int *flags)
>  {
> -	const char *result = refs_resolve_ref_unsafe_implicit_errno(
> -		refs, refname, resolve_flags, oid, flags);
> -	errno = 0;
> -	return result;
> -}
> -
> -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 *result = refs_resolve_ref_unsafe_implicit_errno(
> -		refs, refname, resolve_flags, oid, flags);
> -	*failure_errno = errno;
> -	return result;
> +	int ignore;
> +	return refs_resolve_ref_unsafe_with_errno(refs, refname, resolve_flags,
> +						  oid, flags, &ignore);
>  }

Okey, so here we have something like the "caller should explicitly ignore it" I suggested in <878s2qdy8y.fsf@evledraar.gmail.com>. We no longer set "errno" at all for the benefit of the callers of that function, but instead explicitly throw it away, our refs_resolve_ref_unsafe_with_errno() no longer sets errno.

But this end-state seems to have resulted in introducing new bugs. A bunch of functions are thin wrappers for refs_resolve_ref_unsafe(). Previously they could inspect errno on a -1 return, now they can't.

I didn't look at them all, but just the second one I looked at, refs_read_ref_full() has a verify_lock() caller which calls it, and that function then expects a meaningful errno that it in turn ferries up with "can't verify ref". It in turn is called by lock_ref_oid_basic(), it ferries up that strbuf with the error, which'll now have a meaningless strerror(0) in it.

So it seems to me that the refactoring being done here is halfway done, and results in a buggy end-state. The below diff is my attempt to fix that up for just one caller, things thath call resolve_gitlink_ref() (it's literally the third caller out of N, so I'm not picking and choosing).

In that case I believe that we don't actually have a regression because of your changes, but I think the changes below are the logical end-state of what you're starting here. I.e. we have a low-level function that may encounter an errno, and then callers removed from that via:

    index_path() -> resolve_gitlink_ref() -> refs_resolve_ref_unsafe()

Where the common case for index_path() is to report the error we got, but it doesn't call die_errno() or error_errno() now, but really should, per the below diff (which you can consider to have by SOB if you want to pick it up).

That passes all tests, except one where we actually fail because of what
I'd argue is a better error message. i.e this in t3700-add.sh:
	
	+ diff -u expect actual
	--- expect      2021-07-01 13:01:23.267001881 +0000
	+++ actual      2021-07-01 13:01:23.267001881 +0000
	@@ -1,2 +1,2 @@
	-error: 'empty/' does not have a commit checked out
	+error: 'empty/' does not have a commit checked out: No such file or directory
	 fatal: adding files failed

In one sense I don't think you need to do this excercise of going all the way to the top of callers like index_path() that don't get an errno now, but in another sense I think you really do.

By explicitly clearing "errno" as your end-state does and declaring that callers of refs_resolve_ref_unsafe() must be as happy to ignore "errno" as your own callers are, you're potentially introducing subtle bugs unless we go all the way to the top of the callstack and check if anything above us cares about errno, which we'll need due to do due to its global nature.

I think I'd really only be confident that we've got them all if your chance was amended to something where we add such "int *maybe_errno" parameters to all upstream callers that may relay the <0 return value we got.

diff --git a/builtin/update-index.c b/builtin/update-index.c
index f1f16f2de52..54fcbc5be10 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -272,6 +272,7 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len
 {
 	int option;
 	struct cache_entry *ce;
+	int ignore_errno;
 
 	/* Was the old index entry already up-to-date? */
 	if (old && !ce_stage(old) && !ce_match_stat(old, st, 0))
@@ -285,7 +286,7 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len
 	ce->ce_mode = ce_mode_from_stat(old, st->st_mode);
 
 	if (index_path(&the_index, &ce->oid, path, st,
-		       info_only ? 0 : HASH_WRITE_OBJECT)) {
+		       info_only ? 0 : HASH_WRITE_OBJECT, &ignore_errno)) {
 		discard_cache_entry(ce);
 		return -1;
 	}
@@ -325,14 +326,15 @@ static int process_directory(const char *path, int len, struct stat *st)
 {
 	struct object_id oid;
 	int pos = cache_name_pos(path, len);
+	int their_errno = 0;
 
 	/* Exact match: file or existing gitlink */
 	if (pos >= 0) {
 		const struct cache_entry *ce = active_cache[pos];
 		if (S_ISGITLINK(ce->ce_mode)) {
-
 			/* Do nothing to the index if there is no HEAD! */
-			if (resolve_gitlink_ref(path, "HEAD", &oid) < 0)
+			int ignore_errno;
+			if (resolve_gitlink_ref(path, "HEAD", &oid, &ignore_errno) < 0)
 				return 0;
 
 			return add_one_path(ce, path, len, st);
@@ -358,11 +360,16 @@ static int process_directory(const char *path, int len, struct stat *st)
 	}
 
 	/* No match - should we add it as a gitlink? */
-	if (!resolve_gitlink_ref(path, "HEAD", &oid))
+	if (resolve_gitlink_ref(path, "HEAD", &oid, &their_errno) >= 0)
 		return add_one_path(NULL, path, len, st);
 
 	/* Error out. */
-	return error("%s: is a directory - add files inside instead", path);
+	if (their_errno) {
+		errno = their_errno;
+		return error_errno("%s: is a directory - add files inside instead", path);
+	} else {
+		return error("%s: is a directory - add files inside instead", path);
+	}
 }
 
 static int process_path(const char *path, struct stat *st, int stat_errno)
diff --git a/cache.h b/cache.h
index ba04ff8bd36..62e5ac335b8 100644
--- a/cache.h
+++ b/cache.h
@@ -879,7 +879,9 @@ int ie_modified(struct index_state *, const struct cache_entry *, struct stat *,
 #define HASH_FORMAT_CHECK 2
 #define HASH_RENORMALIZE  4
 int index_fd(struct index_state *istate, struct object_id *oid, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags);
-int index_path(struct index_state *istate, struct object_id *oid, const char *path, struct stat *st, unsigned flags);
+int index_path(struct index_state *istate, struct object_id *oid,
+	       const char *path, struct stat *st, unsigned flags,
+	       int *maybe_errno);
 
 /*
  * Record to sd the data from st that we use to check whether a file
diff --git a/combine-diff.c b/combine-diff.c
index 7d925ce9ce4..7ac9bc6e943 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -1059,7 +1059,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
 			elem->mode = canon_mode(st.st_mode);
 		} else if (S_ISDIR(st.st_mode)) {
 			struct object_id oid;
-			if (resolve_gitlink_ref(elem->path, "HEAD", &oid) < 0)
+			int ignore_errno;
+			if (resolve_gitlink_ref(elem->path, "HEAD", &oid, &ignore_errno) < 0)
 				result = grab_blob(opt->repo, &elem->oid,
 						   elem->mode, &result_size,
 						   NULL, NULL);
diff --git a/diff-lib.c b/diff-lib.c
index c2ac9250fe9..4ae27851cb9 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -40,6 +40,7 @@ static int check_removed(const struct index_state *istate, const struct cache_en
 		return 1;
 	if (S_ISDIR(st->st_mode)) {
 		struct object_id sub;
+		int ignore_errno;
 
 		/*
 		 * If ce is already a gitlink, we can have a plain
@@ -53,7 +54,7 @@ static int check_removed(const struct index_state *istate, const struct cache_en
 		 * a directory --- the blob was removed!
 		 */
 		if (!S_ISGITLINK(ce->ce_mode) &&
-		    resolve_gitlink_ref(ce->name, "HEAD", &sub))
+		    resolve_gitlink_ref(ce->name, "HEAD", &sub, &ignore_errno))
 			return 1;
 	}
 	return 0;
diff --git a/diff.c b/diff.c
index 52c791574b7..972ad0e57de 100644
--- a/diff.c
+++ b/diff.c
@@ -4426,6 +4426,7 @@ static void diff_fill_oid_info(struct diff_filespec *one, struct index_state *is
 {
 	if (DIFF_FILE_VALID(one)) {
 		if (!one->oid_valid) {
+			int maybe_errno = 0;
 			struct stat st;
 			if (one->is_stdin) {
 				oidclr(&one->oid);
@@ -4433,8 +4434,14 @@ static void diff_fill_oid_info(struct diff_filespec *one, struct index_state *is
 			}
 			if (lstat(one->path, &st) < 0)
 				die_errno("stat '%s'", one->path);
-			if (index_path(istate, &one->oid, one->path, &st, 0))
-				die("cannot hash %s", one->path);
+			if (index_path(istate, &one->oid, one->path, &st, 0, &maybe_errno)) {
+				if (maybe_errno) {
+					errno = maybe_errno;
+ 					die_errno("cannot hash %s", one->path);
+				} else {
+ 					die("cannot hash %s", one->path);
+				}
+			}
 		}
 	}
 	else
diff --git a/dir.c b/dir.c
index ebe5ec046e0..95eb4ada718 100644
--- a/dir.c
+++ b/dir.c
@@ -2967,9 +2967,10 @@ static int remove_dir_recurse(struct strbuf *path, int flag, int *kept_up)
 	int only_empty = (flag & REMOVE_DIR_EMPTY_ONLY);
 	int keep_toplevel = (flag & REMOVE_DIR_KEEP_TOPLEVEL);
 	struct object_id submodule_head;
+	int ignore_errno;
 
 	if ((flag & REMOVE_DIR_KEEP_NESTED_GIT) &&
-	    !resolve_gitlink_ref(path->buf, "HEAD", &submodule_head)) {
+	    resolve_gitlink_ref(path->buf, "HEAD", &submodule_head, &ignore_errno) < 0) {
 		/* Do not descend and nuke a nested git work tree. */
 		if (kept_up)
 			*kept_up = 1;
diff --git a/notes-merge.c b/notes-merge.c
index 46c1f7c7f11..f7e0091bd72 100644
--- a/notes-merge.c
+++ b/notes-merge.c
@@ -698,6 +698,7 @@ int notes_merge_commit(struct notes_merge_options *o,
 	while ((e = readdir_skip_dot_and_dotdot(dir)) != NULL) {
 		struct stat st;
 		struct object_id obj_oid, blob_oid;
+		int maybe_errno = 0;
 
 		if (get_oid_hex(e->d_name, &obj_oid)) {
 			if (o->verbosity >= 3)
@@ -710,8 +711,14 @@ int notes_merge_commit(struct notes_merge_options *o,
 		/* write file as blob, and add to partial_tree */
 		if (stat(path.buf, &st))
 			die_errno("Failed to stat '%s'", path.buf);
-		if (index_path(o->repo->index, &blob_oid, path.buf, &st, HASH_WRITE_OBJECT))
-			die("Failed to write blob object from '%s'", path.buf);
+		if (index_path(o->repo->index, &blob_oid, path.buf, &st, HASH_WRITE_OBJECT, &maybe_errno)) {
+			if (maybe_errno) {
+				errno = maybe_errno;
+				die_errno("Failed to write blob object from '%s'", path.buf);
+			} else {
+				die("Failed to write blob object from '%s'", path.buf);
+			}
+		}
 		if (add_note(partial_tree, &obj_oid, &blob_oid, NULL))
 			die("Failed to add resolved note '%s' to notes tree",
 			    path.buf);
diff --git a/object-file.c b/object-file.c
index f233b440b22..0030854dcdf 100644
--- a/object-file.c
+++ b/object-file.c
@@ -2260,7 +2260,8 @@ int index_fd(struct index_state *istate, struct object_id *oid,
 }
 
 int index_path(struct index_state *istate, struct object_id *oid,
-	       const char *path, struct stat *st, unsigned flags)
+	       const char *path, struct stat *st, unsigned flags,
+	       int *maybe_errno)
 {
 	int fd;
 	struct strbuf sb = STRBUF_INIT;
@@ -2286,7 +2287,7 @@ int index_path(struct index_state *istate, struct object_id *oid,
 		strbuf_release(&sb);
 		break;
 	case S_IFDIR:
-		return resolve_gitlink_ref(path, "HEAD", oid);
+		return resolve_gitlink_ref(path, "HEAD", oid, maybe_errno);
 	default:
 		return error(_("%s: unsupported file type"), path);
 	}
diff --git a/read-cache.c b/read-cache.c
index 77961a38854..a40a326587f 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -256,6 +256,7 @@ static int ce_compare_link(const struct cache_entry *ce, size_t expected_size)
 static int ce_compare_gitlink(const struct cache_entry *ce)
 {
 	struct object_id oid;
+	int ignore_errno;
 
 	/*
 	 * We don't actually require that the .git directory
@@ -265,7 +266,7 @@ static int ce_compare_gitlink(const struct cache_entry *ce)
 	 *
 	 * If so, we consider it always to match.
 	 */
-	if (resolve_gitlink_ref(ce->name, "HEAD", &oid) < 0)
+	if (resolve_gitlink_ref(ce->name, "HEAD", &oid, &ignore_errno) < 0)
 		return 0;
 	return !oideq(&oid, &ce->oid);
 }
@@ -748,8 +749,13 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
 
 	namelen = strlen(path);
 	if (S_ISDIR(st_mode)) {
-		if (resolve_gitlink_ref(path, "HEAD", &oid) < 0)
-			return error(_("'%s' does not have a commit checked out"), path);
+		int their_errno = 0;
+		if (resolve_gitlink_ref(path, "HEAD", &oid, &their_errno) < 0) {
+			if (their_errno)
+				return error_errno(_("'%s' does not have a commit checked out"), path);
+			else
+				return error(_("'%s' does not have a commit checked out"), path);
+		}
 		while (namelen && path[namelen-1] == '/')
 			namelen--;
 	}
@@ -799,9 +805,16 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
 		}
 	}
 	if (!intent_only) {
-		if (index_path(istate, &ce->oid, path, st, hash_flags)) {
+		int maybe_errno = 0;
+		if (index_path(istate, &ce->oid, path, st, hash_flags,
+			       &maybe_errno)) {
 			discard_cache_entry(ce);
-			return error(_("unable to index file '%s'"), path);
+			if (maybe_errno) {
+				errno = maybe_errno;
+				return error_errno(_("unable to index file '%s'"), path);
+			} else {
+				return error(_("unable to index file '%s'"), path);
+			}
 		}
 	} else
 		set_object_name_for_intent_to_add_entry(ce);
diff --git a/refs.c b/refs.c
index 92c4796078b..082b6b3d133 100644
--- a/refs.c
+++ b/refs.c
@@ -1807,7 +1807,7 @@ const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
 }
 
 int resolve_gitlink_ref(const char *submodule, const char *refname,
-			struct object_id *oid)
+			struct object_id *oid, int *maybe_errno)
 {
 	struct ref_store *refs;
 	int flags;
@@ -1817,7 +1817,8 @@ int resolve_gitlink_ref(const char *submodule, const char *refname,
 	if (!refs)
 		return -1;
 
-	if (!refs_resolve_ref_unsafe(refs, refname, 0, oid, &flags) ||
+	if (!refs_resolve_ref_unsafe_with_errno(refs, refname, 0, oid, &flags,
+		    maybe_errno) ||
 	    is_null_oid(oid))
 		return -1;
 	return 0;
diff --git a/refs.h b/refs.h
index 48970dfc7e0..b0505b35698 100644
--- a/refs.h
+++ b/refs.h
@@ -133,10 +133,16 @@ int peel_iterated_oid(const struct object_id *base, struct object_id *peeled);
  * Resolve refname in the nested "gitlink" repository in the specified
  * submodule (which must be non-NULL). If the resolution is
  * successful, return 0 and set oid to the name of the object;
- * otherwise, return a non-zero value.
+ * otherwise, return negative value.
+ *
+ * If we encounter an error we may have an errno to report from
+ * refs_resolve_ref_unsafe_with_errno(), or we might have hit another
+ * error. Set your `maybe_errno` to 0 beforehand, and check it after
+ * an error where we return a negative value to see if you should
+ * report the errno as well.
  */
 int resolve_gitlink_ref(const char *submodule, const char *refname,
-			struct object_id *oid);
+			struct object_id *oid, int *maybe_errno);
 
 /*
  * Return true iff abbrev_name is a possible abbreviation for
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 01c9bd0dbf0..9ed58c40de6 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -870,6 +870,7 @@ static int verify_lock(struct ref_store *ref_store, struct ref_lock *lock,
 			       &lock->old_oid, NULL)) {
 		if (old_oid) {
 			int save_errno = errno;
+			BUG("got here");
 			strbuf_addf(err, "can't verify ref '%s'", lock->ref_name);
 			errno = save_errno;
 			return -1;
diff --git a/unpack-trees.c b/unpack-trees.c
index f88a69f8e71..dd90787c56c 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -1986,7 +1986,9 @@ static int verify_clean_subdirectory(const struct cache_entry *ce,
 
 	if (S_ISGITLINK(ce->ce_mode)) {
 		struct object_id oid;
-		int sub_head = resolve_gitlink_ref(ce->name, "HEAD", &oid);
+		int ignore_errno;
+		int sub_head = resolve_gitlink_ref(ce->name, "HEAD", &oid,
+						   &ignore_errno);
 		/*
 		 * If we are not going to update the submodule, then
 		 * we don't care.
Previous: Han-Wen Nienhuys via GitGitGadgetNext: Han-Wen Nienhuys
Message 37 of 148 in “refs: cleanup errno sideband ref related functions”
  1. 0/8 refs: cleanup errno sideband ref related functionsHan-Wen Nienhuys via GitGitGadget, Apr 29, 2021
  2. 1/8 refs: remove EINVAL specification from the errno sideband in read_raw_ref_fnHan-Wen Nienhuys via GitGitGadget, Apr 29, 2021
  3. Junio C HamanoApr 30, 2021
  4. Han-Wen NienhuysMay 19, 2021
  5. Jonathan TanJun 3, 2021
  6. Han-Wen NienhuysJun 9, 2021
  7. 2/8 refs/files-backend: stop setting errno from lock_ref_oid_basicHan-Wen Nienhuys via GitGitGadget, Apr 29, 2021
  8. Junio C HamanoApr 30, 2021
  9. Han-Wen NienhuysMay 19, 2021
  10. Jonathan TanJun 3, 2021
  11. Han-Wen NienhuysJun 10, 2021
  12. 4/8 refs: make errno output explicit for refs_resolve_ref_unsafeHan-Wen Nienhuys via GitGitGadget, Apr 29, 2021
  13. Jonathan TanJun 3, 2021
  14. Han-Wen NienhuysJun 10, 2021
  15. 5/8 refs: add failure_errno to refs_read_raw_ref() signatureHan-Wen Nienhuys via GitGitGadget, Apr 29, 2021
  16. 3/8 refs: make errno output explicit for read_raw_ref_fnHan-Wen Nienhuys via GitGitGadget, Apr 29, 2021
  17. Junio C HamanoApr 30, 2021
  18. Junio C HamanoApr 30, 2021
  19. Han-Wen NienhuysMay 19, 2021
  20. Jonathan TanJun 3, 2021
  21. Han-Wen NienhuysJun 10, 2021
  22. 8/8 refs: explicitly propagate errno from refs_read_raw_refHan-Wen Nienhuys via GitGitGadget, Apr 29, 2021
  23. 6/8 refs: clear errno return in refs_resolve_ref_unsafe()Han-Wen Nienhuys via GitGitGadget, Apr 29, 2021
  24. Jonathan TanJun 3, 2021
  25. Han-Wen NienhuysJun 10, 2021
  26. 7/8 refs: stop setting EINVAL and ELOOP in symref resolutionHan-Wen Nienhuys via GitGitGadget, Apr 29, 2021
  27. Jonathan TanJun 3, 2021
  28. Han-Wen NienhuysJun 10, 2021
  29. Jonathan TanJun 3, 2021
  30. Han-Wen NienhuysJun 9, 2021
  31. 0/8 refs: cleanup errno sideband ref related functionsHan-Wen Nienhuys via GitGitGadget, Jun 10, 2021
  32. 5/8 refs: use refs_resolve_ref_unsafe_with_errno() where neededHan-Wen Nienhuys via GitGitGadget, Jun 10, 2021
  33. Ævar Arnfjörð BjarmasonJul 1, 2021
  34. 4/8 refs: make errno output explicit for refs_resolve_ref_unsafeHan-Wen Nienhuys via GitGitGadget, Jun 10, 2021
  35. Ævar Arnfjörð BjarmasonJul 1, 2021
  36. 8/8 refs: explicitly propagate errno from refs_read_raw_refHan-Wen Nienhuys via GitGitGadget, Jun 10, 2021
  37. Ævar Arnfjörð BjarmasonJul 1, 2021
  38. Han-Wen NienhuysJul 5, 2021
  39. Ævar Arnfjörð BjarmasonJul 5, 2021
  40. Han-Wen NienhuysJul 5, 2021
  41. 1/8 refs: remove EINVAL errno output from specification of read_raw_ref_fnHan-Wen Nienhuys via GitGitGadget, Jun 10, 2021
  42. 2/8 refs/files-backend: stop setting errno from lock_ref_oid_basicHan-Wen Nienhuys via GitGitGadget, Jun 10, 2021
  43. Ævar Arnfjörð BjarmasonJul 1, 2021
  44. Han-Wen NienhuysJul 5, 2021
  45. 3/8 refs: make errno output explicit for read_raw_ref_fnHan-Wen Nienhuys via GitGitGadget, Jun 10, 2021
  46. Ævar Arnfjörð BjarmasonJul 1, 2021
  47. Han-Wen NienhuysJul 5, 2021
  48. 6/8 refs: add failure_errno to refs_read_raw_ref() signatureHan-Wen Nienhuys via GitGitGadget, Jun 10, 2021
  49. Ævar Arnfjörð BjarmasonJul 1, 2021
  50. 7/8 refs: clear errno return in refs_resolve_ref_unsafe()Han-Wen Nienhuys via GitGitGadget, Jun 10, 2021
  51. Ævar Arnfjörð BjarmasonJul 1, 2021
  52. Han-Wen NienhuysJun 14, 2021
  53. 0/5 refs: cleanup errno sideband ref related functionsHan-Wen Nienhuys via GitGitGadget, Jul 5, 2021
  54. 1/5 refs: remove EINVAL errno output from specification of read_raw_ref_fnHan-Wen Nienhuys via GitGitGadget, Jul 5, 2021
  55. 2/5 refs/files-backend: stop setting errno from lock_ref_oid_basicHan-Wen Nienhuys via GitGitGadget, Jul 5, 2021
  56. 3/5 refs: make errno output explicit for read_raw_ref_fnHan-Wen Nienhuys via GitGitGadget, Jul 5, 2021
  57. 4/5 refs: add failure_errno to refs_read_raw_ref() signatureHan-Wen Nienhuys via GitGitGadget, Jul 5, 2021
  58. Junio C HamanoJul 6, 2021
  59. 5/5 refs: make errno output explicit for refs_resolve_ref_unsafeHan-Wen Nienhuys via GitGitGadget, Jul 5, 2021
  60. Ævar Arnfjörð BjarmasonJul 6, 2021
  61. Han-Wen NienhuysJul 6, 2021
  62. Ævar Arnfjörð BjarmasonJul 6, 2021
  63. Han-Wen NienhuysJul 6, 2021
  64. 0/6 refs: cleanup errno sideband ref related functionsHan-Wen Nienhuys via GitGitGadget, Jul 6, 2021
  65. 1/6 refs: remove EINVAL errno output from specification of read_raw_ref_fnHan-Wen Nienhuys via GitGitGadget, Jul 6, 2021
  66. 2/6 refs/files-backend: stop setting errno from lock_ref_oid_basicHan-Wen Nienhuys via GitGitGadget, Jul 6, 2021
  67. 5/6 refs: explicitly return failure_errno from parse_loose_ref_contentsHan-Wen Nienhuys via GitGitGadget, Jul 6, 2021
  68. Junio C HamanoJul 6, 2021
  69. Han-Wen NienhuysJul 7, 2021
  70. 3/6 refs: make errno output explicit for read_raw_ref_fnHan-Wen Nienhuys via GitGitGadget, Jul 6, 2021
  71. 4/6 refs: add failure_errno to refs_read_raw_ref() signatureHan-Wen Nienhuys via GitGitGadget, Jul 6, 2021
  72. Junio C HamanoJul 6, 2021
  73. 6/6 refs: make errno output explicit for refs_resolve_ref_unsafeHan-Wen Nienhuys via GitGitGadget, Jul 6, 2021
  74. 0/6 refs: cleanup errno sideband ref related functionsHan-Wen Nienhuys via GitGitGadget, Jul 7, 2021
  75. 1/6 refs: remove EINVAL errno output from specification of read_raw_ref_fnHan-Wen Nienhuys via GitGitGadget, Jul 7, 2021
  76. 2/6 refs/files-backend: stop setting errno from lock_ref_oid_basicHan-Wen Nienhuys via GitGitGadget, Jul 7, 2021
  77. Ævar Arnfjörð BjarmasonJul 11, 2021
  78. Han-Wen NienhuysJul 13, 2021
  79. 3/6 refs: make errno output explicit for read_raw_ref_fnHan-Wen Nienhuys via GitGitGadget, Jul 7, 2021
  80. Ævar Arnfjörð BjarmasonJul 11, 2021
  81. 4/6 refs: add failure_errno to refs_read_raw_ref() signatureHan-Wen Nienhuys via GitGitGadget, Jul 7, 2021
  82. Ævar Arnfjörð BjarmasonJul 11, 2021
  83. Han-Wen NienhuysJul 13, 2021
  84. 5/6 refs: explicitly return failure_errno from parse_loose_ref_contentsHan-Wen Nienhuys via GitGitGadget, Jul 7, 2021
  85. Ævar Arnfjörð BjarmasonJul 11, 2021
  86. 6/6 refs: make errno output explicit for refs_resolve_ref_unsafeHan-Wen Nienhuys via GitGitGadget, Jul 7, 2021
  87. Junio C HamanoJul 7, 2021
  88. 00/17 refs API: get rid of errno setting entirelyÆvar Arnfjörð Bjarmason, Jul 11, 2021
  89. 01/17 refs: remove EINVAL errno output from specification of read_raw_ref_fnÆvar Arnfjörð Bjarmason, Jul 11, 2021
  90. 03/17 refs: make errno output explicit for read_raw_ref_fnÆvar Arnfjörð Bjarmason, Jul 11, 2021
  91. 02/17 refs/files-backend: stop setting errno from lock_ref_oid_basicÆvar Arnfjörð Bjarmason, Jul 11, 2021
  92. 04/17 refs: add failure_errno to refs_read_raw_ref() signatureÆvar Arnfjörð Bjarmason, Jul 11, 2021
  93. 05/17 refs: explicitly return failure_errno from parse_loose_ref_contentsÆvar Arnfjörð Bjarmason, Jul 11, 2021
  94. 06/17 refs: make errno output explicit for refs_resolve_ref_unsafeÆvar Arnfjörð Bjarmason, Jul 11, 2021
  95. 07/17 refs: make errno ignoring explicit in lock_ref_oid_basic()Ævar Arnfjörð Bjarmason, Jul 11, 2021
  96. 10/17 refs API: remove refs_read_ref_full() wrapperÆvar Arnfjörð Bjarmason, Jul 11, 2021
  97. 11/17 refs API: make resolve_gitlink_ref() not set errnoÆvar Arnfjörð Bjarmason, Jul 11, 2021
  98. 08/17 refs file-backend.c: stop setting "EBUSY" in verify_lock()Ævar Arnfjörð Bjarmason, Jul 11, 2021
  99. Han-Wen NienhuysJul 13, 2021
  100. 09/17 refs file-backend.c: deal with errno directly in verify_lock()Ævar Arnfjörð Bjarmason, Jul 11, 2021
  101. 12/17 refs API: make refs_resolve_ref_unsafe() staticÆvar Arnfjörð Bjarmason, Jul 11, 2021
  102. 13/17 refs API: make refs_resolve_refdup() not set errnoÆvar Arnfjörð Bjarmason, Jul 11, 2021
  103. 14/17 refs API: make refs_ref_exists() not set errnoÆvar Arnfjörð Bjarmason, Jul 11, 2021
  104. 15/17 refs API: make resolve_ref_unsafe() not set errnoÆvar Arnfjörð Bjarmason, Jul 11, 2021
  105. Han-Wen NienhuysJul 13, 2021
  106. Ævar Arnfjörð BjarmasonJul 14, 2021
  107. 17/17 refs API: don't leak "errno" in run_transaction_hook()Ævar Arnfjörð Bjarmason, Jul 11, 2021
  108. 16/17 refs API: make expand_ref() and repo_dwim_log() not set errnoÆvar Arnfjörð Bjarmason, Jul 11, 2021
  109. Han-Wen NienhuysJul 13, 2021
  110. Ævar Arnfjörð BjarmasonJul 13, 2021
  111. Ævar Arnfjörð BjarmasonJul 14, 2021
  112. Han-Wen NienhuysJul 14, 2021
  113. 0/6 refs: cleanup errno sideband ref related functionsÆvar Arnfjörð Bjarmason, Jul 14, 2021
  114. 1/6 refs: remove EINVAL errno output from specification of read_raw_ref_fnÆvar Arnfjörð Bjarmason, Jul 14, 2021
  115. 2/6 refs/files-backend: stop setting errno from lock_ref_oid_basicÆvar Arnfjörð Bjarmason, Jul 14, 2021
  116. 3/6 refs: make errno output explicit for read_raw_ref_fnÆvar Arnfjörð Bjarmason, Jul 14, 2021
  117. 4/6 refs: add failure_errno to refs_read_raw_ref() signatureÆvar Arnfjörð Bjarmason, Jul 14, 2021
  118. 5/6 refs: explicitly return failure_errno from parse_loose_ref_contentsÆvar Arnfjörð Bjarmason, Jul 14, 2021
  119. 6/6 refs: make errno output explicit for refs_resolve_ref_unsafeÆvar Arnfjörð Bjarmason, Jul 14, 2021
  120. 0/7 refs: cleanup errno sideband ref related functionsÆvar Arnfjörð Bjarmason, Jul 16, 2021
  121. 1/7 refs file backend: move raceproof_create_file() hereÆvar Arnfjörð Bjarmason, Jul 16, 2021
  122. 3/7 refs/files-backend: stop setting errno from lock_ref_oid_basicÆvar Arnfjörð Bjarmason, Jul 16, 2021
  123. 2/7 refs: remove EINVAL errno output from specification of read_raw_ref_fnÆvar Arnfjörð Bjarmason, Jul 16, 2021
  124. 4/7 refs: make errno output explicit for read_raw_ref_fnÆvar Arnfjörð Bjarmason, Jul 16, 2021
  125. 5/7 refs: add failure_errno to refs_read_raw_ref() signatureÆvar Arnfjörð Bjarmason, Jul 16, 2021
  126. 6/7 refs: explicitly return failure_errno from parse_loose_ref_contentsÆvar Arnfjörð Bjarmason, Jul 16, 2021
  127. 7/7 refs: make errno output explicit for refs_resolve_ref_unsafeÆvar Arnfjörð Bjarmason, Jul 16, 2021
  128. 0/7 refs: cleanup errno sideband ref related functionsÆvar Arnfjörð Bjarmason, Jul 20, 2021
  129. 1/7 refs file backend: move raceproof_create_file() hereÆvar Arnfjörð Bjarmason, Jul 20, 2021
  130. 2/7 refs: remove EINVAL errno output from specification of read_raw_ref_fnÆvar Arnfjörð Bjarmason, Jul 20, 2021
  131. 3/7 refs/files-backend: stop setting errno from lock_ref_oid_basicÆvar Arnfjörð Bjarmason, Jul 20, 2021
  132. 4/7 refs: make errno output explicit for read_raw_ref_fnÆvar Arnfjörð Bjarmason, Jul 20, 2021
  133. Han-Wen NienhuysAug 16, 2021
  134. 5/7 refs: add failure_errno to refs_read_raw_ref() signatureÆvar Arnfjörð Bjarmason, Jul 20, 2021
  135. 6/7 refs: explicitly return failure_errno from parse_loose_ref_contentsÆvar Arnfjörð Bjarmason, Jul 20, 2021
  136. Jonathan TanAug 13, 2021
  137. 7/7 refs: make errno output explicit for refs_resolve_ref_unsafeÆvar Arnfjörð Bjarmason, Jul 20, 2021
  138. Ævar Arnfjörð BjarmasonJul 26, 2021
  139. Junio C HamanoJul 27, 2021
  140. 0/8 refs: cleanup errno sideband ref related functionsÆvar Arnfjörð Bjarmason, Aug 23, 2021
  141. 1/8 refs file backend: move raceproof_create_file() hereÆvar Arnfjörð Bjarmason, Aug 23, 2021
  142. 2/8 refs: remove EINVAL errno output from specification of read_raw_ref_fnÆvar Arnfjörð Bjarmason, Aug 23, 2021
  143. 3/8 refs/files-backend: stop setting errno from lock_ref_oid_basicÆvar Arnfjörð Bjarmason, Aug 23, 2021
  144. 4/8 refs: make errno output explicit for read_raw_ref_fnÆvar Arnfjörð Bjarmason, Aug 23, 2021
  145. 5/8 refs: add failure_errno to refs_read_raw_ref() signatureÆvar Arnfjörð Bjarmason, Aug 23, 2021
  146. 6/8 branch tests: test for errno propagating on failing readÆvar Arnfjörð Bjarmason, Aug 23, 2021
  147. 7/8 refs: explicitly return failure_errno from parse_loose_ref_contentsÆvar Arnfjörð Bjarmason, Aug 23, 2021
  148. 8/8 refs: make errno output explicit for refs_resolve_ref_unsafeÆvar Arnfjörð Bjarmason, Aug 23, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.