]> git.ipfire.org Git - thirdparty/git.git/blob - t/t1404-update-ref-errors.sh
t2104: style fixes
[thirdparty/git.git] / t / t1404-update-ref-errors.sh
1 #!/bin/sh
2
3 test_description='Test git update-ref error handling'
4
5 TEST_PASSES_SANITIZE_LEAK=true
6 . ./test-lib.sh
7
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
17 # value of $prefix.
18 test_update_rejected () {
19 before="$1" &&
20 pack="$2" &&
21 create="$3" &&
22 error="$4" &&
23 printf "create $prefix/%s $C\n" $before |
24 git update-ref --stdin &&
25 git for-each-ref $prefix >unchanged &&
26 if $pack
27 then
28 git pack-refs --all
29 fi &&
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
35 }
36
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 $SQ$addname$SQ: $SQ$delref$SQ exists; cannot create $SQ$addref$SQ
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
112 test_expect_success 'setup' '
113
114 git commit --allow-empty -m Initial &&
115 C=$(git rev-parse HEAD) &&
116 git commit --allow-empty -m Second &&
117 D=$(git rev-parse HEAD) &&
118 git commit --allow-empty -m Third &&
119 E=$(git rev-parse HEAD)
120 '
121
122 test_expect_success 'existing loose ref is a simple prefix of new' '
123
124 prefix=refs/1l &&
125 test_update_rejected "a c e" false "b c/x d" \
126 "$SQ$prefix/c$SQ exists; cannot create $SQ$prefix/c/x$SQ"
127
128 '
129
130 test_expect_success 'existing packed ref is a simple prefix of new' '
131
132 prefix=refs/1p &&
133 test_update_rejected "a c e" true "b c/x d" \
134 "$SQ$prefix/c$SQ exists; cannot create $SQ$prefix/c/x$SQ"
135
136 '
137
138 test_expect_success 'existing loose ref is a deeper prefix of new' '
139
140 prefix=refs/2l &&
141 test_update_rejected "a c e" false "b c/x/y d" \
142 "$SQ$prefix/c$SQ exists; cannot create $SQ$prefix/c/x/y$SQ"
143
144 '
145
146 test_expect_success 'existing packed ref is a deeper prefix of new' '
147
148 prefix=refs/2p &&
149 test_update_rejected "a c e" true "b c/x/y d" \
150 "$SQ$prefix/c$SQ exists; cannot create $SQ$prefix/c/x/y$SQ"
151
152 '
153
154 test_expect_success 'new ref is a simple prefix of existing loose' '
155
156 prefix=refs/3l &&
157 test_update_rejected "a c/x e" false "b c d" \
158 "$SQ$prefix/c/x$SQ exists; cannot create $SQ$prefix/c$SQ"
159
160 '
161
162 test_expect_success 'new ref is a simple prefix of existing packed' '
163
164 prefix=refs/3p &&
165 test_update_rejected "a c/x e" true "b c d" \
166 "$SQ$prefix/c/x$SQ exists; cannot create $SQ$prefix/c$SQ"
167
168 '
169
170 test_expect_success 'new ref is a deeper prefix of existing loose' '
171
172 prefix=refs/4l &&
173 test_update_rejected "a c/x/y e" false "b c d" \
174 "$SQ$prefix/c/x/y$SQ exists; cannot create $SQ$prefix/c$SQ"
175
176 '
177
178 test_expect_success 'new ref is a deeper prefix of existing packed' '
179
180 prefix=refs/4p &&
181 test_update_rejected "a c/x/y e" true "b c d" \
182 "$SQ$prefix/c/x/y$SQ exists; cannot create $SQ$prefix/c$SQ"
183
184 '
185
186 test_expect_success 'one new ref is a simple prefix of another' '
187
188 prefix=refs/5 &&
189 test_update_rejected "a e" false "b c c/x d" \
190 "cannot process $SQ$prefix/c$SQ and $SQ$prefix/c/x$SQ at the same time"
191
192 '
193
194 test_expect_success REFFILES 'D/F conflict prevents add long + delete short' '
195 df_test refs/df-al-ds --add-del foo/bar foo
196 '
197
198 test_expect_success REFFILES 'D/F conflict prevents add short + delete long' '
199 df_test refs/df-as-dl --add-del foo foo/bar
200 '
201
202 test_expect_success REFFILES 'D/F conflict prevents delete long + add short' '
203 df_test refs/df-dl-as --del-add foo/bar foo
204 '
205
206 test_expect_success REFFILES 'D/F conflict prevents delete short + add long' '
207 df_test refs/df-ds-al --del-add foo foo/bar
208 '
209
210 test_expect_success REFFILES 'D/F conflict prevents add long + delete short packed' '
211 df_test refs/df-al-dsp --pack --add-del foo/bar foo
212 '
213
214 test_expect_success REFFILES 'D/F conflict prevents add short + delete long packed' '
215 df_test refs/df-as-dlp --pack --add-del foo foo/bar
216 '
217
218 test_expect_success REFFILES 'D/F conflict prevents delete long packed + add short' '
219 df_test refs/df-dlp-as --pack --del-add foo/bar foo
220 '
221
222 test_expect_success REFFILES 'D/F conflict prevents delete short packed + add long' '
223 df_test refs/df-dsp-al --pack --del-add foo foo/bar
224 '
225
226 # Try some combinations involving symbolic refs...
227
228 test_expect_success REFFILES 'D/F conflict prevents indirect add long + delete short' '
229 df_test refs/df-ial-ds --sym-add --add-del foo/bar foo
230 '
231
232 test_expect_success REFFILES 'D/F conflict prevents indirect add long + indirect delete short' '
233 df_test refs/df-ial-ids --sym-add --sym-del --add-del foo/bar foo
234 '
235
236 test_expect_success REFFILES 'D/F conflict prevents indirect add short + indirect delete long' '
237 df_test refs/df-ias-idl --sym-add --sym-del --add-del foo foo/bar
238 '
239
240 test_expect_success REFFILES 'D/F conflict prevents indirect delete long + indirect add short' '
241 df_test refs/df-idl-ias --sym-add --sym-del --del-add foo/bar foo
242 '
243
244 test_expect_success REFFILES 'D/F conflict prevents indirect add long + delete short packed' '
245 df_test refs/df-ial-dsp --sym-add --pack --add-del foo/bar foo
246 '
247
248 test_expect_success REFFILES 'D/F conflict prevents indirect add long + indirect delete short packed' '
249 df_test refs/df-ial-idsp --sym-add --sym-del --pack --add-del foo/bar foo
250 '
251
252 test_expect_success REFFILES 'D/F conflict prevents add long + indirect delete short packed' '
253 df_test refs/df-al-idsp --sym-del --pack --add-del foo/bar foo
254 '
255
256 test_expect_success REFFILES 'D/F conflict prevents indirect delete long packed + indirect add short' '
257 df_test refs/df-idlp-ias --sym-add --sym-del --pack --del-add foo/bar foo
258 '
259
260 # Test various errors when reading the old values of references...
261
262 test_expect_success 'missing old value blocks update' '
263 prefix=refs/missing-update &&
264 cat >expected <<-EOF &&
265 fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ
266 EOF
267 printf "%s\n" "update $prefix/foo $E $D" |
268 test_must_fail git update-ref --stdin 2>output.err &&
269 test_cmp expected output.err
270 '
271
272 test_expect_success 'incorrect old value blocks update' '
273 prefix=refs/incorrect-update &&
274 git update-ref $prefix/foo $C &&
275 cat >expected <<-EOF &&
276 fatal: cannot lock ref $SQ$prefix/foo$SQ: is at $C but expected $D
277 EOF
278 printf "%s\n" "update $prefix/foo $E $D" |
279 test_must_fail git update-ref --stdin 2>output.err &&
280 test_cmp expected output.err
281 '
282
283 test_expect_success 'existing old value blocks create' '
284 prefix=refs/existing-create &&
285 git update-ref $prefix/foo $C &&
286 cat >expected <<-EOF &&
287 fatal: cannot lock ref $SQ$prefix/foo$SQ: reference already exists
288 EOF
289 printf "%s\n" "create $prefix/foo $E" |
290 test_must_fail git update-ref --stdin 2>output.err &&
291 test_cmp expected output.err
292 '
293
294 test_expect_success 'incorrect old value blocks delete' '
295 prefix=refs/incorrect-delete &&
296 git update-ref $prefix/foo $C &&
297 cat >expected <<-EOF &&
298 fatal: cannot lock ref $SQ$prefix/foo$SQ: is at $C but expected $D
299 EOF
300 printf "%s\n" "delete $prefix/foo $D" |
301 test_must_fail git update-ref --stdin 2>output.err &&
302 test_cmp expected output.err
303 '
304
305 test_expect_success 'missing old value blocks indirect update' '
306 prefix=refs/missing-indirect-update &&
307 git symbolic-ref $prefix/symref $prefix/foo &&
308 cat >expected <<-EOF &&
309 fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ
310 EOF
311 printf "%s\n" "update $prefix/symref $E $D" |
312 test_must_fail git update-ref --stdin 2>output.err &&
313 test_cmp expected output.err
314 '
315
316 test_expect_success 'incorrect old value blocks indirect update' '
317 prefix=refs/incorrect-indirect-update &&
318 git symbolic-ref $prefix/symref $prefix/foo &&
319 git update-ref $prefix/foo $C &&
320 cat >expected <<-EOF &&
321 fatal: cannot lock ref $SQ$prefix/symref$SQ: is at $C but expected $D
322 EOF
323 printf "%s\n" "update $prefix/symref $E $D" |
324 test_must_fail git update-ref --stdin 2>output.err &&
325 test_cmp expected output.err
326 '
327
328 test_expect_success 'existing old value blocks indirect create' '
329 prefix=refs/existing-indirect-create &&
330 git symbolic-ref $prefix/symref $prefix/foo &&
331 git update-ref $prefix/foo $C &&
332 cat >expected <<-EOF &&
333 fatal: cannot lock ref $SQ$prefix/symref$SQ: reference already exists
334 EOF
335 printf "%s\n" "create $prefix/symref $E" |
336 test_must_fail git update-ref --stdin 2>output.err &&
337 test_cmp expected output.err
338 '
339
340 test_expect_success 'incorrect old value blocks indirect delete' '
341 prefix=refs/incorrect-indirect-delete &&
342 git symbolic-ref $prefix/symref $prefix/foo &&
343 git update-ref $prefix/foo $C &&
344 cat >expected <<-EOF &&
345 fatal: cannot lock ref $SQ$prefix/symref$SQ: is at $C but expected $D
346 EOF
347 printf "%s\n" "delete $prefix/symref $D" |
348 test_must_fail git update-ref --stdin 2>output.err &&
349 test_cmp expected output.err
350 '
351
352 test_expect_success 'missing old value blocks indirect no-deref update' '
353 prefix=refs/missing-noderef-update &&
354 git symbolic-ref $prefix/symref $prefix/foo &&
355 cat >expected <<-EOF &&
356 fatal: cannot lock ref $SQ$prefix/symref$SQ: reference is missing but expected $D
357 EOF
358 printf "%s\n" "option no-deref" "update $prefix/symref $E $D" |
359 test_must_fail git update-ref --stdin 2>output.err &&
360 test_cmp expected output.err
361 '
362
363 test_expect_success 'incorrect old value blocks indirect no-deref update' '
364 prefix=refs/incorrect-noderef-update &&
365 git symbolic-ref $prefix/symref $prefix/foo &&
366 git update-ref $prefix/foo $C &&
367 cat >expected <<-EOF &&
368 fatal: cannot lock ref $SQ$prefix/symref$SQ: is at $C but expected $D
369 EOF
370 printf "%s\n" "option no-deref" "update $prefix/symref $E $D" |
371 test_must_fail git update-ref --stdin 2>output.err &&
372 test_cmp expected output.err
373 '
374
375 test_expect_success 'existing old value blocks indirect no-deref create' '
376 prefix=refs/existing-noderef-create &&
377 git symbolic-ref $prefix/symref $prefix/foo &&
378 git update-ref $prefix/foo $C &&
379 cat >expected <<-EOF &&
380 fatal: cannot lock ref $SQ$prefix/symref$SQ: reference already exists
381 EOF
382 printf "%s\n" "option no-deref" "create $prefix/symref $E" |
383 test_must_fail git update-ref --stdin 2>output.err &&
384 test_cmp expected output.err
385 '
386
387 test_expect_success 'incorrect old value blocks indirect no-deref delete' '
388 prefix=refs/incorrect-noderef-delete &&
389 git symbolic-ref $prefix/symref $prefix/foo &&
390 git update-ref $prefix/foo $C &&
391 cat >expected <<-EOF &&
392 fatal: cannot lock ref $SQ$prefix/symref$SQ: is at $C but expected $D
393 EOF
394 printf "%s\n" "option no-deref" "delete $prefix/symref $D" |
395 test_must_fail git update-ref --stdin 2>output.err &&
396 test_cmp expected output.err
397 '
398
399 test_done