Merge branch 'jk/refs-df-conflict'
An ancient bug that made Git misbehave with creation/renaming of refs has been fixed. * jk/refs-df-conflict: refs_resolve_ref_unsafe: handle d/f conflicts for writes t3308: create a real ref directory/file conflict
This commit is contained in:
commit
bab02c6e63
15
refs.c
15
refs.c
@ -1435,8 +1435,21 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,
|
||||
if (refs_read_raw_ref(refs, refname,
|
||||
sha1, &sb_refname, &read_flags)) {
|
||||
*flags |= read_flags;
|
||||
if (errno != ENOENT || (resolve_flags & RESOLVE_REF_READING))
|
||||
|
||||
/* In reading mode, refs must eventually resolve */
|
||||
if (resolve_flags & RESOLVE_REF_READING)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Otherwise a missing ref is OK. But the files backend
|
||||
* may show errors besides ENOENT if there are
|
||||
* similarly-named refs.
|
||||
*/
|
||||
if (errno != ENOENT &&
|
||||
errno != EISDIR &&
|
||||
errno != ENOTDIR)
|
||||
return NULL;
|
||||
|
||||
hashclr(sha1);
|
||||
if (*flags & REF_BAD_NAME)
|
||||
*flags |= REF_ISBROKEN;
|
||||
|
@ -129,11 +129,35 @@ test_expect_success 'symbolic-ref does not create ref d/f conflicts' '
|
||||
test_must_fail git symbolic-ref refs/heads/df/conflict refs/heads/df
|
||||
'
|
||||
|
||||
test_expect_success 'symbolic-ref handles existing pointer to invalid name' '
|
||||
test_expect_success 'symbolic-ref can overwrite pointer to invalid name' '
|
||||
test_when_finished reset_to_sane &&
|
||||
head=$(git rev-parse HEAD) &&
|
||||
git symbolic-ref HEAD refs/heads/outer &&
|
||||
test_when_finished "git update-ref -d refs/heads/outer/inner" &&
|
||||
git update-ref refs/heads/outer/inner $head &&
|
||||
git symbolic-ref HEAD refs/heads/unrelated
|
||||
'
|
||||
|
||||
test_expect_success 'symbolic-ref can resolve d/f name (EISDIR)' '
|
||||
test_when_finished reset_to_sane &&
|
||||
head=$(git rev-parse HEAD) &&
|
||||
git symbolic-ref HEAD refs/heads/outer/inner &&
|
||||
test_when_finished "git update-ref -d refs/heads/outer" &&
|
||||
git update-ref refs/heads/outer $head &&
|
||||
echo refs/heads/outer/inner >expect &&
|
||||
git symbolic-ref HEAD >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'symbolic-ref can resolve d/f name (ENOTDIR)' '
|
||||
test_when_finished reset_to_sane &&
|
||||
head=$(git rev-parse HEAD) &&
|
||||
git symbolic-ref HEAD refs/heads/outer &&
|
||||
test_when_finished "git update-ref -d refs/heads/outer/inner" &&
|
||||
git update-ref refs/heads/outer/inner $head &&
|
||||
echo refs/heads/outer >expect &&
|
||||
git symbolic-ref HEAD >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_done
|
||||
|
@ -117,6 +117,16 @@ test_expect_success 'git branch -m bbb should rename checked out branch' '
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'renaming checked out branch works with d/f conflict' '
|
||||
test_when_finished "git branch -D foo/bar || git branch -D foo" &&
|
||||
test_when_finished git checkout master &&
|
||||
git checkout -b foo &&
|
||||
git branch -m foo/bar &&
|
||||
git symbolic-ref HEAD >actual &&
|
||||
echo refs/heads/foo/bar >expect &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'git branch -m o/o o should fail when o/p exists' '
|
||||
git branch o/o &&
|
||||
git branch o/p &&
|
||||
|
@ -79,7 +79,7 @@ test_expect_success 'fail to merge empty notes ref into empty notes ref (z => y)
|
||||
test_expect_success 'fail to merge into various non-notes refs' '
|
||||
test_must_fail git -c "core.notesRef=refs/notes" notes merge x &&
|
||||
test_must_fail git -c "core.notesRef=refs/notes/" notes merge x &&
|
||||
mkdir -p .git/refs/notes/dir &&
|
||||
git update-ref refs/notes/dir/foo HEAD &&
|
||||
test_must_fail git -c "core.notesRef=refs/notes/dir" notes merge x &&
|
||||
test_must_fail git -c "core.notesRef=refs/notes/dir/" notes merge x &&
|
||||
test_must_fail git -c "core.notesRef=refs/heads/master" notes merge x &&
|
||||
|
Loading…
Reference in New Issue
Block a user