]> git.ipfire.org Git - thirdparty/git.git/blob - t/t1400-update-ref.sh
9ac4b7036bf7ec8fe0befca6f08797c83a72c4b0
[thirdparty/git.git] / t / t1400-update-ref.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2006 Shawn Pearce
4 #
5
6 test_description='Test git update-ref and basic ref logging'
7 . ./test-lib.sh
8
9 Z=$ZERO_OID
10
11 m=refs/heads/main
12 n_dir=refs/heads/gu
13 n=$n_dir/fixes
14 outside=refs/foo
15 bare=bare-repo
16
17 create_test_commits ()
18 {
19 prfx="$1"
20 for name in A B C D E F
21 do
22 test_tick &&
23 T=$(git write-tree) &&
24 sha1=$(echo $name | git commit-tree $T) &&
25 eval $prfx$name=$sha1
26 done
27 }
28
29 test_expect_success setup '
30 git checkout --orphan main &&
31 create_test_commits "" &&
32 mkdir $bare &&
33 cd $bare &&
34 git init --bare -b main &&
35 create_test_commits "bare" &&
36 cd -
37 '
38
39 test_expect_success "create $m" '
40 git update-ref $m $A &&
41 test $A = $(git show-ref -s --verify $m)
42 '
43 test_expect_success "create $m with oldvalue verification" '
44 git update-ref $m $B $A &&
45 test $B = $(git show-ref -s --verify $m)
46 '
47 test_expect_success "fail to delete $m with stale ref" '
48 test_must_fail git update-ref -d $m $A &&
49 test $B = "$(git show-ref -s --verify $m)"
50 '
51 test_expect_success "delete $m" '
52 test_when_finished "git update-ref -d $m" &&
53 git update-ref -d $m $B &&
54 test_must_fail git show-ref --verify -q $m
55 '
56
57 test_expect_success "delete $m without oldvalue verification" '
58 test_when_finished "git update-ref -d $m" &&
59 git update-ref $m $A &&
60 test $A = $(git show-ref -s --verify $m) &&
61 git update-ref -d $m &&
62 test_must_fail git show-ref --verify -q $m
63 '
64
65 test_expect_success "fail to create $n" '
66 test_when_finished "rm -f .git/$n_dir" &&
67 touch .git/$n_dir &&
68 test_must_fail git update-ref $n $A
69 '
70
71 test_expect_success "create $m (by HEAD)" '
72 git update-ref HEAD $A &&
73 test $A = $(git show-ref -s --verify $m)
74 '
75 test_expect_success "create $m (by HEAD) with oldvalue verification" '
76 git update-ref HEAD $B $A &&
77 test $B = $(git show-ref -s --verify $m)
78 '
79 test_expect_success "fail to delete $m (by HEAD) with stale ref" '
80 test_must_fail git update-ref -d HEAD $A &&
81 test $B = $(git show-ref -s --verify $m)
82 '
83 test_expect_success "delete $m (by HEAD)" '
84 test_when_finished "git update-ref -d $m" &&
85 git update-ref -d HEAD $B &&
86 test_must_fail git show-ref --verify -q $m
87 '
88
89 test_expect_success "deleting current branch adds message to HEAD's log" '
90 test_when_finished "git update-ref -d $m" &&
91 git update-ref $m $A &&
92 git symbolic-ref HEAD $m &&
93 git update-ref -m delete-$m -d $m &&
94 test_must_fail git show-ref --verify -q $m &&
95 grep "delete-$m$" .git/logs/HEAD
96 '
97
98 test_expect_success "deleting by HEAD adds message to HEAD's log" '
99 test_when_finished "git update-ref -d $m" &&
100 git update-ref $m $A &&
101 git symbolic-ref HEAD $m &&
102 git update-ref -m delete-by-head -d HEAD &&
103 test_must_fail git show-ref --verify -q $m &&
104 grep "delete-by-head$" .git/logs/HEAD
105 '
106
107 test_expect_success 'update-ref does not create reflogs by default' '
108 test_when_finished "git update-ref -d $outside" &&
109 git update-ref $outside $A &&
110 git rev-parse $A >expect &&
111 git rev-parse $outside >actual &&
112 test_cmp expect actual &&
113 test_must_fail git reflog exists $outside
114 '
115
116 test_expect_success 'update-ref creates reflogs with --create-reflog' '
117 test_when_finished "git update-ref -d $outside" &&
118 git update-ref --create-reflog $outside $A &&
119 git rev-parse $A >expect &&
120 git rev-parse $outside >actual &&
121 test_cmp expect actual &&
122 git reflog exists $outside
123 '
124
125 test_expect_success 'creates no reflog in bare repository' '
126 git -C $bare update-ref $m $bareA &&
127 git -C $bare rev-parse $bareA >expect &&
128 git -C $bare rev-parse $m >actual &&
129 test_cmp expect actual &&
130 test_must_fail git -C $bare reflog exists $m
131 '
132
133 test_expect_success 'core.logAllRefUpdates=true creates reflog in bare repository' '
134 test_when_finished "git -C $bare config --unset core.logAllRefUpdates && \
135 rm $bare/logs/$m" &&
136 git -C $bare config core.logAllRefUpdates true &&
137 git -C $bare update-ref $m $bareB &&
138 git -C $bare rev-parse $bareB >expect &&
139 git -C $bare rev-parse $m >actual &&
140 test_cmp expect actual &&
141 git -C $bare reflog exists $m
142 '
143
144 test_expect_success 'core.logAllRefUpdates=true does not create reflog by default' '
145 test_config core.logAllRefUpdates true &&
146 test_when_finished "git update-ref -d $outside" &&
147 git update-ref $outside $A &&
148 git rev-parse $A >expect &&
149 git rev-parse $outside >actual &&
150 test_cmp expect actual &&
151 test_must_fail git reflog exists $outside
152 '
153
154 test_expect_success 'core.logAllRefUpdates=always creates reflog by default' '
155 test_config core.logAllRefUpdates always &&
156 test_when_finished "git update-ref -d $outside" &&
157 git update-ref $outside $A &&
158 git rev-parse $A >expect &&
159 git rev-parse $outside >actual &&
160 test_cmp expect actual &&
161 git reflog exists $outside
162 '
163
164 test_expect_success 'core.logAllRefUpdates=always creates reflog for ORIG_HEAD' '
165 test_config core.logAllRefUpdates always &&
166 git update-ref ORIG_HEAD $A &&
167 git reflog exists ORIG_HEAD
168 '
169
170 test_expect_success '--no-create-reflog overrides core.logAllRefUpdates=always' '
171 test_config core.logAllRefUpdates true &&
172 test_when_finished "git update-ref -d $outside" &&
173 git update-ref --no-create-reflog $outside $A &&
174 git rev-parse $A >expect &&
175 git rev-parse $outside >actual &&
176 test_cmp expect actual &&
177 test_must_fail git reflog exists $outside
178 '
179
180 test_expect_success "create $m (by HEAD)" '
181 git update-ref HEAD $A &&
182 test $A = $(git show-ref -s --verify $m)
183 '
184 test_expect_success 'pack refs' '
185 git pack-refs --all
186 '
187 test_expect_success "move $m (by HEAD)" '
188 git update-ref HEAD $B $A &&
189 test $B = $(git show-ref -s --verify $m)
190 '
191 test_expect_success "delete $m (by HEAD) should remove both packed and loose $m" '
192 test_when_finished "git update-ref -d $m" &&
193 git update-ref -d HEAD $B &&
194 ! grep "$m" .git/packed-refs &&
195 test_must_fail git show-ref --verify -q $m
196 '
197
198 test_expect_success 'delete symref without dereference' '
199 test_when_finished "git update-ref -d $m" &&
200 echo foo >foo.c &&
201 git add foo.c &&
202 git commit -m foo &&
203 git symbolic-ref SYMREF $m &&
204 git update-ref --no-deref -d SYMREF &&
205 git show-ref --verify -q $m &&
206 test_must_fail git show-ref --verify -q SYMREF &&
207 test_must_fail git symbolic-ref SYMREF
208 '
209
210 test_expect_success 'delete symref without dereference when the referred ref is packed' '
211 test_when_finished "git update-ref -d $m" &&
212 echo foo >foo.c &&
213 git add foo.c &&
214 git commit -m foo &&
215 git symbolic-ref SYMREF $m &&
216 git pack-refs --all &&
217 git update-ref --no-deref -d SYMREF &&
218 git show-ref --verify -q $m &&
219 test_must_fail git show-ref --verify -q SYMREF &&
220 test_must_fail git symbolic-ref SYMREF
221 '
222
223 test_expect_success 'update-ref -d is not confused by self-reference' '
224 git symbolic-ref refs/heads/self refs/heads/self &&
225 test_when_finished "rm -f .git/refs/heads/self" &&
226 test_path_is_file .git/refs/heads/self &&
227 test_must_fail git update-ref -d refs/heads/self &&
228 test_path_is_file .git/refs/heads/self
229 '
230
231 test_expect_success 'update-ref --no-deref -d can delete self-reference' '
232 git symbolic-ref refs/heads/self refs/heads/self &&
233 test_when_finished "rm -f .git/refs/heads/self" &&
234 test_path_is_file .git/refs/heads/self &&
235 git update-ref --no-deref -d refs/heads/self &&
236 test_must_fail git show-ref --verify -q refs/heads/self
237 '
238
239 test_expect_success 'update-ref --no-deref -d can delete reference to bad ref' '
240 >.git/refs/heads/bad &&
241 test_when_finished "rm -f .git/refs/heads/bad" &&
242 git symbolic-ref refs/heads/ref-to-bad refs/heads/bad &&
243 test_when_finished "git update-ref -d refs/heads/ref-to-bad" &&
244 test_path_is_file .git/refs/heads/ref-to-bad &&
245 git update-ref --no-deref -d refs/heads/ref-to-bad &&
246 test_must_fail git show-ref --verify -q refs/heads/ref-to-bad
247 '
248
249 test_expect_success '(not) create HEAD with old sha1' '
250 test_must_fail git update-ref HEAD $A $B
251 '
252 test_expect_success "(not) prior created .git/$m" '
253 test_when_finished "git update-ref -d $m" &&
254 test_must_fail git show-ref --verify -q $m
255 '
256
257 test_expect_success 'create HEAD' '
258 git update-ref HEAD $A
259 '
260 test_expect_success '(not) change HEAD with wrong SHA1' '
261 test_must_fail git update-ref HEAD $B $Z
262 '
263 test_expect_success "(not) changed .git/$m" '
264 test_when_finished "git update-ref -d $m" &&
265 ! test $B = $(git show-ref -s --verify $m)
266 '
267
268 rm -f .git/logs/refs/heads/main
269 test_expect_success "create $m (logged by touch)" '
270 test_config core.logAllRefUpdates false &&
271 GIT_COMMITTER_DATE="2005-05-26 23:30" \
272 git update-ref --create-reflog HEAD $A -m "Initial Creation" &&
273 test $A = $(git show-ref -s --verify $m)
274 '
275 test_expect_success "update $m (logged by touch)" '
276 test_config core.logAllRefUpdates false &&
277 GIT_COMMITTER_DATE="2005-05-26 23:31" \
278 git update-ref HEAD $B $A -m "Switch" &&
279 test $B = $(git show-ref -s --verify $m)
280 '
281 test_expect_success "set $m (logged by touch)" '
282 test_config core.logAllRefUpdates false &&
283 GIT_COMMITTER_DATE="2005-05-26 23:41" \
284 git update-ref HEAD $A &&
285 test $A = $(git show-ref -s --verify $m)
286 '
287
288 test_expect_success 'empty directory removal' '
289 git branch d1/d2/r1 HEAD &&
290 git branch d1/r2 HEAD &&
291 test_path_is_file .git/refs/heads/d1/d2/r1 &&
292 test_path_is_file .git/logs/refs/heads/d1/d2/r1 &&
293 git branch -d d1/d2/r1 &&
294 test_must_fail git show-ref --verify -q refs/heads/d1/d2 &&
295 test_must_fail git show-ref --verify -q logs/refs/heads/d1/d2 &&
296 test_path_is_file .git/refs/heads/d1/r2 &&
297 test_path_is_file .git/logs/refs/heads/d1/r2
298 '
299
300 test_expect_success 'symref empty directory removal' '
301 git branch e1/e2/r1 HEAD &&
302 git branch e1/r2 HEAD &&
303 git checkout e1/e2/r1 &&
304 test_when_finished "git checkout main" &&
305 test_path_is_file .git/refs/heads/e1/e2/r1 &&
306 test_path_is_file .git/logs/refs/heads/e1/e2/r1 &&
307 git update-ref -d HEAD &&
308 test_must_fail git show-ref --verify -q refs/heads/e1/e2 &&
309 test_must_fail git show-ref --verify -q logs/refs/heads/e1/e2 &&
310 test_path_is_file .git/refs/heads/e1/r2 &&
311 test_path_is_file .git/logs/refs/heads/e1/r2 &&
312 test_path_is_file .git/logs/HEAD
313 '
314
315 cat >expect <<EOF
316 $Z $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 Initial Creation
317 $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150260 +0000 Switch
318 $B $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150860 +0000
319 EOF
320 test_expect_success "verifying $m's log (logged by touch)" '
321 test_when_finished "git update-ref -d $m && rm -rf .git/logs actual expect" &&
322 test-tool ref-store main for-each-reflog-ent $m >actual &&
323 test_cmp actual expect
324 '
325
326 test_expect_success "create $m (logged by config)" '
327 test_config core.logAllRefUpdates true &&
328 GIT_COMMITTER_DATE="2005-05-26 23:32" \
329 git update-ref HEAD $A -m "Initial Creation" &&
330 test $A = $(git show-ref -s --verify $m)
331 '
332 test_expect_success "update $m (logged by config)" '
333 test_config core.logAllRefUpdates true &&
334 GIT_COMMITTER_DATE="2005-05-26 23:33" \
335 git update-ref HEAD $B $A -m "Switch" &&
336 test $B = $(git show-ref -s --verify $m)
337 '
338 test_expect_success "set $m (logged by config)" '
339 test_config core.logAllRefUpdates true &&
340 GIT_COMMITTER_DATE="2005-05-26 23:43" \
341 git update-ref HEAD $A &&
342 test $A = $(git show-ref -s --verify $m)
343 '
344
345 cat >expect <<EOF
346 $Z $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150320 +0000 Initial Creation
347 $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 +0000 Switch
348 $B $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 +0000
349 EOF
350 test_expect_success "verifying $m's log (logged by config)" '
351 test_when_finished "git update-ref -d $m && rm -rf .git/logs actual expect" &&
352 test-tool ref-store main for-each-reflog-ent $m >actual &&
353 test_cmp actual expect
354 '
355
356 test_expect_success 'set up for querying the reflog' '
357 git update-ref $m $D &&
358 cat >.git/logs/$m <<-EOF
359 $Z $C $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150320 -0500
360 $C $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150350 -0500
361 $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 -0500
362 $F $Z $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150680 -0500
363 $Z $E $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 -0500
364 EOF
365 '
366
367 ed="Thu, 26 May 2005 18:32:00 -0500"
368 gd="Thu, 26 May 2005 18:33:00 -0500"
369 ld="Thu, 26 May 2005 18:43:00 -0500"
370 test_expect_success 'Query "main@{May 25 2005}" (before history)' '
371 test_when_finished "rm -f o e" &&
372 git rev-parse --verify "main@{May 25 2005}" >o 2>e &&
373 echo "$C" >expect &&
374 test_cmp expect o &&
375 echo "warning: log for '\''main'\'' only goes back to $ed" >expect &&
376 test_cmp expect e
377 '
378 test_expect_success 'Query main@{2005-05-25} (before history)' '
379 test_when_finished "rm -f o e" &&
380 git rev-parse --verify main@{2005-05-25} >o 2>e &&
381 echo "$C" >expect &&
382 test_cmp expect o &&
383 echo "warning: log for '\''main'\'' only goes back to $ed" >expect &&
384 test_cmp expect e
385 '
386 test_expect_success 'Query "main@{May 26 2005 23:31:59}" (1 second before history)' '
387 test_when_finished "rm -f o e" &&
388 git rev-parse --verify "main@{May 26 2005 23:31:59}" >o 2>e &&
389 echo "$C" >expect &&
390 test_cmp expect o &&
391 echo "warning: log for '\''main'\'' only goes back to $ed" >expect &&
392 test_cmp expect e
393 '
394 test_expect_success 'Query "main@{May 26 2005 23:32:00}" (exactly history start)' '
395 test_when_finished "rm -f o e" &&
396 git rev-parse --verify "main@{May 26 2005 23:32:00}" >o 2>e &&
397 echo "$C" >expect &&
398 test_cmp expect o &&
399 test_must_be_empty e
400 '
401 test_expect_success 'Query "main@{May 26 2005 23:32:30}" (first non-creation change)' '
402 test_when_finished "rm -f o e" &&
403 git rev-parse --verify "main@{May 26 2005 23:32:30}" >o 2>e &&
404 echo "$A" >expect &&
405 test_cmp expect o &&
406 test_must_be_empty e
407 '
408 test_expect_success 'Query "main@{2005-05-26 23:33:01}" (middle of history with gap)' '
409 test_when_finished "rm -f o e" &&
410 git rev-parse --verify "main@{2005-05-26 23:33:01}" >o 2>e &&
411 echo "$B" >expect &&
412 test_cmp expect o &&
413 test_grep -F "warning: log for ref $m has gap after $gd" e
414 '
415 test_expect_success 'Query "main@{2005-05-26 23:38:00}" (middle of history)' '
416 test_when_finished "rm -f o e" &&
417 git rev-parse --verify "main@{2005-05-26 23:38:00}" >o 2>e &&
418 echo "$Z" >expect &&
419 test_cmp expect o &&
420 test_must_be_empty e
421 '
422 test_expect_success 'Query "main@{2005-05-26 23:43:00}" (exact end of history)' '
423 test_when_finished "rm -f o e" &&
424 git rev-parse --verify "main@{2005-05-26 23:43:00}" >o 2>e &&
425 echo "$E" >expect &&
426 test_cmp expect o &&
427 test_must_be_empty e
428 '
429 test_expect_success 'Query "main@{2005-05-28}" (past end of history)' '
430 test_when_finished "rm -f o e" &&
431 git rev-parse --verify "main@{2005-05-28}" >o 2>e &&
432 echo "$D" >expect &&
433 test_cmp expect o &&
434 test_grep -F "warning: log for ref $m unexpectedly ended on $ld" e
435 '
436
437 rm -f .git/$m .git/logs/$m expect
438
439 test_expect_success 'creating initial files' '
440 test_when_finished rm -f M &&
441 echo TEST >F &&
442 git add F &&
443 GIT_AUTHOR_DATE="2005-05-26 23:30" \
444 GIT_COMMITTER_DATE="2005-05-26 23:30" git commit -m add -a &&
445 h_TEST=$(git rev-parse --verify HEAD) &&
446 echo The other day this did not work. >M &&
447 echo And then Bob told me how to fix it. >>M &&
448 echo OTHER >F &&
449 GIT_AUTHOR_DATE="2005-05-26 23:41" \
450 GIT_COMMITTER_DATE="2005-05-26 23:41" git commit -F M -a &&
451 h_OTHER=$(git rev-parse --verify HEAD) &&
452 GIT_AUTHOR_DATE="2005-05-26 23:44" \
453 GIT_COMMITTER_DATE="2005-05-26 23:44" git commit --amend &&
454 h_FIXED=$(git rev-parse --verify HEAD) &&
455 echo Merged initial commit and a later commit. >M &&
456 echo $h_TEST >.git/MERGE_HEAD &&
457 GIT_AUTHOR_DATE="2005-05-26 23:45" \
458 GIT_COMMITTER_DATE="2005-05-26 23:45" git commit -F M &&
459 h_MERGED=$(git rev-parse --verify HEAD)
460 '
461
462 cat >expect <<EOF
463 $Z $h_TEST $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 commit (initial): add
464 $h_TEST $h_OTHER $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150860 +0000 commit: The other day this did not work.
465 $h_OTHER $h_FIXED $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117151040 +0000 commit (amend): The other day this did not work.
466 $h_FIXED $h_MERGED $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117151100 +0000 commit (merge): Merged initial commit and a later commit.
467 EOF
468 test_expect_success 'git commit logged updates' '
469 test-tool ref-store main for-each-reflog-ent $m >actual &&
470 test_cmp expect actual
471 '
472 unset h_TEST h_OTHER h_FIXED h_MERGED
473
474 test_expect_success 'git cat-file blob main:F (expect OTHER)' '
475 test OTHER = $(git cat-file blob main:F)
476 '
477 test_expect_success 'git cat-file blob main@{2005-05-26 23:30}:F (expect TEST)' '
478 test TEST = $(git cat-file blob "main@{2005-05-26 23:30}:F")
479 '
480 test_expect_success 'git cat-file blob main@{2005-05-26 23:42}:F (expect OTHER)' '
481 test OTHER = $(git cat-file blob "main@{2005-05-26 23:42}:F")
482 '
483
484 # Test adding and deleting pseudorefs
485
486 test_expect_success 'given old value for missing pseudoref, do not create' '
487 test_must_fail git update-ref PSEUDOREF $A $B 2>err &&
488 test_must_fail git rev-parse PSEUDOREF &&
489 test_grep "unable to resolve reference" err
490 '
491
492 test_expect_success 'create pseudoref' '
493 git update-ref PSEUDOREF $A &&
494 test $A = $(git rev-parse PSEUDOREF)
495 '
496
497 test_expect_success 'overwrite pseudoref with no old value given' '
498 git update-ref PSEUDOREF $B &&
499 test $B = $(git rev-parse PSEUDOREF)
500 '
501
502 test_expect_success 'overwrite pseudoref with correct old value' '
503 git update-ref PSEUDOREF $C $B &&
504 test $C = $(git rev-parse PSEUDOREF)
505 '
506
507 test_expect_success 'do not overwrite pseudoref with wrong old value' '
508 test_must_fail git update-ref PSEUDOREF $D $E 2>err &&
509 test $C = $(git rev-parse PSEUDOREF) &&
510 test_grep "cannot lock ref.*expected" err
511 '
512
513 test_expect_success 'delete pseudoref' '
514 git update-ref -d PSEUDOREF &&
515 test_must_fail git rev-parse PSEUDOREF
516 '
517
518 test_expect_success 'do not delete pseudoref with wrong old value' '
519 git update-ref PSEUDOREF $A &&
520 test_must_fail git update-ref -d PSEUDOREF $B 2>err &&
521 test $A = $(git rev-parse PSEUDOREF) &&
522 test_grep "cannot lock ref.*expected" err
523 '
524
525 test_expect_success 'delete pseudoref with correct old value' '
526 git update-ref -d PSEUDOREF $A &&
527 test_must_fail git rev-parse PSEUDOREF
528 '
529
530 test_expect_success 'create pseudoref with old OID zero' '
531 git update-ref PSEUDOREF $A $Z &&
532 test $A = $(git rev-parse PSEUDOREF)
533 '
534
535 test_expect_success 'do not overwrite pseudoref with old OID zero' '
536 test_when_finished git update-ref -d PSEUDOREF &&
537 test_must_fail git update-ref PSEUDOREF $B $Z 2>err &&
538 test $A = $(git rev-parse PSEUDOREF) &&
539 test_grep "already exists" err
540 '
541
542 # Test --stdin
543
544 a=refs/heads/a
545 b=refs/heads/b
546 c=refs/heads/c
547 E='""'
548 F='%s\0'
549 pws='path with space'
550
551 test_expect_success 'stdin test setup' '
552 echo "$pws" >"$pws" &&
553 git add -- "$pws" &&
554 git commit -m "$pws"
555 '
556
557 test_expect_success '-z fails without --stdin' '
558 test_must_fail git update-ref -z $m $m $m 2>err &&
559 test_grep "usage: git update-ref" err
560 '
561
562 test_expect_success 'stdin works with no input' '
563 >stdin &&
564 git update-ref --stdin <stdin &&
565 git rev-parse --verify -q $m
566 '
567
568 test_expect_success 'stdin fails on empty line' '
569 echo "" >stdin &&
570 test_must_fail git update-ref --stdin <stdin 2>err &&
571 grep "fatal: empty command in input" err
572 '
573
574 test_expect_success 'stdin fails on only whitespace' '
575 echo " " >stdin &&
576 test_must_fail git update-ref --stdin <stdin 2>err &&
577 grep "fatal: whitespace before command: " err
578 '
579
580 test_expect_success 'stdin fails on leading whitespace' '
581 echo " create $a $m" >stdin &&
582 test_must_fail git update-ref --stdin <stdin 2>err &&
583 grep "fatal: whitespace before command: create $a $m" err
584 '
585
586 test_expect_success 'stdin fails on unknown command' '
587 echo "unknown $a" >stdin &&
588 test_must_fail git update-ref --stdin <stdin 2>err &&
589 grep "fatal: unknown command: unknown $a" err
590 '
591
592 test_expect_success 'stdin fails on unbalanced quotes' '
593 echo "create $a \"main" >stdin &&
594 test_must_fail git update-ref --stdin <stdin 2>err &&
595 grep "fatal: badly quoted argument: \\\"main" err
596 '
597
598 test_expect_success 'stdin fails on invalid escape' '
599 echo "create $a \"ma\zn\"" >stdin &&
600 test_must_fail git update-ref --stdin <stdin 2>err &&
601 grep "fatal: badly quoted argument: \\\"ma\\\\zn\\\"" err
602 '
603
604 test_expect_success 'stdin fails on junk after quoted argument' '
605 echo "create \"$a\"main" >stdin &&
606 test_must_fail git update-ref --stdin <stdin 2>err &&
607 grep "fatal: unexpected character after quoted argument: \\\"$a\\\"main" err
608 '
609
610 test_expect_success 'stdin fails create with no ref' '
611 echo "create " >stdin &&
612 test_must_fail git update-ref --stdin <stdin 2>err &&
613 grep "fatal: create: missing <ref>" err
614 '
615
616 test_expect_success 'stdin fails create with no new value' '
617 echo "create $a" >stdin &&
618 test_must_fail git update-ref --stdin <stdin 2>err &&
619 grep "fatal: create $a: missing <newvalue>" err
620 '
621
622 test_expect_success 'stdin fails create with too many arguments' '
623 echo "create $a $m $m" >stdin &&
624 test_must_fail git update-ref --stdin <stdin 2>err &&
625 grep "fatal: create $a: extra input: $m" err
626 '
627
628 test_expect_success 'stdin fails update with no ref' '
629 echo "update " >stdin &&
630 test_must_fail git update-ref --stdin <stdin 2>err &&
631 grep "fatal: update: missing <ref>" err
632 '
633
634 test_expect_success 'stdin fails update with no new value' '
635 echo "update $a" >stdin &&
636 test_must_fail git update-ref --stdin <stdin 2>err &&
637 grep "fatal: update $a: missing <newvalue>" err
638 '
639
640 test_expect_success 'stdin fails update with too many arguments' '
641 echo "update $a $m $m $m" >stdin &&
642 test_must_fail git update-ref --stdin <stdin 2>err &&
643 grep "fatal: update $a: extra input: $m" err
644 '
645
646 test_expect_success 'stdin fails delete with no ref' '
647 echo "delete " >stdin &&
648 test_must_fail git update-ref --stdin <stdin 2>err &&
649 grep "fatal: delete: missing <ref>" err
650 '
651
652 test_expect_success 'stdin fails delete with too many arguments' '
653 echo "delete $a $m $m" >stdin &&
654 test_must_fail git update-ref --stdin <stdin 2>err &&
655 grep "fatal: delete $a: extra input: $m" err
656 '
657
658 test_expect_success 'stdin fails verify with too many arguments' '
659 echo "verify $a $m $m" >stdin &&
660 test_must_fail git update-ref --stdin <stdin 2>err &&
661 grep "fatal: verify $a: extra input: $m" err
662 '
663
664 test_expect_success 'stdin fails option with unknown name' '
665 echo "option unknown" >stdin &&
666 test_must_fail git update-ref --stdin <stdin 2>err &&
667 grep "fatal: option unknown: unknown" err
668 '
669
670 test_expect_success 'stdin fails with duplicate refs' '
671 cat >stdin <<-EOF &&
672 create $a $m
673 create $b $m
674 create $a $m
675 EOF
676 test_must_fail git update-ref --stdin <stdin 2>err &&
677 test_grep "fatal: multiple updates for ref '"'"'$a'"'"' not allowed" err
678 '
679
680 test_expect_success 'stdin create ref works' '
681 echo "create $a $m" >stdin &&
682 git update-ref --stdin <stdin &&
683 git rev-parse $m >expect &&
684 git rev-parse $a >actual &&
685 test_cmp expect actual
686 '
687
688 test_expect_success 'stdin does not create reflogs by default' '
689 test_when_finished "git update-ref -d $outside" &&
690 echo "create $outside $m" >stdin &&
691 git update-ref --stdin <stdin &&
692 git rev-parse $m >expect &&
693 git rev-parse $outside >actual &&
694 test_cmp expect actual &&
695 test_must_fail git reflog exists $outside
696 '
697
698 test_expect_success 'stdin creates reflogs with --create-reflog' '
699 test_when_finished "git update-ref -d $outside" &&
700 echo "create $outside $m" >stdin &&
701 git update-ref --create-reflog --stdin <stdin &&
702 git rev-parse $m >expect &&
703 git rev-parse $outside >actual &&
704 test_cmp expect actual &&
705 git reflog exists $outside
706 '
707
708 test_expect_success 'stdin succeeds with quoted argument' '
709 git update-ref -d $a &&
710 echo "create $a \"$m\"" >stdin &&
711 git update-ref --stdin <stdin &&
712 git rev-parse $m >expect &&
713 git rev-parse $a >actual &&
714 test_cmp expect actual
715 '
716
717 test_expect_success 'stdin succeeds with escaped character' '
718 git update-ref -d $a &&
719 echo "create $a \"ma\\151n\"" >stdin &&
720 git update-ref --stdin <stdin &&
721 git rev-parse $m >expect &&
722 git rev-parse $a >actual &&
723 test_cmp expect actual
724 '
725
726 test_expect_success 'stdin update ref creates with zero old value' '
727 echo "update $b $m $Z" >stdin &&
728 git update-ref --stdin <stdin &&
729 git rev-parse $m >expect &&
730 git rev-parse $b >actual &&
731 test_cmp expect actual &&
732 git update-ref -d $b
733 '
734
735 test_expect_success 'stdin update ref creates with empty old value' '
736 echo "update $b $m $E" >stdin &&
737 git update-ref --stdin <stdin &&
738 git rev-parse $m >expect &&
739 git rev-parse $b >actual &&
740 test_cmp expect actual
741 '
742
743 test_expect_success 'stdin create ref works with path with space to blob' '
744 echo "create refs/blobs/pws \"$m:$pws\"" >stdin &&
745 git update-ref --stdin <stdin &&
746 git rev-parse "$m:$pws" >expect &&
747 git rev-parse refs/blobs/pws >actual &&
748 test_cmp expect actual &&
749 git update-ref -d refs/blobs/pws
750 '
751
752 test_expect_success 'stdin update ref fails with wrong old value' '
753 echo "update $c $m $m~1" >stdin &&
754 test_must_fail git update-ref --stdin <stdin 2>err &&
755 grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
756 test_must_fail git rev-parse --verify -q $c
757 '
758
759 test_expect_success 'stdin update ref fails with bad old value' '
760 echo "update $c $m does-not-exist" >stdin &&
761 test_must_fail git update-ref --stdin <stdin 2>err &&
762 grep "fatal: update $c: invalid <oldvalue>: does-not-exist" err &&
763 test_must_fail git rev-parse --verify -q $c
764 '
765
766 test_expect_success 'stdin create ref fails with bad new value' '
767 echo "create $c does-not-exist" >stdin &&
768 test_must_fail git update-ref --stdin <stdin 2>err &&
769 grep "fatal: create $c: invalid <newvalue>: does-not-exist" err &&
770 test_must_fail git rev-parse --verify -q $c
771 '
772
773 test_expect_success 'stdin create ref fails with zero new value' '
774 echo "create $c " >stdin &&
775 test_must_fail git update-ref --stdin <stdin 2>err &&
776 grep "fatal: create $c: zero <newvalue>" err &&
777 test_must_fail git rev-parse --verify -q $c
778 '
779
780 test_expect_success 'stdin update ref works with right old value' '
781 echo "update $b $m~1 $m" >stdin &&
782 git update-ref --stdin <stdin &&
783 git rev-parse $m~1 >expect &&
784 git rev-parse $b >actual &&
785 test_cmp expect actual
786 '
787
788 test_expect_success 'stdin delete ref fails with wrong old value' '
789 echo "delete $a $m~1" >stdin &&
790 test_must_fail git update-ref --stdin <stdin 2>err &&
791 grep "fatal: cannot lock ref '"'"'$a'"'"'" err &&
792 git rev-parse $m >expect &&
793 git rev-parse $a >actual &&
794 test_cmp expect actual
795 '
796
797 test_expect_success 'stdin delete ref fails with zero old value' '
798 echo "delete $a " >stdin &&
799 test_must_fail git update-ref --stdin <stdin 2>err &&
800 grep "fatal: delete $a: zero <oldvalue>" err &&
801 git rev-parse $m >expect &&
802 git rev-parse $a >actual &&
803 test_cmp expect actual
804 '
805
806 test_expect_success 'stdin update symref works option no-deref' '
807 git symbolic-ref TESTSYMREF $b &&
808 cat >stdin <<-EOF &&
809 option no-deref
810 update TESTSYMREF $a $b
811 EOF
812 git update-ref --stdin <stdin &&
813 git rev-parse TESTSYMREF >expect &&
814 git rev-parse $a >actual &&
815 test_cmp expect actual &&
816 git rev-parse $m~1 >expect &&
817 git rev-parse $b >actual &&
818 test_cmp expect actual
819 '
820
821 test_expect_success 'stdin delete symref works option no-deref' '
822 git symbolic-ref TESTSYMREF $b &&
823 cat >stdin <<-EOF &&
824 option no-deref
825 delete TESTSYMREF $b
826 EOF
827 git update-ref --stdin <stdin &&
828 test_must_fail git rev-parse --verify -q TESTSYMREF &&
829 git rev-parse $m~1 >expect &&
830 git rev-parse $b >actual &&
831 test_cmp expect actual
832 '
833
834 test_expect_success 'stdin update symref works flag --no-deref' '
835 git symbolic-ref TESTSYMREFONE $b &&
836 git symbolic-ref TESTSYMREFTWO $b &&
837 cat >stdin <<-EOF &&
838 update TESTSYMREFONE $a $b
839 update TESTSYMREFTWO $a $b
840 EOF
841 git update-ref --no-deref --stdin <stdin &&
842 git rev-parse TESTSYMREFONE TESTSYMREFTWO >expect &&
843 git rev-parse $a $a >actual &&
844 test_cmp expect actual &&
845 git rev-parse $m~1 >expect &&
846 git rev-parse $b >actual &&
847 test_cmp expect actual
848 '
849
850 test_expect_success 'stdin delete symref works flag --no-deref' '
851 git symbolic-ref TESTSYMREFONE $b &&
852 git symbolic-ref TESTSYMREFTWO $b &&
853 cat >stdin <<-EOF &&
854 delete TESTSYMREFONE $b
855 delete TESTSYMREFTWO $b
856 EOF
857 git update-ref --no-deref --stdin <stdin &&
858 test_must_fail git rev-parse --verify -q TESTSYMREFONE &&
859 test_must_fail git rev-parse --verify -q TESTSYMREFTWO &&
860 git rev-parse $m~1 >expect &&
861 git rev-parse $b >actual &&
862 test_cmp expect actual
863 '
864
865 test_expect_success 'stdin delete ref works with right old value' '
866 echo "delete $b $m~1" >stdin &&
867 git update-ref --stdin <stdin &&
868 test_must_fail git rev-parse --verify -q $b
869 '
870
871 test_expect_success 'stdin update/create/verify combination works' '
872 cat >stdin <<-EOF &&
873 update $a $m
874 create $b $m
875 verify $c
876 EOF
877 git update-ref --stdin <stdin &&
878 git rev-parse $m >expect &&
879 git rev-parse $a >actual &&
880 test_cmp expect actual &&
881 git rev-parse $b >actual &&
882 test_cmp expect actual &&
883 test_must_fail git rev-parse --verify -q $c
884 '
885
886 test_expect_success 'stdin verify succeeds for correct value' '
887 git rev-parse $m >expect &&
888 echo "verify $m $m" >stdin &&
889 git update-ref --stdin <stdin &&
890 git rev-parse $m >actual &&
891 test_cmp expect actual
892 '
893
894 test_expect_success 'stdin verify succeeds for missing reference' '
895 echo "verify refs/heads/missing $Z" >stdin &&
896 git update-ref --stdin <stdin &&
897 test_must_fail git rev-parse --verify -q refs/heads/missing
898 '
899
900 test_expect_success 'stdin verify treats no value as missing' '
901 echo "verify refs/heads/missing" >stdin &&
902 git update-ref --stdin <stdin &&
903 test_must_fail git rev-parse --verify -q refs/heads/missing
904 '
905
906 test_expect_success 'stdin verify fails for wrong value' '
907 git rev-parse $m >expect &&
908 echo "verify $m $m~1" >stdin &&
909 test_must_fail git update-ref --stdin <stdin &&
910 git rev-parse $m >actual &&
911 test_cmp expect actual
912 '
913
914 test_expect_success 'stdin verify fails for mistaken null value' '
915 git rev-parse $m >expect &&
916 echo "verify $m $Z" >stdin &&
917 test_must_fail git update-ref --stdin <stdin &&
918 git rev-parse $m >actual &&
919 test_cmp expect actual
920 '
921
922 test_expect_success 'stdin verify fails for mistaken empty value' '
923 M=$(git rev-parse $m) &&
924 test_when_finished "git update-ref $m $M" &&
925 git rev-parse $m >expect &&
926 echo "verify $m" >stdin &&
927 test_must_fail git update-ref --stdin <stdin &&
928 git rev-parse $m >actual &&
929 test_cmp expect actual
930 '
931
932 test_expect_success 'stdin update refs works with identity updates' '
933 cat >stdin <<-EOF &&
934 update $a $m $m
935 update $b $m $m
936 update $c $Z $E
937 EOF
938 git update-ref --stdin <stdin &&
939 git rev-parse $m >expect &&
940 git rev-parse $a >actual &&
941 test_cmp expect actual &&
942 git rev-parse $b >actual &&
943 test_cmp expect actual &&
944 test_must_fail git rev-parse --verify -q $c
945 '
946
947 test_expect_success 'stdin update refs fails with wrong old value' '
948 git update-ref $c $m &&
949 cat >stdin <<-EOF &&
950 update $a $m $m
951 update $b $m $m
952 update $c ''
953 EOF
954 test_must_fail git update-ref --stdin <stdin 2>err &&
955 grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
956 git rev-parse $m >expect &&
957 git rev-parse $a >actual &&
958 test_cmp expect actual &&
959 git rev-parse $b >actual &&
960 test_cmp expect actual &&
961 git rev-parse $c >actual &&
962 test_cmp expect actual
963 '
964
965 test_expect_success 'stdin delete refs works with packed and loose refs' '
966 git pack-refs --all &&
967 git update-ref $c $m~1 &&
968 cat >stdin <<-EOF &&
969 delete $a $m
970 update $b $Z $m
971 update $c $E $m~1
972 EOF
973 git update-ref --stdin <stdin &&
974 test_must_fail git rev-parse --verify -q $a &&
975 test_must_fail git rev-parse --verify -q $b &&
976 test_must_fail git rev-parse --verify -q $c
977 '
978
979 test_expect_success 'stdin -z works on empty input' '
980 >stdin &&
981 git update-ref -z --stdin <stdin &&
982 git rev-parse --verify -q $m
983 '
984
985 test_expect_success 'stdin -z fails on empty line' '
986 echo "" >stdin &&
987 test_must_fail git update-ref -z --stdin <stdin 2>err &&
988 grep "fatal: whitespace before command: " err
989 '
990
991 test_expect_success 'stdin -z fails on empty command' '
992 printf $F "" >stdin &&
993 test_must_fail git update-ref -z --stdin <stdin 2>err &&
994 grep "fatal: empty command in input" err
995 '
996
997 test_expect_success 'stdin -z fails on only whitespace' '
998 printf $F " " >stdin &&
999 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1000 grep "fatal: whitespace before command: " err
1001 '
1002
1003 test_expect_success 'stdin -z fails on leading whitespace' '
1004 printf $F " create $a" "$m" >stdin &&
1005 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1006 grep "fatal: whitespace before command: create $a" err
1007 '
1008
1009 test_expect_success 'stdin -z fails on unknown command' '
1010 printf $F "unknown $a" >stdin &&
1011 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1012 grep "fatal: unknown command: unknown $a" err
1013 '
1014
1015 test_expect_success 'stdin -z fails create with no ref' '
1016 printf $F "create " >stdin &&
1017 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1018 grep "fatal: create: missing <ref>" err
1019 '
1020
1021 test_expect_success 'stdin -z fails create with no new value' '
1022 printf $F "create $a" >stdin &&
1023 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1024 grep "fatal: create $a: unexpected end of input when reading <newvalue>" err
1025 '
1026
1027 test_expect_success 'stdin -z fails create with too many arguments' '
1028 printf $F "create $a" "$m" "$m" >stdin &&
1029 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1030 grep "fatal: unknown command: $m" err
1031 '
1032
1033 test_expect_success 'stdin -z fails update with no ref' '
1034 printf $F "update " >stdin &&
1035 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1036 grep "fatal: update: missing <ref>" err
1037 '
1038
1039 test_expect_success 'stdin -z fails update with too few args' '
1040 printf $F "update $a" "$m" >stdin &&
1041 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1042 grep "fatal: update $a: unexpected end of input when reading <oldvalue>" err
1043 '
1044
1045 test_expect_success 'stdin -z emits warning with empty new value' '
1046 git update-ref $a $m &&
1047 printf $F "update $a" "" "" >stdin &&
1048 git update-ref -z --stdin <stdin 2>err &&
1049 grep "warning: update $a: missing <newvalue>, treating as zero" err &&
1050 test_must_fail git rev-parse --verify -q $a
1051 '
1052
1053 test_expect_success 'stdin -z fails update with no new value' '
1054 printf $F "update $a" >stdin &&
1055 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1056 grep "fatal: update $a: unexpected end of input when reading <newvalue>" err
1057 '
1058
1059 test_expect_success 'stdin -z fails update with no old value' '
1060 printf $F "update $a" "$m" >stdin &&
1061 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1062 grep "fatal: update $a: unexpected end of input when reading <oldvalue>" err
1063 '
1064
1065 test_expect_success 'stdin -z fails update with too many arguments' '
1066 printf $F "update $a" "$m" "$m" "$m" >stdin &&
1067 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1068 grep "fatal: unknown command: $m" err
1069 '
1070
1071 test_expect_success 'stdin -z fails delete with no ref' '
1072 printf $F "delete " >stdin &&
1073 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1074 grep "fatal: delete: missing <ref>" err
1075 '
1076
1077 test_expect_success 'stdin -z fails delete with no old value' '
1078 printf $F "delete $a" >stdin &&
1079 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1080 grep "fatal: delete $a: unexpected end of input when reading <oldvalue>" err
1081 '
1082
1083 test_expect_success 'stdin -z fails delete with too many arguments' '
1084 printf $F "delete $a" "$m" "$m" >stdin &&
1085 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1086 grep "fatal: unknown command: $m" err
1087 '
1088
1089 test_expect_success 'stdin -z fails verify with too many arguments' '
1090 printf $F "verify $a" "$m" "$m" >stdin &&
1091 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1092 grep "fatal: unknown command: $m" err
1093 '
1094
1095 test_expect_success 'stdin -z fails verify with no old value' '
1096 printf $F "verify $a" >stdin &&
1097 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1098 grep "fatal: verify $a: unexpected end of input when reading <oldvalue>" err
1099 '
1100
1101 test_expect_success 'stdin -z fails option with unknown name' '
1102 printf $F "option unknown" >stdin &&
1103 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1104 grep "fatal: option unknown: unknown" err
1105 '
1106
1107 test_expect_success 'stdin -z fails with duplicate refs' '
1108 printf $F "create $a" "$m" "create $b" "$m" "create $a" "$m" >stdin &&
1109 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1110 test_grep "fatal: multiple updates for ref '"'"'$a'"'"' not allowed" err
1111 '
1112
1113 test_expect_success 'stdin -z create ref works' '
1114 printf $F "create $a" "$m" >stdin &&
1115 git update-ref -z --stdin <stdin &&
1116 git rev-parse $m >expect &&
1117 git rev-parse $a >actual &&
1118 test_cmp expect actual
1119 '
1120
1121 test_expect_success 'stdin -z update ref creates with zero old value' '
1122 printf $F "update $b" "$m" "$Z" >stdin &&
1123 git update-ref -z --stdin <stdin &&
1124 git rev-parse $m >expect &&
1125 git rev-parse $b >actual &&
1126 test_cmp expect actual &&
1127 git update-ref -d $b
1128 '
1129
1130 test_expect_success 'stdin -z update ref creates with empty old value' '
1131 printf $F "update $b" "$m" "" >stdin &&
1132 git update-ref -z --stdin <stdin &&
1133 git rev-parse $m >expect &&
1134 git rev-parse $b >actual &&
1135 test_cmp expect actual
1136 '
1137
1138 test_expect_success 'stdin -z create ref works with path with space to blob' '
1139 printf $F "create refs/blobs/pws" "$m:$pws" >stdin &&
1140 git update-ref -z --stdin <stdin &&
1141 git rev-parse "$m:$pws" >expect &&
1142 git rev-parse refs/blobs/pws >actual &&
1143 test_cmp expect actual &&
1144 git update-ref -d refs/blobs/pws
1145 '
1146
1147 test_expect_success 'stdin -z update ref fails with wrong old value' '
1148 printf $F "update $c" "$m" "$m~1" >stdin &&
1149 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1150 grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
1151 test_must_fail git rev-parse --verify -q $c
1152 '
1153
1154 test_expect_success 'stdin -z update ref fails with bad old value' '
1155 printf $F "update $c" "$m" "does-not-exist" >stdin &&
1156 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1157 grep "fatal: update $c: invalid <oldvalue>: does-not-exist" err &&
1158 test_must_fail git rev-parse --verify -q $c
1159 '
1160
1161 test_expect_success 'stdin -z create ref fails when ref exists' '
1162 git update-ref $c $m &&
1163 git rev-parse "$c" >expect &&
1164 printf $F "create $c" "$m~1" >stdin &&
1165 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1166 grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
1167 git rev-parse "$c" >actual &&
1168 test_cmp expect actual
1169 '
1170
1171 test_expect_success 'stdin -z create ref fails with bad new value' '
1172 git update-ref -d "$c" &&
1173 printf $F "create $c" "does-not-exist" >stdin &&
1174 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1175 grep "fatal: create $c: invalid <newvalue>: does-not-exist" err &&
1176 test_must_fail git rev-parse --verify -q $c
1177 '
1178
1179 test_expect_success 'stdin -z create ref fails with empty new value' '
1180 printf $F "create $c" "" >stdin &&
1181 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1182 grep "fatal: create $c: missing <newvalue>" err &&
1183 test_must_fail git rev-parse --verify -q $c
1184 '
1185
1186 test_expect_success 'stdin -z update ref works with right old value' '
1187 printf $F "update $b" "$m~1" "$m" >stdin &&
1188 git update-ref -z --stdin <stdin &&
1189 git rev-parse $m~1 >expect &&
1190 git rev-parse $b >actual &&
1191 test_cmp expect actual
1192 '
1193
1194 test_expect_success 'stdin -z delete ref fails with wrong old value' '
1195 printf $F "delete $a" "$m~1" >stdin &&
1196 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1197 grep "fatal: cannot lock ref '"'"'$a'"'"'" err &&
1198 git rev-parse $m >expect &&
1199 git rev-parse $a >actual &&
1200 test_cmp expect actual
1201 '
1202
1203 test_expect_success 'stdin -z delete ref fails with zero old value' '
1204 printf $F "delete $a" "$Z" >stdin &&
1205 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1206 grep "fatal: delete $a: zero <oldvalue>" err &&
1207 git rev-parse $m >expect &&
1208 git rev-parse $a >actual &&
1209 test_cmp expect actual
1210 '
1211
1212 test_expect_success 'stdin -z update symref works option no-deref' '
1213 git symbolic-ref TESTSYMREF $b &&
1214 printf $F "option no-deref" "update TESTSYMREF" "$a" "$b" >stdin &&
1215 git update-ref -z --stdin <stdin &&
1216 git rev-parse TESTSYMREF >expect &&
1217 git rev-parse $a >actual &&
1218 test_cmp expect actual &&
1219 git rev-parse $m~1 >expect &&
1220 git rev-parse $b >actual &&
1221 test_cmp expect actual
1222 '
1223
1224 test_expect_success 'stdin -z delete symref works option no-deref' '
1225 git symbolic-ref TESTSYMREF $b &&
1226 printf $F "option no-deref" "delete TESTSYMREF" "$b" >stdin &&
1227 git update-ref -z --stdin <stdin &&
1228 test_must_fail git rev-parse --verify -q TESTSYMREF &&
1229 git rev-parse $m~1 >expect &&
1230 git rev-parse $b >actual &&
1231 test_cmp expect actual
1232 '
1233
1234 test_expect_success 'stdin -z delete ref works with right old value' '
1235 printf $F "delete $b" "$m~1" >stdin &&
1236 git update-ref -z --stdin <stdin &&
1237 test_must_fail git rev-parse --verify -q $b
1238 '
1239
1240 test_expect_success 'stdin -z update/create/verify combination works' '
1241 printf $F "update $a" "$m" "" "create $b" "$m" "verify $c" "" >stdin &&
1242 git update-ref -z --stdin <stdin &&
1243 git rev-parse $m >expect &&
1244 git rev-parse $a >actual &&
1245 test_cmp expect actual &&
1246 git rev-parse $b >actual &&
1247 test_cmp expect actual &&
1248 test_must_fail git rev-parse --verify -q $c
1249 '
1250
1251 test_expect_success 'stdin -z verify succeeds for correct value' '
1252 git rev-parse $m >expect &&
1253 printf $F "verify $m" "$m" >stdin &&
1254 git update-ref -z --stdin <stdin &&
1255 git rev-parse $m >actual &&
1256 test_cmp expect actual
1257 '
1258
1259 test_expect_success 'stdin -z verify succeeds for missing reference' '
1260 printf $F "verify refs/heads/missing" "$Z" >stdin &&
1261 git update-ref -z --stdin <stdin &&
1262 test_must_fail git rev-parse --verify -q refs/heads/missing
1263 '
1264
1265 test_expect_success 'stdin -z verify treats no value as missing' '
1266 printf $F "verify refs/heads/missing" "" >stdin &&
1267 git update-ref -z --stdin <stdin &&
1268 test_must_fail git rev-parse --verify -q refs/heads/missing
1269 '
1270
1271 test_expect_success 'stdin -z verify fails for wrong value' '
1272 git rev-parse $m >expect &&
1273 printf $F "verify $m" "$m~1" >stdin &&
1274 test_must_fail git update-ref -z --stdin <stdin &&
1275 git rev-parse $m >actual &&
1276 test_cmp expect actual
1277 '
1278
1279 test_expect_success 'stdin -z verify fails for mistaken null value' '
1280 git rev-parse $m >expect &&
1281 printf $F "verify $m" "$Z" >stdin &&
1282 test_must_fail git update-ref -z --stdin <stdin &&
1283 git rev-parse $m >actual &&
1284 test_cmp expect actual
1285 '
1286
1287 test_expect_success 'stdin -z verify fails for mistaken empty value' '
1288 M=$(git rev-parse $m) &&
1289 test_when_finished "git update-ref $m $M" &&
1290 git rev-parse $m >expect &&
1291 printf $F "verify $m" "" >stdin &&
1292 test_must_fail git update-ref -z --stdin <stdin &&
1293 git rev-parse $m >actual &&
1294 test_cmp expect actual
1295 '
1296
1297 test_expect_success 'stdin -z update refs works with identity updates' '
1298 printf $F "update $a" "$m" "$m" "update $b" "$m" "$m" "update $c" "$Z" "" >stdin &&
1299 git update-ref -z --stdin <stdin &&
1300 git rev-parse $m >expect &&
1301 git rev-parse $a >actual &&
1302 test_cmp expect actual &&
1303 git rev-parse $b >actual &&
1304 test_cmp expect actual &&
1305 test_must_fail git rev-parse --verify -q $c
1306 '
1307
1308 test_expect_success 'stdin -z update refs fails with wrong old value' '
1309 git update-ref $c $m &&
1310 printf $F "update $a" "$m" "$m" "update $b" "$m" "$m" "update $c" "$m" "$Z" >stdin &&
1311 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1312 grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
1313 git rev-parse $m >expect &&
1314 git rev-parse $a >actual &&
1315 test_cmp expect actual &&
1316 git rev-parse $b >actual &&
1317 test_cmp expect actual &&
1318 git rev-parse $c >actual &&
1319 test_cmp expect actual
1320 '
1321
1322 test_expect_success 'stdin -z delete refs works with packed and loose refs' '
1323 git pack-refs --all &&
1324 git update-ref $c $m~1 &&
1325 printf $F "delete $a" "$m" "update $b" "$Z" "$m" "update $c" "" "$m~1" >stdin &&
1326 git update-ref -z --stdin <stdin &&
1327 test_must_fail git rev-parse --verify -q $a &&
1328 test_must_fail git rev-parse --verify -q $b &&
1329 test_must_fail git rev-parse --verify -q $c
1330 '
1331
1332 test_expect_success 'fails with duplicate HEAD update' '
1333 git branch target1 $A &&
1334 git checkout target1 &&
1335 cat >stdin <<-EOF &&
1336 update refs/heads/target1 $C
1337 option no-deref
1338 update HEAD $B
1339 EOF
1340 test_must_fail git update-ref --stdin <stdin 2>err &&
1341 test_grep "fatal: multiple updates for '\''HEAD'\'' (including one via its referent .refs/heads/target1.) are not allowed" err &&
1342 echo "refs/heads/target1" >expect &&
1343 git symbolic-ref HEAD >actual &&
1344 test_cmp expect actual &&
1345 echo "$A" >expect &&
1346 git rev-parse refs/heads/target1 >actual &&
1347 test_cmp expect actual
1348 '
1349
1350 test_expect_success 'fails with duplicate ref update via symref' '
1351 git branch target2 $A &&
1352 git symbolic-ref refs/heads/symref2 refs/heads/target2 &&
1353 cat >stdin <<-EOF &&
1354 update refs/heads/target2 $C
1355 update refs/heads/symref2 $B
1356 EOF
1357 test_must_fail git update-ref --stdin <stdin 2>err &&
1358 test_grep "fatal: multiple updates for '\''refs/heads/target2'\'' (including one via symref .refs/heads/symref2.) are not allowed" err &&
1359 echo "refs/heads/target2" >expect &&
1360 git symbolic-ref refs/heads/symref2 >actual &&
1361 test_cmp expect actual &&
1362 echo "$A" >expect &&
1363 git rev-parse refs/heads/target2 >actual &&
1364 test_cmp expect actual
1365 '
1366
1367 test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction creating branches does not burst open file limit' '
1368 (
1369 for i in $(test_seq 33)
1370 do
1371 echo "create refs/heads/$i HEAD" || exit 1
1372 done >large_input &&
1373 run_with_limited_open_files git update-ref --stdin <large_input &&
1374 git rev-parse --verify -q refs/heads/33
1375 )
1376 '
1377
1378 test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction deleting branches does not burst open file limit' '
1379 (
1380 for i in $(test_seq 33)
1381 do
1382 echo "delete refs/heads/$i HEAD" || exit 1
1383 done >large_input &&
1384 run_with_limited_open_files git update-ref --stdin <large_input &&
1385 test_must_fail git rev-parse --verify -q refs/heads/33
1386 )
1387 '
1388
1389 test_expect_success 'handle per-worktree refs in refs/bisect' '
1390 git commit --allow-empty -m "initial commit" &&
1391 git worktree add -b branch worktree &&
1392 (
1393 cd worktree &&
1394 git commit --allow-empty -m "test commit" &&
1395 git for-each-ref >for-each-ref.out &&
1396 ! grep refs/bisect for-each-ref.out &&
1397 git update-ref refs/bisect/something HEAD &&
1398 git rev-parse refs/bisect/something >../worktree-head &&
1399 git for-each-ref | grep refs/bisect/something
1400 ) &&
1401 git show-ref >actual &&
1402 ! grep 'refs/bisect' actual &&
1403 test_must_fail git rev-parse refs/bisect/something &&
1404 git update-ref refs/bisect/something HEAD &&
1405 git rev-parse refs/bisect/something >main-head &&
1406 ! test_cmp main-head worktree-head
1407 '
1408
1409 test_expect_success 'transaction handles empty commit' '
1410 cat >stdin <<-EOF &&
1411 start
1412 prepare
1413 commit
1414 EOF
1415 git update-ref --stdin <stdin >actual &&
1416 printf "%s: ok\n" start prepare commit >expect &&
1417 test_cmp expect actual
1418 '
1419
1420 test_expect_success 'transaction handles empty commit with missing prepare' '
1421 cat >stdin <<-EOF &&
1422 start
1423 commit
1424 EOF
1425 git update-ref --stdin <stdin >actual &&
1426 printf "%s: ok\n" start commit >expect &&
1427 test_cmp expect actual
1428 '
1429
1430 test_expect_success 'transaction handles sole commit' '
1431 cat >stdin <<-EOF &&
1432 commit
1433 EOF
1434 git update-ref --stdin <stdin >actual &&
1435 printf "%s: ok\n" commit >expect &&
1436 test_cmp expect actual
1437 '
1438
1439 test_expect_success 'transaction handles empty abort' '
1440 cat >stdin <<-EOF &&
1441 start
1442 prepare
1443 abort
1444 EOF
1445 git update-ref --stdin <stdin >actual &&
1446 printf "%s: ok\n" start prepare abort >expect &&
1447 test_cmp expect actual
1448 '
1449
1450 test_expect_success 'transaction exits on multiple aborts' '
1451 cat >stdin <<-EOF &&
1452 abort
1453 abort
1454 EOF
1455 test_must_fail git update-ref --stdin <stdin >actual 2>err &&
1456 printf "%s: ok\n" abort >expect &&
1457 test_cmp expect actual &&
1458 grep "fatal: transaction is closed" err
1459 '
1460
1461 test_expect_success 'transaction exits on start after prepare' '
1462 cat >stdin <<-EOF &&
1463 prepare
1464 start
1465 EOF
1466 test_must_fail git update-ref --stdin <stdin 2>err >actual &&
1467 printf "%s: ok\n" prepare >expect &&
1468 test_cmp expect actual &&
1469 grep "fatal: prepared transactions can only be closed" err
1470 '
1471
1472 test_expect_success 'transaction handles empty abort with missing prepare' '
1473 cat >stdin <<-EOF &&
1474 start
1475 abort
1476 EOF
1477 git update-ref --stdin <stdin >actual &&
1478 printf "%s: ok\n" start abort >expect &&
1479 test_cmp expect actual
1480 '
1481
1482 test_expect_success 'transaction handles sole abort' '
1483 cat >stdin <<-EOF &&
1484 abort
1485 EOF
1486 git update-ref --stdin <stdin >actual &&
1487 printf "%s: ok\n" abort >expect &&
1488 test_cmp expect actual
1489 '
1490
1491 test_expect_success 'transaction can handle commit' '
1492 cat >stdin <<-EOF &&
1493 start
1494 create $a HEAD
1495 commit
1496 EOF
1497 git update-ref --stdin <stdin >actual &&
1498 printf "%s: ok\n" start commit >expect &&
1499 test_cmp expect actual &&
1500 git rev-parse HEAD >expect &&
1501 git rev-parse $a >actual &&
1502 test_cmp expect actual
1503 '
1504
1505 test_expect_success 'transaction can handle abort' '
1506 cat >stdin <<-EOF &&
1507 start
1508 create $b HEAD
1509 abort
1510 EOF
1511 git update-ref --stdin <stdin >actual &&
1512 printf "%s: ok\n" start abort >expect &&
1513 test_cmp expect actual &&
1514 test_must_fail git show-ref --verify -q $b
1515 '
1516
1517 test_expect_success 'transaction aborts by default' '
1518 cat >stdin <<-EOF &&
1519 start
1520 create $b HEAD
1521 EOF
1522 git update-ref --stdin <stdin >actual &&
1523 printf "%s: ok\n" start >expect &&
1524 test_cmp expect actual &&
1525 test_must_fail git show-ref --verify -q $b
1526 '
1527
1528 test_expect_success 'transaction with prepare aborts by default' '
1529 cat >stdin <<-EOF &&
1530 start
1531 create $b HEAD
1532 prepare
1533 EOF
1534 git update-ref --stdin <stdin >actual &&
1535 printf "%s: ok\n" start prepare >expect &&
1536 test_cmp expect actual &&
1537 test_must_fail git show-ref --verify -q $b
1538 '
1539
1540 test_expect_success 'transaction can commit multiple times' '
1541 cat >stdin <<-EOF &&
1542 start
1543 create refs/heads/branch-1 $A
1544 commit
1545 start
1546 create refs/heads/branch-2 $B
1547 commit
1548 EOF
1549 git update-ref --stdin <stdin >actual &&
1550 printf "%s: ok\n" start commit start commit >expect &&
1551 test_cmp expect actual &&
1552 echo "$A" >expect &&
1553 git rev-parse refs/heads/branch-1 >actual &&
1554 test_cmp expect actual &&
1555 echo "$B" >expect &&
1556 git rev-parse refs/heads/branch-2 >actual &&
1557 test_cmp expect actual
1558 '
1559
1560 test_expect_success 'transaction can create and delete' '
1561 cat >stdin <<-EOF &&
1562 start
1563 create refs/heads/create-and-delete $A
1564 commit
1565 start
1566 delete refs/heads/create-and-delete $A
1567 commit
1568 EOF
1569 git update-ref --stdin <stdin >actual &&
1570 printf "%s: ok\n" start commit start commit >expect &&
1571 test_cmp expect actual &&
1572 test_must_fail git show-ref --verify refs/heads/create-and-delete
1573 '
1574
1575 test_expect_success 'transaction can commit after abort' '
1576 cat >stdin <<-EOF &&
1577 start
1578 create refs/heads/abort $A
1579 abort
1580 start
1581 create refs/heads/abort $A
1582 commit
1583 EOF
1584 git update-ref --stdin <stdin >actual &&
1585 printf "%s: ok\n" start abort start commit >expect &&
1586 echo "$A" >expect &&
1587 git rev-parse refs/heads/abort >actual &&
1588 test_cmp expect actual
1589 '
1590
1591 test_expect_success 'transaction cannot restart ongoing transaction' '
1592 cat >stdin <<-EOF &&
1593 start
1594 create refs/heads/restart $A
1595 start
1596 commit
1597 EOF
1598 test_must_fail git update-ref --stdin <stdin >actual &&
1599 printf "%s: ok\n" start >expect &&
1600 test_cmp expect actual &&
1601 test_must_fail git show-ref --verify refs/heads/restart
1602 '
1603
1604 test_expect_success PIPE 'transaction flushes status updates' '
1605 mkfifo in out &&
1606 (git update-ref --stdin <in >out &) &&
1607
1608 exec 9>in &&
1609 exec 8<out &&
1610 test_when_finished "exec 9>&-" &&
1611 test_when_finished "exec 8<&-" &&
1612
1613 echo "start" >&9 &&
1614 echo "start: ok" >expected &&
1615 read line <&8 &&
1616 echo "$line" >actual &&
1617 test_cmp expected actual &&
1618
1619 echo "create refs/heads/flush $A" >&9 &&
1620
1621 echo prepare >&9 &&
1622 echo "prepare: ok" >expected &&
1623 read line <&8 &&
1624 echo "$line" >actual &&
1625 test_cmp expected actual &&
1626
1627 # This must now fail given that we have locked the ref.
1628 test_must_fail git update-ref refs/heads/flush $B 2>stderr &&
1629 grep "fatal: update_ref failed for ref ${SQ}refs/heads/flush${SQ}: cannot lock ref" stderr &&
1630
1631 echo commit >&9 &&
1632 echo "commit: ok" >expected &&
1633 read line <&8 &&
1634 echo "$line" >actual &&
1635 test_cmp expected actual
1636 '
1637
1638 test_expect_success 'directory not created deleting packed ref' '
1639 git branch d1/d2/r1 HEAD &&
1640 git pack-refs --all &&
1641 test_path_is_missing .git/refs/heads/d1/d2 &&
1642 git update-ref -d refs/heads/d1/d2/r1 &&
1643 test_path_is_missing .git/refs/heads/d1/d2 &&
1644 test_path_is_missing .git/refs/heads/d1
1645 '
1646
1647 test_done