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 <mhag...@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

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to