@@ -34,6 +34,81 @@ test_update_rejected () {
3434
3535Q=" '"
3636
37+ # Test adding and deleting D/F-conflicting references in a single
38+ # transaction.
39+ df_test () {
40+ prefix=" $1 "
41+ pack=: symadd=false symdel=false add_del=false addref= delref=
42+ shift
43+ while test $# -gt 0
44+ do
45+ case " $1 " in
46+ --pack)
47+ pack=" git pack-refs --all"
48+ shift
49+ ;;
50+ --sym-add)
51+ # Perform the add via a symbolic reference
52+ symadd=true
53+ shift
54+ ;;
55+ --sym-del)
56+ # Perform the del via a symbolic reference
57+ symdel=true
58+ shift
59+ ;;
60+ --del-add)
61+ # Delete first reference then add second
62+ add_del=false
63+ delref=" $prefix /r/$2 "
64+ addref=" $prefix /r/$3 "
65+ shift 3
66+ ;;
67+ --add-del)
68+ # Add first reference then delete second
69+ add_del=true
70+ addref=" $prefix /r/$2 "
71+ delref=" $prefix /r/$3 "
72+ shift 3
73+ ;;
74+ * )
75+ echo 1>&2 " Extra args to df_test: $* "
76+ return 1
77+ ;;
78+ esac
79+ done
80+ git update-ref " $delref " $C &&
81+ if $symadd
82+ then
83+ addname=" $prefix /s/symadd" &&
84+ git symbolic-ref " $addname " " $addref "
85+ else
86+ addname=" $addref "
87+ fi &&
88+ if $symdel
89+ then
90+ delname=" $prefix /s/symdel" &&
91+ git symbolic-ref " $delname " " $delref "
92+ else
93+ delname=" $delref "
94+ fi &&
95+ cat > expected-err << -EOF &&
96+ fatal: cannot lock ref $Q$addname$Q : $Q$delref$Q exists; cannot create $Q$addref$Q
97+ EOF
98+ $pack &&
99+ if $add_del
100+ then
101+ printf " %s\n" " create $addname $D " " delete $delname "
102+ else
103+ printf " %s\n" " delete $delname " " create $addname $D "
104+ fi > commands &&
105+ test_must_fail git update-ref --stdin < commands 2> output.err &&
106+ test_cmp expected-err output.err &&
107+ printf " %s\n" " $C $delref " > expected-refs &&
108+ git for-each-ref --format=" %(objectname) %(refname)" $prefix /r > actual-refs &&
109+ test_cmp expected-refs actual-refs
110+ }
111+
37112test_expect_success ' setup' '
38113
39114 git commit --allow-empty -m Initial &&
@@ -188,6 +263,72 @@ test_expect_success 'empty directory should not fool 1-arg delete' '
188263 git update-ref --stdin
189264'
190265
266+ test_expect_success ' D/F conflict prevents add long + delete short' '
267+ df_test refs/df-al-ds --add-del foo/bar foo
268+ '
269+
270+ test_expect_success ' D/F conflict prevents add short + delete long' '
271+ df_test refs/df-as-dl --add-del foo foo/bar
272+ '
273+
274+ test_expect_failure ' D/F conflict prevents delete long + add short' '
275+ df_test refs/df-dl-as --del-add foo/bar foo
276+ '
277+
278+ test_expect_failure ' D/F conflict prevents delete short + add long' '
279+ df_test refs/df-ds-al --del-add foo foo/bar
280+ '
281+
282+ test_expect_success ' D/F conflict prevents add long + delete short packed' '
283+ df_test refs/df-al-dsp --pack --add-del foo/bar foo
284+ '
285+
286+ test_expect_success ' D/F conflict prevents add short + delete long packed' '
287+ df_test refs/df-as-dlp --pack --add-del foo foo/bar
288+ '
289+
290+ test_expect_failure ' D/F conflict prevents delete long packed + add short' '
291+ df_test refs/df-dlp-as --pack --del-add foo/bar foo
292+ '
293+
294+ test_expect_failure ' D/F conflict prevents delete short packed + add long' '
295+ df_test refs/df-dsp-al --pack --del-add foo foo/bar
296+ '
297+
298+ # Try some combinations involving symbolic refs...
299+
300+ test_expect_failure ' D/F conflict prevents indirect add long + delete short' '
301+ df_test refs/df-ial-ds --sym-add --add-del foo/bar foo
302+ '
303+
304+ test_expect_success ' D/F conflict prevents indirect add long + indirect delete short' '
305+ df_test refs/df-ial-ids --sym-add --sym-del --add-del foo/bar foo
306+ '
307+
308+ test_expect_success ' D/F conflict prevents indirect add short + indirect delete long' '
309+ df_test refs/df-ias-idl --sym-add --sym-del --add-del foo foo/bar
310+ '
311+
312+ test_expect_failure ' D/F conflict prevents indirect delete long + indirect add short' '
313+ df_test refs/df-idl-ias --sym-add --sym-del --del-add foo/bar foo
314+ '
315+
316+ test_expect_failure ' D/F conflict prevents indirect add long + delete short packed' '
317+ df_test refs/df-ial-dsp --sym-add --pack --add-del foo/bar foo
318+ '
319+
320+ test_expect_success ' D/F conflict prevents indirect add long + indirect delete short packed' '
321+ df_test refs/df-ial-idsp --sym-add --sym-del --pack --add-del foo/bar foo
322+ '
323+
324+ test_expect_success ' D/F conflict prevents add long + indirect delete short packed' '
325+ df_test refs/df-al-idsp --sym-del --pack --add-del foo/bar foo
326+ '
327+
328+ test_expect_failure ' D/F conflict prevents indirect delete long packed + indirect add short' '
329+ df_test refs/df-idlp-ias --sym-add --sym-del --pack --del-add foo/bar foo
330+ '
331+
191332# Test various errors when reading the old values of references...
192333
193334test_expect_success ' missing old value blocks update' '
0 commit comments