3 test_description='Test git update-ref error handling'
6 # Create some references, perhaps run pack-refs --all, then try to
7 # create some more references. Ensure that the second creation fails
8 # with the correct error message.
9 # Usage: test_update_rejected <before> <pack> <create> <error>
10 # <before> is a ws-separated list of refs to create before the test
11 # <pack> (true or false) tells whether to pack the refs before the test
12 # <create> is a list of variables to attempt creating
13 # <error> is a string to look for in the stderr of update-ref.
14 # All references are created in the namespace specified by the current
16 test_update_rejected () {
21 printf "create $prefix/%s $C\n" $before |
22 git update-ref --stdin &&
23 git for-each-ref $prefix >unchanged &&
28 printf "create $prefix/%s $C\n" $create >input &&
29 test_must_fail git update-ref --stdin <input 2>output.err &&
30 grep -F "$error" output.err &&
31 git for-each-ref $prefix >actual &&
32 test_cmp unchanged actual
37 test_expect_success 'setup' '
39 git commit --allow-empty -m Initial &&
40 C=$(git rev-parse HEAD) &&
41 git commit --allow-empty -m Second &&
42 D=$(git rev-parse HEAD) &&
43 git commit --allow-empty -m Third &&
44 E=$(git rev-parse HEAD)
47 test_expect_success 'existing loose ref is a simple prefix of new' '
50 test_update_rejected "a c e" false "b c/x d" \
51 "$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x$Q"
55 test_expect_success 'existing packed ref is a simple prefix of new' '
58 test_update_rejected "a c e" true "b c/x d" \
59 "$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x$Q"
63 test_expect_success 'existing loose ref is a deeper prefix of new' '
66 test_update_rejected "a c e" false "b c/x/y d" \
67 "$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x/y$Q"
71 test_expect_success 'existing packed ref is a deeper prefix of new' '
74 test_update_rejected "a c e" true "b c/x/y d" \
75 "$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x/y$Q"
79 test_expect_success 'new ref is a simple prefix of existing loose' '
82 test_update_rejected "a c/x e" false "b c d" \
83 "$Q$prefix/c/x$Q exists; cannot create $Q$prefix/c$Q"
87 test_expect_success 'new ref is a simple prefix of existing packed' '
90 test_update_rejected "a c/x e" true "b c d" \
91 "$Q$prefix/c/x$Q exists; cannot create $Q$prefix/c$Q"
95 test_expect_success 'new ref is a deeper prefix of existing loose' '
98 test_update_rejected "a c/x/y e" false "b c d" \
99 "$Q$prefix/c/x/y$Q exists; cannot create $Q$prefix/c$Q"
103 test_expect_success 'new ref is a deeper prefix of existing packed' '
106 test_update_rejected "a c/x/y e" true "b c d" \
107 "$Q$prefix/c/x/y$Q exists; cannot create $Q$prefix/c$Q"
111 test_expect_success 'one new ref is a simple prefix of another' '
114 test_update_rejected "a e" false "b c c/x d" \
115 "cannot process $Q$prefix/c$Q and $Q$prefix/c/x$Q at the same time"
119 test_expect_success 'empty directory should not fool rev-parse' '
120 prefix=refs/e-rev-parse &&
121 git update-ref $prefix/foo $C &&
122 git pack-refs --all &&
123 mkdir -p .git/$prefix/foo/bar/baz &&
124 echo "$C" >expected &&
125 git rev-parse $prefix/foo >actual &&
126 test_cmp expected actual
129 test_expect_success 'empty directory should not fool for-each-ref' '
130 prefix=refs/e-for-each-ref &&
131 git update-ref $prefix/foo $C &&
132 git for-each-ref $prefix >expected &&
133 git pack-refs --all &&
134 mkdir -p .git/$prefix/foo/bar/baz &&
135 git for-each-ref $prefix >actual &&
136 test_cmp expected actual
139 test_expect_success 'empty directory should not fool create' '
140 prefix=refs/e-create &&
141 mkdir -p .git/$prefix/foo/bar/baz &&
142 printf "create %s $C\n" $prefix/foo |
143 git update-ref --stdin
146 test_expect_success 'empty directory should not fool verify' '
147 prefix=refs/e-verify &&
148 git update-ref $prefix/foo $C &&
149 git pack-refs --all &&
150 mkdir -p .git/$prefix/foo/bar/baz &&
151 printf "verify %s $C\n" $prefix/foo |
152 git update-ref --stdin
155 test_expect_success 'empty directory should not fool 1-arg update' '
156 prefix=refs/e-update-1 &&
157 git update-ref $prefix/foo $C &&
158 git pack-refs --all &&
159 mkdir -p .git/$prefix/foo/bar/baz &&
160 printf "update %s $D\n" $prefix/foo |
161 git update-ref --stdin
164 test_expect_success 'empty directory should not fool 2-arg update' '
165 prefix=refs/e-update-2 &&
166 git update-ref $prefix/foo $C &&
167 git pack-refs --all &&
168 mkdir -p .git/$prefix/foo/bar/baz &&
169 printf "update %s $D $C\n" $prefix/foo |
170 git update-ref --stdin
173 test_expect_success 'empty directory should not fool 0-arg delete' '
174 prefix=refs/e-delete-0 &&
175 git update-ref $prefix/foo $C &&
176 git pack-refs --all &&
177 mkdir -p .git/$prefix/foo/bar/baz &&
178 printf "delete %s\n" $prefix/foo |
179 git update-ref --stdin
182 test_expect_success 'empty directory should not fool 1-arg delete' '
183 prefix=refs/e-delete-1 &&
184 git update-ref $prefix/foo $C &&
185 git pack-refs --all &&
186 mkdir -p .git/$prefix/foo/bar/baz &&
187 printf "delete %s $C\n" $prefix/foo |
188 git update-ref --stdin
191 # Test various errors when reading the old values of references...
193 test_expect_success 'missing old value blocks update' '
194 prefix=refs/missing-update &&
195 cat >expected <<-EOF &&
196 fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q
198 printf "%s\n" "update $prefix/foo $E $D" |
199 test_must_fail git update-ref --stdin 2>output.err &&
200 test_cmp expected output.err
203 test_expect_success 'incorrect old value blocks update' '
204 prefix=refs/incorrect-update &&
205 git update-ref $prefix/foo $C &&
206 cat >expected <<-EOF &&
207 fatal: cannot lock ref $Q$prefix/foo$Q: is at $C but expected $D
209 printf "%s\n" "update $prefix/foo $E $D" |
210 test_must_fail git update-ref --stdin 2>output.err &&
211 test_cmp expected output.err
214 test_expect_success 'existing old value blocks create' '
215 prefix=refs/existing-create &&
216 git update-ref $prefix/foo $C &&
217 cat >expected <<-EOF &&
218 fatal: cannot lock ref $Q$prefix/foo$Q: reference already exists
220 printf "%s\n" "create $prefix/foo $E" |
221 test_must_fail git update-ref --stdin 2>output.err &&
222 test_cmp expected output.err
225 test_expect_success 'incorrect old value blocks delete' '
226 prefix=refs/incorrect-delete &&
227 git update-ref $prefix/foo $C &&
228 cat >expected <<-EOF &&
229 fatal: cannot lock ref $Q$prefix/foo$Q: is at $C but expected $D
231 printf "%s\n" "delete $prefix/foo $D" |
232 test_must_fail git update-ref --stdin 2>output.err &&
233 test_cmp expected output.err
236 test_expect_success 'missing old value blocks indirect update' '
237 prefix=refs/missing-indirect-update &&
238 git symbolic-ref $prefix/symref $prefix/foo &&
239 cat >expected <<-EOF &&
240 fatal: cannot lock ref $Q$prefix/symref$Q: unable to resolve reference $Q$prefix/foo$Q
242 printf "%s\n" "update $prefix/symref $E $D" |
243 test_must_fail git update-ref --stdin 2>output.err &&
244 test_cmp expected output.err
247 test_expect_success 'incorrect old value blocks indirect update' '
248 prefix=refs/incorrect-indirect-update &&
249 git symbolic-ref $prefix/symref $prefix/foo &&
250 git update-ref $prefix/foo $C &&
251 cat >expected <<-EOF &&
252 fatal: cannot lock ref $Q$prefix/symref$Q: is at $C but expected $D
254 printf "%s\n" "update $prefix/symref $E $D" |
255 test_must_fail git update-ref --stdin 2>output.err &&
256 test_cmp expected output.err
259 test_expect_success 'existing old value blocks indirect create' '
260 prefix=refs/existing-indirect-create &&
261 git symbolic-ref $prefix/symref $prefix/foo &&
262 git update-ref $prefix/foo $C &&
263 cat >expected <<-EOF &&
264 fatal: cannot lock ref $Q$prefix/symref$Q: reference already exists
266 printf "%s\n" "create $prefix/symref $E" |
267 test_must_fail git update-ref --stdin 2>output.err &&
268 test_cmp expected output.err
271 test_expect_success 'incorrect old value blocks indirect delete' '
272 prefix=refs/incorrect-indirect-delete &&
273 git symbolic-ref $prefix/symref $prefix/foo &&
274 git update-ref $prefix/foo $C &&
275 cat >expected <<-EOF &&
276 fatal: cannot lock ref $Q$prefix/symref$Q: is at $C but expected $D
278 printf "%s\n" "delete $prefix/symref $D" |
279 test_must_fail git update-ref --stdin 2>output.err &&
280 test_cmp expected output.err
283 test_expect_success 'missing old value blocks indirect no-deref update' '
284 prefix=refs/missing-noderef-update &&
285 git symbolic-ref $prefix/symref $prefix/foo &&
286 cat >expected <<-EOF &&
287 fatal: cannot lock ref $Q$prefix/symref$Q: reference is missing but expected $D
289 printf "%s\n" "option no-deref" "update $prefix/symref $E $D" |
290 test_must_fail git update-ref --stdin 2>output.err &&
291 test_cmp expected output.err
294 test_expect_success 'incorrect old value blocks indirect no-deref update' '
295 prefix=refs/incorrect-noderef-update &&
296 git symbolic-ref $prefix/symref $prefix/foo &&
297 git update-ref $prefix/foo $C &&
298 cat >expected <<-EOF &&
299 fatal: cannot lock ref $Q$prefix/symref$Q: is at $C but expected $D
301 printf "%s\n" "option no-deref" "update $prefix/symref $E $D" |
302 test_must_fail git update-ref --stdin 2>output.err &&
303 test_cmp expected output.err
306 test_expect_success 'existing old value blocks indirect no-deref create' '
307 prefix=refs/existing-noderef-create &&
308 git symbolic-ref $prefix/symref $prefix/foo &&
309 git update-ref $prefix/foo $C &&
310 cat >expected <<-EOF &&
311 fatal: cannot lock ref $Q$prefix/symref$Q: reference already exists
313 printf "%s\n" "option no-deref" "create $prefix/symref $E" |
314 test_must_fail git update-ref --stdin 2>output.err &&
315 test_cmp expected output.err
318 test_expect_success 'incorrect old value blocks indirect no-deref delete' '
319 prefix=refs/incorrect-noderef-delete &&
320 git symbolic-ref $prefix/symref $prefix/foo &&
321 git update-ref $prefix/foo $C &&
322 cat >expected <<-EOF &&
323 fatal: cannot lock ref $Q$prefix/symref$Q: is at $C but expected $D
325 printf "%s\n" "option no-deref" "delete $prefix/symref $D" |
326 test_must_fail git update-ref --stdin 2>output.err &&
327 test_cmp expected output.err
330 test_expect_success 'non-empty directory blocks create' '
331 prefix=refs/ne-create &&
332 mkdir -p .git/$prefix/foo/bar &&
333 : >.git/$prefix/foo/bar/baz.lock &&
334 test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" &&
335 cat >expected <<-EOF &&
336 fatal: cannot lock ref $Q$prefix/foo$Q: there is a non-empty directory $Q.git/$prefix/foo$Q blocking reference $Q$prefix/foo$Q
338 printf "%s\n" "update $prefix/foo $C" |
339 test_must_fail git update-ref --stdin 2>output.err &&
340 test_cmp expected output.err &&
341 cat >expected <<-EOF &&
342 fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q
344 printf "%s\n" "update $prefix/foo $D $C" |
345 test_must_fail git update-ref --stdin 2>output.err &&
346 test_cmp expected output.err
349 test_expect_success 'broken reference blocks create' '
350 prefix=refs/broken-create &&
351 mkdir -p .git/$prefix &&
352 echo "gobbledigook" >.git/$prefix/foo &&
353 test_when_finished "rm -f .git/$prefix/foo" &&
354 cat >expected <<-EOF &&
355 fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
357 printf "%s\n" "update $prefix/foo $C" |
358 test_must_fail git update-ref --stdin 2>output.err &&
359 test_cmp expected output.err &&
360 cat >expected <<-EOF &&
361 fatal: cannot lock ref $Q$prefix/foo$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
363 printf "%s\n" "update $prefix/foo $D $C" |
364 test_must_fail git update-ref --stdin 2>output.err &&
365 test_cmp expected output.err
368 test_expect_success 'non-empty directory blocks indirect create' '
369 prefix=refs/ne-indirect-create &&
370 git symbolic-ref $prefix/symref $prefix/foo &&
371 mkdir -p .git/$prefix/foo/bar &&
372 : >.git/$prefix/foo/bar/baz.lock &&
373 test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" &&
374 cat >expected <<-EOF &&
375 fatal: cannot lock ref $Q$prefix/symref$Q: there is a non-empty directory $Q.git/$prefix/foo$Q blocking reference $Q$prefix/foo$Q
377 printf "%s\n" "update $prefix/symref $C" |
378 test_must_fail git update-ref --stdin 2>output.err &&
379 test_cmp expected output.err &&
380 cat >expected <<-EOF &&
381 fatal: cannot lock ref $Q$prefix/symref$Q: unable to resolve reference $Q$prefix/foo$Q
383 printf "%s\n" "update $prefix/symref $D $C" |
384 test_must_fail git update-ref --stdin 2>output.err &&
385 test_cmp expected output.err
388 test_expect_success 'broken reference blocks indirect create' '
389 prefix=refs/broken-indirect-create &&
390 git symbolic-ref $prefix/symref $prefix/foo &&
391 echo "gobbledigook" >.git/$prefix/foo &&
392 test_when_finished "rm -f .git/$prefix/foo" &&
393 cat >expected <<-EOF &&
394 fatal: cannot lock ref $Q$prefix/symref$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
396 printf "%s\n" "update $prefix/symref $C" |
397 test_must_fail git update-ref --stdin 2>output.err &&
398 test_cmp expected output.err &&
399 cat >expected <<-EOF &&
400 fatal: cannot lock ref $Q$prefix/symref$Q: unable to resolve reference $Q$prefix/foo$Q: reference broken
402 printf "%s\n" "update $prefix/symref $D $C" |
403 test_must_fail git update-ref --stdin 2>output.err &&
404 test_cmp expected output.err
407 test_expect_success 'no bogus intermediate values during delete' '
408 prefix=refs/slow-transaction &&
409 # Set up a reference with differing loose and packed versions:
410 git update-ref $prefix/foo $C &&
411 git pack-refs --all &&
412 git update-ref $prefix/foo $D &&
413 git for-each-ref $prefix >unchanged &&
414 # Now try to update the reference, but hold the `packed-refs` lock
415 # for a while to see what happens while the process is blocked:
416 : >.git/packed-refs.lock &&
417 test_when_finished "rm -f .git/packed-refs.lock" &&
419 # Note: the following command is intentionally run in the
420 # background. We increase the timeout so that `update-ref`
421 # attempts to acquire the `packed-refs` lock for longer than
422 # it takes for us to do the check then delete it:
423 git -c core.packedrefstimeout=3000 update-ref -d $prefix/foo &
426 # Give update-ref plenty of time to get to the point where it tries
427 # to lock packed-refs:
429 # Make sure that update-ref did not complete despite the lock:
431 # Verify that the reference still has its old value:
432 sha1=$(git rev-parse --verify --quiet $prefix/foo || echo undefined) &&
435 # This is what we hope for; it means that nothing
436 # user-visible has changed yet.
439 # This is not correct; it means the deletion has happened
440 # already even though update-ref should not have been
441 # able to acquire the lock yet.
442 echo "$prefix/foo deleted prematurely" &&
446 # This value should never be seen. Probably the loose
447 # reference has been deleted but the packed reference
449 echo "$prefix/foo incorrectly observed to be C" &&
454 echo "unexpected value observed for $prefix/foo: $sha1" &&
458 rm -f .git/packed-refs.lock &&
460 test_must_be_empty out &&
461 test_must_fail git rev-parse --verify --quiet $prefix/foo
464 test_expect_success 'delete fails cleanly if packed-refs file is locked' '
465 prefix=refs/locked-packed-refs &&
466 # Set up a reference with differing loose and packed versions:
467 git update-ref $prefix/foo $C &&
468 git pack-refs --all &&
469 git update-ref $prefix/foo $D &&
470 git for-each-ref $prefix >unchanged &&
471 # Now try to delete it while the `packed-refs` lock is held:
472 : >.git/packed-refs.lock &&
473 test_when_finished "rm -f .git/packed-refs.lock" &&
474 test_must_fail git update-ref -d $prefix/foo >out 2>err &&
475 git for-each-ref $prefix >actual &&
476 test_i18ngrep "Unable to create $Q.*packed-refs.lock$Q: File exists" err &&
477 test_cmp unchanged actual