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

[PATCH 14/18] lock_ref_sha1_basic(): improve diagnostics for D/F conflicts

From
Michael Haggerty <mhagger@alum.mit.edu>
Date
May 1, 2015, 12:25 UTC
Message-ID
<1430483158-14349-15-git-send-email-mhagger@alum.mit.edu>
In-Reply-To
<1430483158-14349-1-git-send-email-mhagger@alum.mit.edu>

If there is a failure to lock that is likely caused by a D/F conflict, invoke verify_refname_available() to try to generate a more helpful error message. If that function doesn't detect an error (which could happen if, for example, some non-reference file is blocking the deletion of an otherwise-empty directory tree or if there was a race with another process that just deleted the offending reference), then generate the strerror-based error message like before.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 refs.c                             | 16 ++++++++++++----
 t/t1404-update-ref-df-conflicts.sh |  8 ++++----
 2 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/refs.c b/refs.c
index 1b466bc..cdbd31a 100644
--- a/refs.c
+++ b/refs.c
@@ -2350,8 +2350,12 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
 		ref_file = git_path("%s", orig_refname);
 		if (remove_empty_directories(ref_file)) {
 			last_errno = errno;
-			strbuf_addf(err, "there are still refs under '%s'",
-				    orig_refname);
+
+			if (!verify_refname_available(orig_refname, extras, skip,
+						      get_loose_refs(&ref_cache), err))
+				strbuf_addf(err, "there are still refs under '%s'",
+					    orig_refname);
+
 			goto error_return;
 		}
 		refname = resolve_ref_unsafe(orig_refname, resolve_flags,
@@ -2361,8 +2365,12 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
 	    *type_p = type;
 	if (!refname) {
 		last_errno = errno;
-		strbuf_addf(err, "unable to resolve reference %s: %s",
-			    orig_refname, strerror(errno));
+		if (last_errno != ENOTDIR ||
+		    !verify_refname_available(orig_refname, extras, skip,
+					      get_loose_refs(&ref_cache), err))
+			strbuf_addf(err, "unable to resolve reference %s: %s",
+				    orig_refname, strerror(last_errno));
+
 		goto error_return;
 	}
 	/*
diff --git a/t/t1404-update-ref-df-conflicts.sh b/t/t1404-update-ref-df-conflicts.sh
index 136fb48..11b6d5b 100755
--- a/t/t1404-update-ref-df-conflicts.sh
+++ b/t/t1404-update-ref-df-conflicts.sh
@@ -36,7 +36,7 @@ test_expect_success 'existing loose ref is a simple prefix of new' '
 
 	prefix=refs/1l &&
 	test_update_rejected $prefix "a c e" false "b c/x d" \
-		"unable to resolve reference $prefix/c/x: Not a directory"
+		"$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x$Q"
 
 '
 
@@ -52,7 +52,7 @@ test_expect_success 'existing loose ref is a deeper prefix of new' '
 
 	prefix=refs/2l &&
 	test_update_rejected $prefix "a c e" false "b c/x/y d" \
-		"unable to resolve reference $prefix/c/x/y: Not a directory"
+		"$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x/y$Q"
 
 '
 
@@ -68,7 +68,7 @@ test_expect_success 'new ref is a simple prefix of existing loose' '
 
 	prefix=refs/3l &&
 	test_update_rejected $prefix "a c/x e" false "b c d" \
-		"there are still refs under $Q$prefix/c$Q"
+		"$Q$prefix/c/x$Q exists; cannot create $Q$prefix/c$Q"
 
 '
 
@@ -84,7 +84,7 @@ test_expect_success 'new ref is a deeper prefix of existing loose' '
 
 	prefix=refs/4l &&
 	test_update_rejected $prefix "a c/x/y e" false "b c d" \
-		"there are still refs under $Q$prefix/c$Q"
+		"$Q$prefix/c/x/y$Q exists; cannot create $Q$prefix/c$Q"
 
 '
 
-- 
2.1.4
Previous: Michael HaggertyNext: Michael Haggerty
Message 19 of 25 in “Improve handling of D/F conflicts”
  1. 00/18 Improve handling of D/F conflictsMichael Haggerty, May 1, 2015
  2. 01/18 t1404: new tests of D/F conflicts within ref transactionsMichael Haggerty, May 1, 2015
  3. Eric SunshineMay 5, 2015
  4. Michael HaggertyMay 5, 2015
  5. 02/18 is_refname_available(): explain the reason for an early exitMichael Haggerty, May 1, 2015
  6. Stefan BellerMay 1, 2015
  7. Michael HaggertyMay 5, 2015
  8. 03/18 is_refname_available(): avoid shadowing "dir" variableMichael Haggerty, May 1, 2015
  9. 04/18 is_refname_available(): convert local variable "dirname" to strbufMichael Haggerty, May 1, 2015
  10. 05/18 entry_matches(): inline functionMichael Haggerty, May 1, 2015
  11. 06/18 report_refname_conflict(): inline functionMichael Haggerty, May 1, 2015
  12. 07/18 struct nonmatching_ref_data: store a refname instead of a ref_entryMichael Haggerty, May 1, 2015
  13. 08/18 is_refname_available(): use dirname in first loopMichael Haggerty, May 1, 2015
  14. 09/18 ref_transaction_commit(): use a string_list for detecting duplicatesMichael Haggerty, May 1, 2015
  15. 10/18 refs: check for D/F conflicts among refs processed in a transactionMichael Haggerty, May 1, 2015
  16. 11/18 verify_refname_available(): rename functionMichael Haggerty, May 1, 2015
  17. 12/18 verify_refname_available(): report errors via a "struct strbuf *err"Michael Haggerty, May 1, 2015
  18. 13/18 lock_ref_sha1_basic(): report errors via a "struct strbuf *err"Michael Haggerty, May 1, 2015
  19. 14/18 lock_ref_sha1_basic(): improve diagnostics for D/F conflictsMichael Haggerty, May 1, 2015
  20. 15/18 rename_ref(): integrate lock_ref_sha1_basic() errors into oursMichael Haggerty, May 1, 2015
  21. 16/18 ref_transaction_commit(): provide better error messagesMichael Haggerty, May 1, 2015
  22. 17/18 ref_transaction_commit(): delete extra "the" from error messageMichael Haggerty, May 1, 2015
  23. 18/18 reflog_expire(): integrate lock_ref_sha1_basic() errors into oursMichael Haggerty, May 1, 2015
  24. Junio C HamanoMay 3, 2015
  25. Michael HaggertyMay 5, 2015

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.