3 test_description
='Test git update-ref error handling'
5 TEST_PASSES_SANITIZE_LEAK
=true
8 # Create some references, perhaps run pack-refs --all, then try to
9 # create some more references. Ensure that the second creation fails
10 # with the correct error message.
11 # Usage: test_update_rejected <before> <pack> <create> <error>
12 # <before> is a ws-separated list of refs to create before the test
13 # <pack> (true or false) tells whether to pack the refs before the test
14 # <create> is a list of variables to attempt creating
15 # <error> is a string to look for in the stderr of update-ref.
16 # All references are created in the namespace specified by the current
18 test_update_rejected
() {
23 printf "create $prefix/%s $C\n" $before |
24 git update-ref
--stdin &&
25 git for-each-ref
$prefix >unchanged
&&
30 printf "create $prefix/%s $C\n" $create >input
&&
31 test_must_fail git update-ref
--stdin <input
2>output.err
&&
32 test_grep
-F "$error" output.err
&&
33 git for-each-ref
$prefix >actual
&&
34 test_cmp unchanged actual
37 # Test adding and deleting D/F-conflicting references in a single
41 pack
=: symadd
=false symdel
=false add_del
=false addref
= delref
=
47 pack
="git pack-refs --all"
51 # Perform the add via a symbolic reference
56 # Perform the del via a symbolic reference
61 # Delete first reference then add second
68 # Add first reference then delete second
75 echo 1>&2 "Extra args to df_test: $*"
80 git update-ref
"$delref" $C &&
83 addname
="$prefix/s/symadd" &&
84 git symbolic-ref
"$addname" "$addref"
90 delname
="$prefix/s/symdel" &&
91 git symbolic-ref
"$delname" "$delref"
98 printf "%s\n" "create $addname $D" "delete $delname"
100 printf "%s\n" "delete $delname" "create $addname $D"
102 test_must_fail git update-ref
--stdin <commands
2>output.err
&&
103 grep -E "fatal:( cannot lock ref '$addname':)? '$delref' exists; cannot create '$addref'" output.err
&&
104 printf "%s\n" "$C $delref" >expected-refs
&&
105 git for-each-ref
--format="%(objectname) %(refname)" $prefix/r
>actual-refs
&&
106 test_cmp expected-refs actual-refs
109 test_expect_success
'setup' - <<\EOT
111 git commit
--allow-empty -m Initial
&&
112 C
=$
(git rev-parse HEAD
) &&
113 git commit
--allow-empty -m Second
&&
114 D
=$
(git rev-parse HEAD
) &&
115 git commit
--allow-empty -m Third
&&
116 E
=$
(git rev-parse HEAD
)
119 test_expect_success
'existing loose ref is a simple prefix of new' - <<\EOT
122 test_update_rejected
"a c e" false
"b c/x d" \
123 "'$prefix/c' exists; cannot create '$prefix/c/x'"
127 test_expect_success
'existing packed ref is a simple prefix of new' - <<\EOT
130 test_update_rejected
"a c e" true
"b c/x d" \
131 "'$prefix/c' exists; cannot create '$prefix/c/x'"
135 test_expect_success
'existing loose ref is a deeper prefix of new' - <<\EOT
138 test_update_rejected
"a c e" false
"b c/x/y d" \
139 "'$prefix/c' exists; cannot create '$prefix/c/x/y'"
143 test_expect_success
'existing packed ref is a deeper prefix of new' - <<\EOT
146 test_update_rejected
"a c e" true
"b c/x/y d" \
147 "'$prefix/c' exists; cannot create '$prefix/c/x/y'"
151 test_expect_success
'new ref is a simple prefix of existing loose' - <<\EOT
154 test_update_rejected
"a c/x e" false
"b c d" \
155 "'$prefix/c/x' exists; cannot create '$prefix/c'"
159 test_expect_success
'new ref is a simple prefix of existing packed' - <<\EOT
162 test_update_rejected
"a c/x e" true
"b c d" \
163 "'$prefix/c/x' exists; cannot create '$prefix/c'"
167 test_expect_success
'new ref is a deeper prefix of existing loose' - <<\EOT
170 test_update_rejected
"a c/x/y e" false
"b c d" \
171 "'$prefix/c/x/y' exists; cannot create '$prefix/c'"
175 test_expect_success
'new ref is a deeper prefix of existing packed' - <<\EOT
178 test_update_rejected
"a c/x/y e" true
"b c d" \
179 "'$prefix/c/x/y' exists; cannot create '$prefix/c'"
183 test_expect_success
'one new ref is a simple prefix of another' - <<\EOT
186 test_update_rejected
"a e" false
"b c c/x d" \
187 "cannot process '$prefix/c' and '$prefix/c/x' at the same time"
191 test_expect_success
'D/F conflict prevents add long + delete short' - <<\EOT
192 df_test refs
/df-al-ds
--add-del foo
/bar foo
195 test_expect_success
'D/F conflict prevents add short + delete long' - <<\EOT
196 df_test refs
/df-as-dl
--add-del foo foo
/bar
199 test_expect_success
'D/F conflict prevents delete long + add short' - <<\EOT
200 df_test refs
/df-dl-as
--del-add foo
/bar foo
203 test_expect_success
'D/F conflict prevents delete short + add long' - <<\EOT
204 df_test refs
/df-ds-al
--del-add foo foo
/bar
207 test_expect_success
'D/F conflict prevents add long + delete short packed' - <<\EOT
208 df_test refs
/df-al-dsp
--pack --add-del foo
/bar foo
211 test_expect_success
'D/F conflict prevents add short + delete long packed' - <<\EOT
212 df_test refs
/df-as-dlp
--pack --add-del foo foo
/bar
215 test_expect_success
'D/F conflict prevents delete long packed + add short' - <<\EOT
216 df_test refs
/df-dlp-as
--pack --del-add foo
/bar foo
219 test_expect_success
'D/F conflict prevents delete short packed + add long' - <<\EOT
220 df_test refs
/df-dsp-al
--pack --del-add foo foo
/bar
223 # Try some combinations involving symbolic refs...
225 test_expect_success
'D/F conflict prevents indirect add long + delete short' - <<\EOT
226 df_test refs
/df-ial-ds
--sym-add --add-del foo
/bar foo
229 test_expect_success
'D/F conflict prevents indirect add long + indirect delete short' - <<\EOT
230 df_test refs
/df-ial-ids
--sym-add --sym-del --add-del foo
/bar foo
233 test_expect_success
'D/F conflict prevents indirect add short + indirect delete long' - <<\EOT
234 df_test refs
/df-ias-idl
--sym-add --sym-del --add-del foo foo
/bar
237 test_expect_success
'D/F conflict prevents indirect delete long + indirect add short' - <<\EOT
238 df_test refs
/df-idl-ias
--sym-add --sym-del --del-add foo
/bar foo
241 test_expect_success
'D/F conflict prevents indirect add long + delete short packed' - <<\EOT
242 df_test refs
/df-ial-dsp
--sym-add --pack --add-del foo
/bar foo
245 test_expect_success
'D/F conflict prevents indirect add long + indirect delete short packed' - <<\EOT
246 df_test refs
/df-ial-idsp
--sym-add --sym-del --pack --add-del foo
/bar foo
249 test_expect_success
'D/F conflict prevents add long + indirect delete short packed' - <<\EOT
250 df_test refs
/df-al-idsp
--sym-del --pack --add-del foo
/bar foo
253 test_expect_success
'D/F conflict prevents indirect delete long packed + indirect add short' - <<\EOT
254 df_test refs
/df-idlp-ias
--sym-add --sym-del --pack --del-add foo
/bar foo
257 # Test various errors when reading the old values of references...
259 test_expect_success
'missing old value blocks update' - <<\EOT
260 prefix
=refs
/missing-update
&&
261 cat >expected
<<-EOF &&
262 fatal: cannot lock ref '$prefix/foo': unable to resolve reference '$prefix/foo'
264 printf "%s\n" "update $prefix/foo $E $D" |
265 test_must_fail git update-ref
--stdin 2>output.err
&&
266 test_cmp expected output.err
269 test_expect_success
'incorrect old value blocks update' - <<\EOT
270 prefix
=refs
/incorrect-update
&&
271 git update-ref
$prefix/foo
$C &&
272 cat >expected
<<-EOF &&
273 fatal: cannot lock ref '$prefix/foo': is at $C but expected $D
275 printf "%s\n" "update $prefix/foo $E $D" |
276 test_must_fail git update-ref
--stdin 2>output.err
&&
277 test_cmp expected output.err
280 test_expect_success
'existing old value blocks create' - <<\EOT
281 prefix
=refs
/existing-create
&&
282 git update-ref
$prefix/foo
$C &&
283 cat >expected
<<-EOF &&
284 fatal: cannot lock ref '$prefix/foo': reference already exists
286 printf "%s\n" "create $prefix/foo $E" |
287 test_must_fail git update-ref
--stdin 2>output.err
&&
288 test_cmp expected output.err
291 test_expect_success
'incorrect old value blocks delete' - <<\EOT
292 prefix
=refs
/incorrect-delete
&&
293 git update-ref
$prefix/foo
$C &&
294 cat >expected
<<-EOF &&
295 fatal: cannot lock ref '$prefix/foo': is at $C but expected $D
297 printf "%s\n" "delete $prefix/foo $D" |
298 test_must_fail git update-ref
--stdin 2>output.err
&&
299 test_cmp expected output.err
302 test_expect_success
'missing old value blocks indirect update' - <<\EOT
303 prefix
=refs
/missing-indirect-update
&&
304 git symbolic-ref
$prefix/symref
$prefix/foo
&&
305 cat >expected
<<-EOF &&
306 fatal: cannot lock ref '$prefix/symref': unable to resolve reference '$prefix/foo'
308 printf "%s\n" "update $prefix/symref $E $D" |
309 test_must_fail git update-ref
--stdin 2>output.err
&&
310 test_cmp expected output.err
313 test_expect_success
'incorrect old value blocks indirect update' - <<\EOT
314 prefix
=refs
/incorrect-indirect-update
&&
315 git symbolic-ref
$prefix/symref
$prefix/foo
&&
316 git update-ref
$prefix/foo
$C &&
317 cat >expected
<<-EOF &&
318 fatal: cannot lock ref '$prefix/symref': is at $C but expected $D
320 printf "%s\n" "update $prefix/symref $E $D" |
321 test_must_fail git update-ref
--stdin 2>output.err
&&
322 test_cmp expected output.err
325 test_expect_success
'existing old value blocks indirect create' - <<\EOT
326 prefix
=refs
/existing-indirect-create
&&
327 git symbolic-ref
$prefix/symref
$prefix/foo
&&
328 git update-ref
$prefix/foo
$C &&
329 cat >expected
<<-EOF &&
330 fatal: cannot lock ref '$prefix/symref': reference already exists
332 printf "%s\n" "create $prefix/symref $E" |
333 test_must_fail git update-ref
--stdin 2>output.err
&&
334 test_cmp expected output.err
337 test_expect_success
'incorrect old value blocks indirect delete' - <<\EOT
338 prefix
=refs
/incorrect-indirect-delete
&&
339 git symbolic-ref
$prefix/symref
$prefix/foo
&&
340 git update-ref
$prefix/foo
$C &&
341 cat >expected
<<-EOF &&
342 fatal: cannot lock ref '$prefix/symref': is at $C but expected $D
344 printf "%s\n" "delete $prefix/symref $D" |
345 test_must_fail git update-ref
--stdin 2>output.err
&&
346 test_cmp expected output.err
349 test_expect_success
'missing old value blocks indirect no-deref update' - <<\EOT
350 prefix
=refs
/missing-noderef-update
&&
351 git symbolic-ref
$prefix/symref
$prefix/foo
&&
352 cat >expected
<<-EOF &&
353 fatal: cannot lock ref '$prefix/symref': reference is missing but expected $D
355 printf "%s\n" "option no-deref" "update $prefix/symref $E $D" |
356 test_must_fail git update-ref
--stdin 2>output.err
&&
357 test_cmp expected output.err
360 test_expect_success
'incorrect old value blocks indirect no-deref update' - <<\EOT
361 prefix
=refs
/incorrect-noderef-update
&&
362 git symbolic-ref
$prefix/symref
$prefix/foo
&&
363 git update-ref
$prefix/foo
$C &&
364 cat >expected
<<-EOF &&
365 fatal: cannot lock ref '$prefix/symref': is at $C but expected $D
367 printf "%s\n" "option no-deref" "update $prefix/symref $E $D" |
368 test_must_fail git update-ref
--stdin 2>output.err
&&
369 test_cmp expected output.err
372 test_expect_success
'existing old value blocks indirect no-deref create' - <<\EOT
373 prefix
=refs
/existing-noderef-create
&&
374 git symbolic-ref
$prefix/symref
$prefix/foo
&&
375 git update-ref
$prefix/foo
$C &&
376 cat >expected
<<-EOF &&
377 fatal: cannot lock ref '$prefix/symref': reference already exists
379 printf "%s\n" "option no-deref" "create $prefix/symref $E" |
380 test_must_fail git update-ref
--stdin 2>output.err
&&
381 test_cmp expected output.err
384 test_expect_success
'incorrect old value blocks indirect no-deref delete' - <<\EOT
385 prefix
=refs
/incorrect-noderef-delete
&&
386 git symbolic-ref
$prefix/symref
$prefix/foo
&&
387 git update-ref
$prefix/foo
$C &&
388 cat >expected
<<-EOF &&
389 fatal: cannot lock ref '$prefix/symref': is at $C but expected $D
391 printf "%s\n" "option no-deref" "delete $prefix/symref $D" |
392 test_must_fail git update-ref
--stdin 2>output.err
&&
393 test_cmp expected output.err