lock_ref_sha1_basic(): improve diagnostics for ref D/F conflicts
If there is a failure to lock a reference that is likely caused by a D/F conflict (e.g., trying to lock "refs/foo/bar" when reference "refs/foo" already exists), invoke verify_refname_available() to try to generate a more helpful error message. That function might not detect an error. For example, some non-reference file might be blocking the deletion of an otherwise-empty directory tree, or there might be a race with another process that just deleted the offending reference. In such cases, generate the strerror-based error message like before. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
This commit is contained in:
parent
4a32b2e08b
commit
5b2d8d6f21
16
refs.c
16
refs.c
@ -2369,8 +2369,12 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
|
|||||||
ref_file = git_path("%s", orig_refname);
|
ref_file = git_path("%s", orig_refname);
|
||||||
if (remove_empty_directories(ref_file)) {
|
if (remove_empty_directories(ref_file)) {
|
||||||
last_errno = errno;
|
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;
|
goto error_return;
|
||||||
}
|
}
|
||||||
refname = resolve_ref_unsafe(orig_refname, resolve_flags,
|
refname = resolve_ref_unsafe(orig_refname, resolve_flags,
|
||||||
@ -2380,8 +2384,12 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
|
|||||||
*type_p = type;
|
*type_p = type;
|
||||||
if (!refname) {
|
if (!refname) {
|
||||||
last_errno = errno;
|
last_errno = errno;
|
||||||
strbuf_addf(err, "unable to resolve reference %s: %s",
|
if (last_errno != ENOTDIR ||
|
||||||
orig_refname, strerror(errno));
|
!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;
|
goto error_return;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -36,7 +36,7 @@ test_expect_success 'existing loose ref is a simple prefix of new' '
|
|||||||
|
|
||||||
prefix=refs/1l &&
|
prefix=refs/1l &&
|
||||||
test_update_rejected $prefix "a c e" false "b c/x d" \
|
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 &&
|
prefix=refs/2l &&
|
||||||
test_update_rejected $prefix "a c e" false "b c/x/y d" \
|
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 &&
|
prefix=refs/3l &&
|
||||||
test_update_rejected $prefix "a c/x e" false "b c d" \
|
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 &&
|
prefix=refs/4l &&
|
||||||
test_update_rejected $prefix "a c/x/y e" false "b c d" \
|
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"
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user