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,
|
if (refs_read_raw_ref(refs, refname,
|
||||||
sha1, &sb_refname, &read_flags)) {
|
sha1, &sb_refname, &read_flags)) {
|
||||||
*flags |= 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;
|
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);
|
hashclr(sha1);
|
||||||
if (*flags & REF_BAD_NAME)
|
if (*flags & REF_BAD_NAME)
|
||||||
*flags |= REF_ISBROKEN;
|
*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_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) &&
|
head=$(git rev-parse HEAD) &&
|
||||||
git symbolic-ref HEAD refs/heads/outer &&
|
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 update-ref refs/heads/outer/inner $head &&
|
||||||
git symbolic-ref HEAD refs/heads/unrelated
|
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
|
test_done
|
||||||
|
@ -117,6 +117,16 @@ test_expect_success 'git branch -m bbb should rename checked out branch' '
|
|||||||
test_cmp expect actual
|
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' '
|
test_expect_success 'git branch -m o/o o should fail when o/p exists' '
|
||||||
git branch o/o &&
|
git branch o/o &&
|
||||||
git branch o/p &&
|
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_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 &&
|
||||||
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/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 &&
|
test_must_fail git -c "core.notesRef=refs/heads/master" notes merge x &&
|
||||||
|
Loading…
Reference in New Issue
Block a user