summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Haggerty <mhagger@alum.mit.edu>2015-05-01 14:25:54 +0200
committerJunio C Hamano <gitster@pobox.com>2015-05-10 11:31:32 -0700
commit2ec85f20a4e069a1d535b9cedd99becbd6d52abb (patch)
tree905371150cce640f08965ecceee58d5548c6bd2d
parentb1a668a8f93be36891cf453ae7ba4db190a9e961 (diff)
downloadgit-2ec85f20a4e069a1d535b9cedd99becbd6d52abb.tar.gz
lock_ref_sha1_basic(): improve diagnostics for D/F conflicts
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>
-rw-r--r--refs.c16
-rwxr-xr-xt/t1404-update-ref-df-conflicts.sh8
2 files changed, 16 insertions, 8 deletions
diff --git a/refs.c b/refs.c
index 6f15c8c1e7..c2962604aa 100644
--- a/refs.c
+++ b/refs.c
@@ -2352,8 +2352,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,
@@ -2363,8 +2367,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 136fb48856..11b6d5ba3d 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"
'