Skip to content

Commit bab02c6

Browse files
committed
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
2 parents 3d2a6dc + a1c1d81 commit bab02c6

File tree

4 files changed

+50
-3
lines changed

4 files changed

+50
-3
lines changed

refs.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1435,8 +1435,21 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,
14351435
if (refs_read_raw_ref(refs, refname,
14361436
sha1, &sb_refname, &read_flags)) {
14371437
*flags |= read_flags;
1438-
if (errno != ENOENT || (resolve_flags & RESOLVE_REF_READING))
1438+
1439+
/* In reading mode, refs must eventually resolve */
1440+
if (resolve_flags & RESOLVE_REF_READING)
1441+
return NULL;
1442+
1443+
/*
1444+
* Otherwise a missing ref is OK. But the files backend
1445+
* may show errors besides ENOENT if there are
1446+
* similarly-named refs.
1447+
*/
1448+
if (errno != ENOENT &&
1449+
errno != EISDIR &&
1450+
errno != ENOTDIR)
14391451
return NULL;
1452+
14401453
hashclr(sha1);
14411454
if (*flags & REF_BAD_NAME)
14421455
*flags |= REF_ISBROKEN;

t/t1401-symbolic-ref.sh

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,35 @@ test_expect_success 'symbolic-ref does not create ref d/f conflicts' '
129129
test_must_fail git symbolic-ref refs/heads/df/conflict refs/heads/df
130130
'
131131

132-
test_expect_success 'symbolic-ref handles existing pointer to invalid name' '
132+
test_expect_success 'symbolic-ref can overwrite pointer to invalid name' '
133+
test_when_finished reset_to_sane &&
133134
head=$(git rev-parse HEAD) &&
134135
git symbolic-ref HEAD refs/heads/outer &&
136+
test_when_finished "git update-ref -d refs/heads/outer/inner" &&
135137
git update-ref refs/heads/outer/inner $head &&
136138
git symbolic-ref HEAD refs/heads/unrelated
137139
'
138140

141+
test_expect_success 'symbolic-ref can resolve d/f name (EISDIR)' '
142+
test_when_finished reset_to_sane &&
143+
head=$(git rev-parse HEAD) &&
144+
git symbolic-ref HEAD refs/heads/outer/inner &&
145+
test_when_finished "git update-ref -d refs/heads/outer" &&
146+
git update-ref refs/heads/outer $head &&
147+
echo refs/heads/outer/inner >expect &&
148+
git symbolic-ref HEAD >actual &&
149+
test_cmp expect actual
150+
'
151+
152+
test_expect_success 'symbolic-ref can resolve d/f name (ENOTDIR)' '
153+
test_when_finished reset_to_sane &&
154+
head=$(git rev-parse HEAD) &&
155+
git symbolic-ref HEAD refs/heads/outer &&
156+
test_when_finished "git update-ref -d refs/heads/outer/inner" &&
157+
git update-ref refs/heads/outer/inner $head &&
158+
echo refs/heads/outer >expect &&
159+
git symbolic-ref HEAD >actual &&
160+
test_cmp expect actual
161+
'
162+
139163
test_done

t/t3200-branch.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,16 @@ test_expect_success 'git branch -m bbb should rename checked out branch' '
117117
test_cmp expect actual
118118
'
119119

120+
test_expect_success 'renaming checked out branch works with d/f conflict' '
121+
test_when_finished "git branch -D foo/bar || git branch -D foo" &&
122+
test_when_finished git checkout master &&
123+
git checkout -b foo &&
124+
git branch -m foo/bar &&
125+
git symbolic-ref HEAD >actual &&
126+
echo refs/heads/foo/bar >expect &&
127+
test_cmp expect actual
128+
'
129+
120130
test_expect_success 'git branch -m o/o o should fail when o/p exists' '
121131
git branch o/o &&
122132
git branch o/p &&

t/t3308-notes-merge.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ test_expect_success 'fail to merge empty notes ref into empty notes ref (z => y)
7979
test_expect_success 'fail to merge into various non-notes refs' '
8080
test_must_fail git -c "core.notesRef=refs/notes" notes merge x &&
8181
test_must_fail git -c "core.notesRef=refs/notes/" notes merge x &&
82-
mkdir -p .git/refs/notes/dir &&
82+
git update-ref refs/notes/dir/foo HEAD &&
8383
test_must_fail git -c "core.notesRef=refs/notes/dir" notes merge x &&
8484
test_must_fail git -c "core.notesRef=refs/notes/dir/" notes merge x &&
8585
test_must_fail git -c "core.notesRef=refs/heads/master" notes merge x &&

0 commit comments

Comments
 (0)