pathspec: allow querying for attributes
[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=$_z40
10
11 m=refs/heads/master
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         create_test_commits "" &&
31         mkdir $bare &&
32         cd $bare &&
33         git init --bare &&
34         create_test_commits "bare" &&
35         cd -
36 '
37
38 test_expect_success \
39         "create $m" \
40         "git update-ref $m $A &&
41          test $A"' = $(cat .git/'"$m"')'
42 test_expect_success \
43         "create $m" \
44         "git update-ref $m $B $A &&
45          test $B"' = $(cat .git/'"$m"')'
46 test_expect_success "fail to delete $m with stale ref" '
47         test_must_fail git update-ref -d $m $A &&
48         test $B = "$(cat .git/$m)"
49 '
50 test_expect_success "delete $m" '
51         git update-ref -d $m $B &&
52         ! test -f .git/$m
53 '
54 rm -f .git/$m
55
56 test_expect_success "delete $m without oldvalue verification" "
57         git update-ref $m $A &&
58         test $A = \$(cat .git/$m) &&
59         git update-ref -d $m &&
60         ! test -f .git/$m
61 "
62 rm -f .git/$m
63
64 test_expect_success \
65         "fail to create $n" \
66         "touch .git/$n_dir &&
67          test_must_fail git update-ref $n $A >out 2>err"
68 rm -f .git/$n_dir out err
69
70 test_expect_success \
71         "create $m (by HEAD)" \
72         "git update-ref HEAD $A &&
73          test $A"' = $(cat .git/'"$m"')'
74 test_expect_success \
75         "create $m (by HEAD)" \
76         "git update-ref HEAD $B $A &&
77          test $B"' = $(cat .git/'"$m"')'
78 test_expect_success "fail to delete $m (by HEAD) with stale ref" '
79         test_must_fail git update-ref -d HEAD $A &&
80         test $B = $(cat .git/$m)
81 '
82 test_expect_success "delete $m (by HEAD)" '
83         git update-ref -d HEAD $B &&
84         ! test -f .git/$m
85 '
86 rm -f .git/$m
87
88 test_expect_success "deleting current branch adds message to HEAD's log" '
89         git update-ref $m $A &&
90         git symbolic-ref HEAD $m &&
91         git update-ref -m delete-$m -d $m &&
92         ! test -f .git/$m &&
93         grep "delete-$m$" .git/logs/HEAD
94 '
95 rm -f .git/$m
96
97 test_expect_success "deleting by HEAD adds message to HEAD's log" '
98         git update-ref $m $A &&
99         git symbolic-ref HEAD $m &&
100         git update-ref -m delete-by-head -d HEAD &&
101         ! test -f .git/$m &&
102         grep "delete-by-head$" .git/logs/HEAD
103 '
104 rm -f .git/$m
105
106 test_expect_success 'update-ref does not create reflogs by default' '
107         test_when_finished "git update-ref -d $outside" &&
108         git update-ref $outside $A &&
109         git rev-parse $A >expect &&
110         git rev-parse $outside >actual &&
111         test_cmp expect actual &&
112         test_must_fail git reflog exists $outside
113 '
114
115 test_expect_success 'update-ref creates reflogs with --create-reflog' '
116         test_when_finished "git update-ref -d $outside" &&
117         git update-ref --create-reflog $outside $A &&
118         git rev-parse $A >expect &&
119         git rev-parse $outside >actual &&
120         test_cmp expect actual &&
121         git reflog exists $outside
122 '
123
124 test_expect_success 'creates no reflog in bare repository' '
125         git -C $bare update-ref $m $bareA &&
126         git -C $bare rev-parse $bareA >expect &&
127         git -C $bare rev-parse $m >actual &&
128         test_cmp expect actual &&
129         test_must_fail git -C $bare reflog exists $m
130 '
131
132 test_expect_success 'core.logAllRefUpdates=true creates reflog in bare repository' '
133         test_when_finished "git -C $bare config --unset core.logAllRefUpdates && \
134                 rm $bare/logs/$m" &&
135         git -C $bare config core.logAllRefUpdates true &&
136         git -C $bare update-ref $m $bareB &&
137         git -C $bare rev-parse $bareB >expect &&
138         git -C $bare rev-parse $m >actual &&
139         test_cmp expect actual &&
140         git -C $bare reflog exists $m
141 '
142
143 test_expect_success 'core.logAllRefUpdates=true does not create reflog by default' '
144         test_config core.logAllRefUpdates true &&
145         test_when_finished "git update-ref -d $outside" &&
146         git update-ref $outside $A &&
147         git rev-parse $A >expect &&
148         git rev-parse $outside >actual &&
149         test_cmp expect actual &&
150         test_must_fail git reflog exists $outside
151 '
152
153 test_expect_success 'core.logAllRefUpdates=always creates reflog by default' '
154         test_config core.logAllRefUpdates always &&
155         test_when_finished "git update-ref -d $outside" &&
156         git update-ref $outside $A &&
157         git rev-parse $A >expect &&
158         git rev-parse $outside >actual &&
159         test_cmp expect actual &&
160         git reflog exists $outside
161 '
162
163 test_expect_success 'core.logAllRefUpdates=always creates no reflog for ORIG_HEAD' '
164         test_config core.logAllRefUpdates always &&
165         git update-ref ORIG_HEAD $A &&
166         test_must_fail git reflog exists ORIG_HEAD
167 '
168
169 test_expect_success '--no-create-reflog overrides core.logAllRefUpdates=always' '
170         test_config core.logAllRefUpdates true &&
171         test_when_finished "git update-ref -d $outside" &&
172         git update-ref --no-create-reflog $outside $A &&
173         git rev-parse $A >expect &&
174         git rev-parse $outside >actual &&
175         test_cmp expect actual &&
176         test_must_fail git reflog exists $outside
177 '
178
179 test_expect_success \
180         "create $m (by HEAD)" \
181         "git update-ref HEAD $A &&
182          test $A"' = $(cat .git/'"$m"')'
183 test_expect_success \
184         "pack refs" \
185         "git pack-refs --all"
186 test_expect_success \
187         "move $m (by HEAD)" \
188         "git update-ref HEAD $B $A &&
189          test $B"' = $(cat .git/'"$m"')'
190 test_expect_success "delete $m (by HEAD) should remove both packed and loose $m" '
191         git update-ref -d HEAD $B &&
192         ! grep "$m" .git/packed-refs &&
193         ! test -f .git/$m
194 '
195 rm -f .git/$m
196
197 cp -f .git/HEAD .git/HEAD.orig
198 test_expect_success "delete symref without dereference" '
199         git update-ref --no-deref -d HEAD &&
200         ! test -f .git/HEAD
201 '
202 cp -f .git/HEAD.orig .git/HEAD
203
204 test_expect_success "delete symref without dereference when the referred ref is packed" '
205         echo foo >foo.c &&
206         git add foo.c &&
207         git commit -m foo &&
208         git pack-refs --all &&
209         git update-ref --no-deref -d HEAD &&
210         ! test -f .git/HEAD
211 '
212 cp -f .git/HEAD.orig .git/HEAD
213 git update-ref -d $m
214
215 test_expect_success 'update-ref -d is not confused by self-reference' '
216         git symbolic-ref refs/heads/self refs/heads/self &&
217         test_when_finished "rm -f .git/refs/heads/self" &&
218         test_path_is_file .git/refs/heads/self &&
219         test_must_fail git update-ref -d refs/heads/self &&
220         test_path_is_file .git/refs/heads/self
221 '
222
223 test_expect_success 'update-ref --no-deref -d can delete 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         git update-ref --no-deref -d refs/heads/self &&
228         test_path_is_missing .git/refs/heads/self
229 '
230
231 test_expect_success 'update-ref --no-deref -d can delete reference to bad ref' '
232         >.git/refs/heads/bad &&
233         test_when_finished "rm -f .git/refs/heads/bad" &&
234         git symbolic-ref refs/heads/ref-to-bad refs/heads/bad &&
235         test_when_finished "rm -f .git/refs/heads/ref-to-bad" &&
236         test_path_is_file .git/refs/heads/ref-to-bad &&
237         git update-ref --no-deref -d refs/heads/ref-to-bad &&
238         test_path_is_missing .git/refs/heads/ref-to-bad
239 '
240
241 test_expect_success '(not) create HEAD with old sha1' "
242         test_must_fail git update-ref HEAD $A $B
243 "
244 test_expect_success "(not) prior created .git/$m" "
245         ! test -f .git/$m
246 "
247 rm -f .git/$m
248
249 test_expect_success \
250         "create HEAD" \
251         "git update-ref HEAD $A"
252 test_expect_success '(not) change HEAD with wrong SHA1' "
253         test_must_fail git update-ref HEAD $B $Z
254 "
255 test_expect_success "(not) changed .git/$m" "
256         ! test $B"' = $(cat .git/'"$m"')
257 '
258 rm -f .git/$m
259
260 rm -f .git/logs/refs/heads/master
261 test_expect_success \
262         "create $m (logged by touch)" \
263         'GIT_COMMITTER_DATE="2005-05-26 23:30" \
264          git update-ref --create-reflog HEAD '"$A"' -m "Initial Creation" &&
265          test '"$A"' = $(cat .git/'"$m"')'
266 test_expect_success \
267         "update $m (logged by touch)" \
268         'GIT_COMMITTER_DATE="2005-05-26 23:31" \
269          git update-ref HEAD'" $B $A "'-m "Switch" &&
270          test '"$B"' = $(cat .git/'"$m"')'
271 test_expect_success \
272         "set $m (logged by touch)" \
273         'GIT_COMMITTER_DATE="2005-05-26 23:41" \
274          git update-ref HEAD'" $A &&
275          test $A"' = $(cat .git/'"$m"')'
276
277 test_expect_success "empty directory removal" '
278         git branch d1/d2/r1 HEAD &&
279         git branch d1/r2 HEAD &&
280         test -f .git/refs/heads/d1/d2/r1 &&
281         test -f .git/logs/refs/heads/d1/d2/r1 &&
282         git branch -d d1/d2/r1 &&
283         ! test -e .git/refs/heads/d1/d2 &&
284         ! test -e .git/logs/refs/heads/d1/d2 &&
285         test -f .git/refs/heads/d1/r2 &&
286         test -f .git/logs/refs/heads/d1/r2
287 '
288
289 test_expect_success "symref empty directory removal" '
290         git branch e1/e2/r1 HEAD &&
291         git branch e1/r2 HEAD &&
292         git checkout e1/e2/r1 &&
293         test_when_finished "git checkout master" &&
294         test -f .git/refs/heads/e1/e2/r1 &&
295         test -f .git/logs/refs/heads/e1/e2/r1 &&
296         git update-ref -d HEAD &&
297         ! test -e .git/refs/heads/e1/e2 &&
298         ! test -e .git/logs/refs/heads/e1/e2 &&
299         test -f .git/refs/heads/e1/r2 &&
300         test -f .git/logs/refs/heads/e1/r2 &&
301         test -f .git/logs/HEAD
302 '
303
304 cat >expect <<EOF
305 $Z $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000       Initial Creation
306 $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150260 +0000       Switch
307 $B $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150860 +0000
308 EOF
309 test_expect_success \
310         "verifying $m's log" \
311         "test_cmp expect .git/logs/$m"
312 rm -rf .git/$m .git/logs expect
313
314 test_expect_success \
315         'enable core.logAllRefUpdates' \
316         'git config core.logAllRefUpdates true &&
317          test true = $(git config --bool --get core.logAllRefUpdates)'
318
319 test_expect_success \
320         "create $m (logged by config)" \
321         'GIT_COMMITTER_DATE="2005-05-26 23:32" \
322          git update-ref HEAD'" $A "'-m "Initial Creation" &&
323          test '"$A"' = $(cat .git/'"$m"')'
324 test_expect_success \
325         "update $m (logged by config)" \
326         'GIT_COMMITTER_DATE="2005-05-26 23:33" \
327          git update-ref HEAD'" $B $A "'-m "Switch" &&
328          test '"$B"' = $(cat .git/'"$m"')'
329 test_expect_success \
330         "set $m (logged by config)" \
331         'GIT_COMMITTER_DATE="2005-05-26 23:43" \
332          git update-ref HEAD '"$A &&
333          test $A"' = $(cat .git/'"$m"')'
334
335 cat >expect <<EOF
336 $Z $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150320 +0000       Initial Creation
337 $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 +0000       Switch
338 $B $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 +0000
339 EOF
340 test_expect_success \
341         "verifying $m's log" \
342         'test_cmp expect .git/logs/$m'
343 rm -f .git/$m .git/logs/$m expect
344
345 git update-ref $m $D
346 cat >.git/logs/$m <<EOF
347 0000000000000000000000000000000000000000 $C $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150320 -0500
348 $C $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150350 -0500
349 $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 -0500
350 $F $Z $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150680 -0500
351 $Z $E $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 -0500
352 EOF
353
354 ed="Thu, 26 May 2005 18:32:00 -0500"
355 gd="Thu, 26 May 2005 18:33:00 -0500"
356 ld="Thu, 26 May 2005 18:43:00 -0500"
357 test_expect_success \
358         'Query "master@{May 25 2005}" (before history)' \
359         'rm -f o e &&
360          git rev-parse --verify "master@{May 25 2005}" >o 2>e &&
361          test '"$C"' = $(cat o) &&
362          test "warning: Log for '\'master\'' only goes back to $ed." = "$(cat e)"'
363 test_expect_success \
364         "Query master@{2005-05-25} (before history)" \
365         'rm -f o e &&
366          git rev-parse --verify master@{2005-05-25} >o 2>e &&
367          test '"$C"' = $(cat o) &&
368          echo test "warning: Log for '\'master\'' only goes back to $ed." = "$(cat e)"'
369 test_expect_success \
370         'Query "master@{May 26 2005 23:31:59}" (1 second before history)' \
371         'rm -f o e &&
372          git rev-parse --verify "master@{May 26 2005 23:31:59}" >o 2>e &&
373          test '"$C"' = $(cat o) &&
374          test "warning: Log for '\''master'\'' only goes back to $ed." = "$(cat e)"'
375 test_expect_success \
376         'Query "master@{May 26 2005 23:32:00}" (exactly history start)' \
377         'rm -f o e &&
378          git rev-parse --verify "master@{May 26 2005 23:32:00}" >o 2>e &&
379          test '"$C"' = $(cat o) &&
380          test "" = "$(cat e)"'
381 test_expect_success \
382         'Query "master@{May 26 2005 23:32:30}" (first non-creation change)' \
383         'rm -f o e &&
384          git rev-parse --verify "master@{May 26 2005 23:32:30}" >o 2>e &&
385          test '"$A"' = $(cat o) &&
386          test "" = "$(cat e)"'
387 test_expect_success \
388         'Query "master@{2005-05-26 23:33:01}" (middle of history with gap)' \
389         'rm -f o e &&
390          git rev-parse --verify "master@{2005-05-26 23:33:01}" >o 2>e &&
391          test '"$B"' = $(cat o) &&
392          test "warning: Log for ref '"$m has gap after $gd"'." = "$(cat e)"'
393 test_expect_success \
394         'Query "master@{2005-05-26 23:38:00}" (middle of history)' \
395         'rm -f o e &&
396          git rev-parse --verify "master@{2005-05-26 23:38:00}" >o 2>e &&
397          test '"$Z"' = $(cat o) &&
398          test "" = "$(cat e)"'
399 test_expect_success \
400         'Query "master@{2005-05-26 23:43:00}" (exact end of history)' \
401         'rm -f o e &&
402          git rev-parse --verify "master@{2005-05-26 23:43:00}" >o 2>e &&
403          test '"$E"' = $(cat o) &&
404          test "" = "$(cat e)"'
405 test_expect_success \
406         'Query "master@{2005-05-28}" (past end of history)' \
407         'rm -f o e &&
408          git rev-parse --verify "master@{2005-05-28}" >o 2>e &&
409          test '"$D"' = $(cat o) &&
410          test "warning: Log for ref '"$m unexpectedly ended on $ld"'." = "$(cat e)"'
411
412
413 rm -f .git/$m .git/logs/$m expect
414
415 test_expect_success \
416     'creating initial files' \
417     'echo TEST >F &&
418      git add F &&
419          GIT_AUTHOR_DATE="2005-05-26 23:30" \
420          GIT_COMMITTER_DATE="2005-05-26 23:30" git commit -m add -a &&
421          h_TEST=$(git rev-parse --verify HEAD) &&
422          echo The other day this did not work. >M &&
423          echo And then Bob told me how to fix it. >>M &&
424          echo OTHER >F &&
425          GIT_AUTHOR_DATE="2005-05-26 23:41" \
426          GIT_COMMITTER_DATE="2005-05-26 23:41" git commit -F M -a &&
427          h_OTHER=$(git rev-parse --verify HEAD) &&
428          GIT_AUTHOR_DATE="2005-05-26 23:44" \
429          GIT_COMMITTER_DATE="2005-05-26 23:44" git commit --amend &&
430          h_FIXED=$(git rev-parse --verify HEAD) &&
431          echo Merged initial commit and a later commit. >M &&
432          echo $h_TEST >.git/MERGE_HEAD &&
433          GIT_AUTHOR_DATE="2005-05-26 23:45" \
434          GIT_COMMITTER_DATE="2005-05-26 23:45" git commit -F M &&
435          h_MERGED=$(git rev-parse --verify HEAD) &&
436          rm -f M'
437
438 cat >expect <<EOF
439 $Z $h_TEST $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000  commit (initial): add
440 $h_TEST $h_OTHER $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150860 +0000    commit: The other day this did not work.
441 $h_OTHER $h_FIXED $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117151040 +0000   commit (amend): The other day this did not work.
442 $h_FIXED $h_MERGED $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117151100 +0000  commit (merge): Merged initial commit and a later commit.
443 EOF
444 test_expect_success \
445         'git commit logged updates' \
446         "test_cmp expect .git/logs/$m"
447 unset h_TEST h_OTHER h_FIXED h_MERGED
448
449 test_expect_success \
450         'git cat-file blob master:F (expect OTHER)' \
451         'test OTHER = $(git cat-file blob master:F)'
452 test_expect_success \
453         'git cat-file blob master@{2005-05-26 23:30}:F (expect TEST)' \
454         'test TEST = $(git cat-file blob "master@{2005-05-26 23:30}:F")'
455 test_expect_success \
456         'git cat-file blob master@{2005-05-26 23:42}:F (expect OTHER)' \
457         'test OTHER = $(git cat-file blob "master@{2005-05-26 23:42}:F")'
458
459 a=refs/heads/a
460 b=refs/heads/b
461 c=refs/heads/c
462 E='""'
463 F='%s\0'
464 pws='path with space'
465
466 test_expect_success 'stdin test setup' '
467         echo "$pws" >"$pws" &&
468         git add -- "$pws" &&
469         git commit -m "$pws"
470 '
471
472 test_expect_success '-z fails without --stdin' '
473         test_must_fail git update-ref -z $m $m $m 2>err &&
474         test_i18ngrep "usage: git update-ref" err
475 '
476
477 test_expect_success 'stdin works with no input' '
478         >stdin &&
479         git update-ref --stdin <stdin &&
480         git rev-parse --verify -q $m
481 '
482
483 test_expect_success 'stdin fails on empty line' '
484         echo "" >stdin &&
485         test_must_fail git update-ref --stdin <stdin 2>err &&
486         grep "fatal: empty command in input" err
487 '
488
489 test_expect_success 'stdin fails on only whitespace' '
490         echo " " >stdin &&
491         test_must_fail git update-ref --stdin <stdin 2>err &&
492         grep "fatal: whitespace before command:  " err
493 '
494
495 test_expect_success 'stdin fails on leading whitespace' '
496         echo " create $a $m" >stdin &&
497         test_must_fail git update-ref --stdin <stdin 2>err &&
498         grep "fatal: whitespace before command:  create $a $m" err
499 '
500
501 test_expect_success 'stdin fails on unknown command' '
502         echo "unknown $a" >stdin &&
503         test_must_fail git update-ref --stdin <stdin 2>err &&
504         grep "fatal: unknown command: unknown $a" err
505 '
506
507 test_expect_success 'stdin fails on unbalanced quotes' '
508         echo "create $a \"master" >stdin &&
509         test_must_fail git update-ref --stdin <stdin 2>err &&
510         grep "fatal: badly quoted argument: \\\"master" err
511 '
512
513 test_expect_success 'stdin fails on invalid escape' '
514         echo "create $a \"ma\zter\"" >stdin &&
515         test_must_fail git update-ref --stdin <stdin 2>err &&
516         grep "fatal: badly quoted argument: \\\"ma\\\\zter\\\"" err
517 '
518
519 test_expect_success 'stdin fails on junk after quoted argument' '
520         echo "create \"$a\"master" >stdin &&
521         test_must_fail git update-ref --stdin <stdin 2>err &&
522         grep "fatal: unexpected character after quoted argument: \\\"$a\\\"master" err
523 '
524
525 test_expect_success 'stdin fails create with no ref' '
526         echo "create " >stdin &&
527         test_must_fail git update-ref --stdin <stdin 2>err &&
528         grep "fatal: create: missing <ref>" err
529 '
530
531 test_expect_success 'stdin fails create with no new value' '
532         echo "create $a" >stdin &&
533         test_must_fail git update-ref --stdin <stdin 2>err &&
534         grep "fatal: create $a: missing <newvalue>" err
535 '
536
537 test_expect_success 'stdin fails create with too many arguments' '
538         echo "create $a $m $m" >stdin &&
539         test_must_fail git update-ref --stdin <stdin 2>err &&
540         grep "fatal: create $a: extra input:  $m" err
541 '
542
543 test_expect_success 'stdin fails update with no ref' '
544         echo "update " >stdin &&
545         test_must_fail git update-ref --stdin <stdin 2>err &&
546         grep "fatal: update: missing <ref>" err
547 '
548
549 test_expect_success 'stdin fails update with no new value' '
550         echo "update $a" >stdin &&
551         test_must_fail git update-ref --stdin <stdin 2>err &&
552         grep "fatal: update $a: missing <newvalue>" err
553 '
554
555 test_expect_success 'stdin fails update with too many arguments' '
556         echo "update $a $m $m $m" >stdin &&
557         test_must_fail git update-ref --stdin <stdin 2>err &&
558         grep "fatal: update $a: extra input:  $m" err
559 '
560
561 test_expect_success 'stdin fails delete with no ref' '
562         echo "delete " >stdin &&
563         test_must_fail git update-ref --stdin <stdin 2>err &&
564         grep "fatal: delete: missing <ref>" err
565 '
566
567 test_expect_success 'stdin fails delete with too many arguments' '
568         echo "delete $a $m $m" >stdin &&
569         test_must_fail git update-ref --stdin <stdin 2>err &&
570         grep "fatal: delete $a: extra input:  $m" err
571 '
572
573 test_expect_success 'stdin fails verify with too many arguments' '
574         echo "verify $a $m $m" >stdin &&
575         test_must_fail git update-ref --stdin <stdin 2>err &&
576         grep "fatal: verify $a: extra input:  $m" err
577 '
578
579 test_expect_success 'stdin fails option with unknown name' '
580         echo "option unknown" >stdin &&
581         test_must_fail git update-ref --stdin <stdin 2>err &&
582         grep "fatal: option unknown: unknown" err
583 '
584
585 test_expect_success 'stdin fails with duplicate refs' '
586         cat >stdin <<-EOF &&
587         create $a $m
588         create $b $m
589         create $a $m
590         EOF
591         test_must_fail git update-ref --stdin <stdin 2>err &&
592         grep "fatal: multiple updates for ref '"'"'$a'"'"' not allowed." err
593 '
594
595 test_expect_success 'stdin create ref works' '
596         echo "create $a $m" >stdin &&
597         git update-ref --stdin <stdin &&
598         git rev-parse $m >expect &&
599         git rev-parse $a >actual &&
600         test_cmp expect actual
601 '
602
603 test_expect_success 'stdin does not create reflogs by default' '
604         test_when_finished "git update-ref -d $outside" &&
605         echo "create $outside $m" >stdin &&
606         git update-ref --stdin <stdin &&
607         git rev-parse $m >expect &&
608         git rev-parse $outside >actual &&
609         test_cmp expect actual &&
610         test_must_fail git reflog exists $outside
611 '
612
613 test_expect_success 'stdin creates reflogs with --create-reflog' '
614         test_when_finished "git update-ref -d $outside" &&
615         echo "create $outside $m" >stdin &&
616         git update-ref --create-reflog --stdin <stdin &&
617         git rev-parse $m >expect &&
618         git rev-parse $outside >actual &&
619         test_cmp expect actual &&
620         git reflog exists $outside
621 '
622
623 test_expect_success 'stdin succeeds with quoted argument' '
624         git update-ref -d $a &&
625         echo "create $a \"$m\"" >stdin &&
626         git update-ref --stdin <stdin &&
627         git rev-parse $m >expect &&
628         git rev-parse $a >actual &&
629         test_cmp expect actual
630 '
631
632 test_expect_success 'stdin succeeds with escaped character' '
633         git update-ref -d $a &&
634         echo "create $a \"ma\\163ter\"" >stdin &&
635         git update-ref --stdin <stdin &&
636         git rev-parse $m >expect &&
637         git rev-parse $a >actual &&
638         test_cmp expect actual
639 '
640
641 test_expect_success 'stdin update ref creates with zero old value' '
642         echo "update $b $m $Z" >stdin &&
643         git update-ref --stdin <stdin &&
644         git rev-parse $m >expect &&
645         git rev-parse $b >actual &&
646         test_cmp expect actual &&
647         git update-ref -d $b
648 '
649
650 test_expect_success 'stdin update ref creates with empty old value' '
651         echo "update $b $m $E" >stdin &&
652         git update-ref --stdin <stdin &&
653         git rev-parse $m >expect &&
654         git rev-parse $b >actual &&
655         test_cmp expect actual
656 '
657
658 test_expect_success 'stdin create ref works with path with space to blob' '
659         echo "create refs/blobs/pws \"$m:$pws\"" >stdin &&
660         git update-ref --stdin <stdin &&
661         git rev-parse "$m:$pws" >expect &&
662         git rev-parse refs/blobs/pws >actual &&
663         test_cmp expect actual &&
664         git update-ref -d refs/blobs/pws
665 '
666
667 test_expect_success 'stdin update ref fails with wrong old value' '
668         echo "update $c $m $m~1" >stdin &&
669         test_must_fail git update-ref --stdin <stdin 2>err &&
670         grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
671         test_must_fail git rev-parse --verify -q $c
672 '
673
674 test_expect_success 'stdin update ref fails with bad old value' '
675         echo "update $c $m does-not-exist" >stdin &&
676         test_must_fail git update-ref --stdin <stdin 2>err &&
677         grep "fatal: update $c: invalid <oldvalue>: does-not-exist" err &&
678         test_must_fail git rev-parse --verify -q $c
679 '
680
681 test_expect_success 'stdin create ref fails with bad new value' '
682         echo "create $c does-not-exist" >stdin &&
683         test_must_fail git update-ref --stdin <stdin 2>err &&
684         grep "fatal: create $c: invalid <newvalue>: does-not-exist" err &&
685         test_must_fail git rev-parse --verify -q $c
686 '
687
688 test_expect_success 'stdin create ref fails with zero new value' '
689         echo "create $c " >stdin &&
690         test_must_fail git update-ref --stdin <stdin 2>err &&
691         grep "fatal: create $c: zero <newvalue>" err &&
692         test_must_fail git rev-parse --verify -q $c
693 '
694
695 test_expect_success 'stdin update ref works with right old value' '
696         echo "update $b $m~1 $m" >stdin &&
697         git update-ref --stdin <stdin &&
698         git rev-parse $m~1 >expect &&
699         git rev-parse $b >actual &&
700         test_cmp expect actual
701 '
702
703 test_expect_success 'stdin delete ref fails with wrong old value' '
704         echo "delete $a $m~1" >stdin &&
705         test_must_fail git update-ref --stdin <stdin 2>err &&
706         grep "fatal: cannot lock ref '"'"'$a'"'"'" err &&
707         git rev-parse $m >expect &&
708         git rev-parse $a >actual &&
709         test_cmp expect actual
710 '
711
712 test_expect_success 'stdin delete ref fails with zero old value' '
713         echo "delete $a " >stdin &&
714         test_must_fail git update-ref --stdin <stdin 2>err &&
715         grep "fatal: delete $a: zero <oldvalue>" err &&
716         git rev-parse $m >expect &&
717         git rev-parse $a >actual &&
718         test_cmp expect actual
719 '
720
721 test_expect_success 'stdin update symref works option no-deref' '
722         git symbolic-ref TESTSYMREF $b &&
723         cat >stdin <<-EOF &&
724         option no-deref
725         update TESTSYMREF $a $b
726         EOF
727         git update-ref --stdin <stdin &&
728         git rev-parse TESTSYMREF >expect &&
729         git rev-parse $a >actual &&
730         test_cmp expect actual &&
731         git rev-parse $m~1 >expect &&
732         git rev-parse $b >actual &&
733         test_cmp expect actual
734 '
735
736 test_expect_success 'stdin delete symref works option no-deref' '
737         git symbolic-ref TESTSYMREF $b &&
738         cat >stdin <<-EOF &&
739         option no-deref
740         delete TESTSYMREF $b
741         EOF
742         git update-ref --stdin <stdin &&
743         test_must_fail git rev-parse --verify -q TESTSYMREF &&
744         git rev-parse $m~1 >expect &&
745         git rev-parse $b >actual &&
746         test_cmp expect actual
747 '
748
749 test_expect_success 'stdin delete ref works with right old value' '
750         echo "delete $b $m~1" >stdin &&
751         git update-ref --stdin <stdin &&
752         test_must_fail git rev-parse --verify -q $b
753 '
754
755 test_expect_success 'stdin update/create/verify combination works' '
756         cat >stdin <<-EOF &&
757         update $a $m
758         create $b $m
759         verify $c
760         EOF
761         git update-ref --stdin <stdin &&
762         git rev-parse $m >expect &&
763         git rev-parse $a >actual &&
764         test_cmp expect actual &&
765         git rev-parse $b >actual &&
766         test_cmp expect actual &&
767         test_must_fail git rev-parse --verify -q $c
768 '
769
770 test_expect_success 'stdin verify succeeds for correct value' '
771         git rev-parse $m >expect &&
772         echo "verify $m $m" >stdin &&
773         git update-ref --stdin <stdin &&
774         git rev-parse $m >actual &&
775         test_cmp expect actual
776 '
777
778 test_expect_success 'stdin verify succeeds for missing reference' '
779         echo "verify refs/heads/missing $Z" >stdin &&
780         git update-ref --stdin <stdin &&
781         test_must_fail git rev-parse --verify -q refs/heads/missing
782 '
783
784 test_expect_success 'stdin verify treats no value as missing' '
785         echo "verify refs/heads/missing" >stdin &&
786         git update-ref --stdin <stdin &&
787         test_must_fail git rev-parse --verify -q refs/heads/missing
788 '
789
790 test_expect_success 'stdin verify fails for wrong value' '
791         git rev-parse $m >expect &&
792         echo "verify $m $m~1" >stdin &&
793         test_must_fail git update-ref --stdin <stdin &&
794         git rev-parse $m >actual &&
795         test_cmp expect actual
796 '
797
798 test_expect_success 'stdin verify fails for mistaken null value' '
799         git rev-parse $m >expect &&
800         echo "verify $m $Z" >stdin &&
801         test_must_fail git update-ref --stdin <stdin &&
802         git rev-parse $m >actual &&
803         test_cmp expect actual
804 '
805
806 test_expect_success 'stdin verify fails for mistaken empty value' '
807         M=$(git rev-parse $m) &&
808         test_when_finished "git update-ref $m $M" &&
809         git rev-parse $m >expect &&
810         echo "verify $m" >stdin &&
811         test_must_fail git update-ref --stdin <stdin &&
812         git rev-parse $m >actual &&
813         test_cmp expect actual
814 '
815
816 test_expect_success 'stdin update refs works with identity updates' '
817         cat >stdin <<-EOF &&
818         update $a $m $m
819         update $b $m $m
820         update $c $Z $E
821         EOF
822         git update-ref --stdin <stdin &&
823         git rev-parse $m >expect &&
824         git rev-parse $a >actual &&
825         test_cmp expect actual &&
826         git rev-parse $b >actual &&
827         test_cmp expect actual &&
828         test_must_fail git rev-parse --verify -q $c
829 '
830
831 test_expect_success 'stdin update refs fails with wrong old value' '
832         git update-ref $c $m &&
833         cat >stdin <<-EOF &&
834         update $a $m $m
835         update $b $m $m
836         update $c  ''
837         EOF
838         test_must_fail git update-ref --stdin <stdin 2>err &&
839         grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
840         git rev-parse $m >expect &&
841         git rev-parse $a >actual &&
842         test_cmp expect actual &&
843         git rev-parse $b >actual &&
844         test_cmp expect actual &&
845         git rev-parse $c >actual &&
846         test_cmp expect actual
847 '
848
849 test_expect_success 'stdin delete refs works with packed and loose refs' '
850         git pack-refs --all &&
851         git update-ref $c $m~1 &&
852         cat >stdin <<-EOF &&
853         delete $a $m
854         update $b $Z $m
855         update $c $E $m~1
856         EOF
857         git update-ref --stdin <stdin &&
858         test_must_fail git rev-parse --verify -q $a &&
859         test_must_fail git rev-parse --verify -q $b &&
860         test_must_fail git rev-parse --verify -q $c
861 '
862
863 test_expect_success 'stdin -z works on empty input' '
864         >stdin &&
865         git update-ref -z --stdin <stdin &&
866         git rev-parse --verify -q $m
867 '
868
869 test_expect_success 'stdin -z fails on empty line' '
870         echo "" >stdin &&
871         test_must_fail git update-ref -z --stdin <stdin 2>err &&
872         grep "fatal: whitespace before command: " err
873 '
874
875 test_expect_success 'stdin -z fails on empty command' '
876         printf $F "" >stdin &&
877         test_must_fail git update-ref -z --stdin <stdin 2>err &&
878         grep "fatal: empty command in input" err
879 '
880
881 test_expect_success 'stdin -z fails on only whitespace' '
882         printf $F " " >stdin &&
883         test_must_fail git update-ref -z --stdin <stdin 2>err &&
884         grep "fatal: whitespace before command:  " err
885 '
886
887 test_expect_success 'stdin -z fails on leading whitespace' '
888         printf $F " create $a" "$m" >stdin &&
889         test_must_fail git update-ref -z --stdin <stdin 2>err &&
890         grep "fatal: whitespace before command:  create $a" err
891 '
892
893 test_expect_success 'stdin -z fails on unknown command' '
894         printf $F "unknown $a" >stdin &&
895         test_must_fail git update-ref -z --stdin <stdin 2>err &&
896         grep "fatal: unknown command: unknown $a" err
897 '
898
899 test_expect_success 'stdin -z fails create with no ref' '
900         printf $F "create " >stdin &&
901         test_must_fail git update-ref -z --stdin <stdin 2>err &&
902         grep "fatal: create: missing <ref>" err
903 '
904
905 test_expect_success 'stdin -z fails create with no new value' '
906         printf $F "create $a" >stdin &&
907         test_must_fail git update-ref -z --stdin <stdin 2>err &&
908         grep "fatal: create $a: unexpected end of input when reading <newvalue>" err
909 '
910
911 test_expect_success 'stdin -z fails create with too many arguments' '
912         printf $F "create $a" "$m" "$m" >stdin &&
913         test_must_fail git update-ref -z --stdin <stdin 2>err &&
914         grep "fatal: unknown command: $m" err
915 '
916
917 test_expect_success 'stdin -z fails update with no ref' '
918         printf $F "update " >stdin &&
919         test_must_fail git update-ref -z --stdin <stdin 2>err &&
920         grep "fatal: update: missing <ref>" err
921 '
922
923 test_expect_success 'stdin -z fails update with too few args' '
924         printf $F "update $a" "$m" >stdin &&
925         test_must_fail git update-ref -z --stdin <stdin 2>err &&
926         grep "fatal: update $a: unexpected end of input when reading <oldvalue>" err
927 '
928
929 test_expect_success 'stdin -z emits warning with empty new value' '
930         git update-ref $a $m &&
931         printf $F "update $a" "" "" >stdin &&
932         git update-ref -z --stdin <stdin 2>err &&
933         grep "warning: update $a: missing <newvalue>, treating as zero" err &&
934         test_must_fail git rev-parse --verify -q $a
935 '
936
937 test_expect_success 'stdin -z fails update with no new value' '
938         printf $F "update $a" >stdin &&
939         test_must_fail git update-ref -z --stdin <stdin 2>err &&
940         grep "fatal: update $a: unexpected end of input when reading <newvalue>" err
941 '
942
943 test_expect_success 'stdin -z fails update with no old value' '
944         printf $F "update $a" "$m" >stdin &&
945         test_must_fail git update-ref -z --stdin <stdin 2>err &&
946         grep "fatal: update $a: unexpected end of input when reading <oldvalue>" err
947 '
948
949 test_expect_success 'stdin -z fails update with too many arguments' '
950         printf $F "update $a" "$m" "$m" "$m" >stdin &&
951         test_must_fail git update-ref -z --stdin <stdin 2>err &&
952         grep "fatal: unknown command: $m" err
953 '
954
955 test_expect_success 'stdin -z fails delete with no ref' '
956         printf $F "delete " >stdin &&
957         test_must_fail git update-ref -z --stdin <stdin 2>err &&
958         grep "fatal: delete: missing <ref>" err
959 '
960
961 test_expect_success 'stdin -z fails delete with no old value' '
962         printf $F "delete $a" >stdin &&
963         test_must_fail git update-ref -z --stdin <stdin 2>err &&
964         grep "fatal: delete $a: unexpected end of input when reading <oldvalue>" err
965 '
966
967 test_expect_success 'stdin -z fails delete with too many arguments' '
968         printf $F "delete $a" "$m" "$m" >stdin &&
969         test_must_fail git update-ref -z --stdin <stdin 2>err &&
970         grep "fatal: unknown command: $m" err
971 '
972
973 test_expect_success 'stdin -z fails verify with too many arguments' '
974         printf $F "verify $a" "$m" "$m" >stdin &&
975         test_must_fail git update-ref -z --stdin <stdin 2>err &&
976         grep "fatal: unknown command: $m" err
977 '
978
979 test_expect_success 'stdin -z fails verify with no old value' '
980         printf $F "verify $a" >stdin &&
981         test_must_fail git update-ref -z --stdin <stdin 2>err &&
982         grep "fatal: verify $a: unexpected end of input when reading <oldvalue>" err
983 '
984
985 test_expect_success 'stdin -z fails option with unknown name' '
986         printf $F "option unknown" >stdin &&
987         test_must_fail git update-ref -z --stdin <stdin 2>err &&
988         grep "fatal: option unknown: unknown" err
989 '
990
991 test_expect_success 'stdin -z fails with duplicate refs' '
992         printf $F "create $a" "$m" "create $b" "$m" "create $a" "$m" >stdin &&
993         test_must_fail git update-ref -z --stdin <stdin 2>err &&
994         grep "fatal: multiple updates for ref '"'"'$a'"'"' not allowed." err
995 '
996
997 test_expect_success 'stdin -z create ref works' '
998         printf $F "create $a" "$m" >stdin &&
999         git update-ref -z --stdin <stdin &&
1000         git rev-parse $m >expect &&
1001         git rev-parse $a >actual &&
1002         test_cmp expect actual
1003 '
1004
1005 test_expect_success 'stdin -z update ref creates with zero old value' '
1006         printf $F "update $b" "$m" "$Z" >stdin &&
1007         git update-ref -z --stdin <stdin &&
1008         git rev-parse $m >expect &&
1009         git rev-parse $b >actual &&
1010         test_cmp expect actual &&
1011         git update-ref -d $b
1012 '
1013
1014 test_expect_success 'stdin -z update ref creates with empty old value' '
1015         printf $F "update $b" "$m" "" >stdin &&
1016         git update-ref -z --stdin <stdin &&
1017         git rev-parse $m >expect &&
1018         git rev-parse $b >actual &&
1019         test_cmp expect actual
1020 '
1021
1022 test_expect_success 'stdin -z create ref works with path with space to blob' '
1023         printf $F "create refs/blobs/pws" "$m:$pws" >stdin &&
1024         git update-ref -z --stdin <stdin &&
1025         git rev-parse "$m:$pws" >expect &&
1026         git rev-parse refs/blobs/pws >actual &&
1027         test_cmp expect actual &&
1028         git update-ref -d refs/blobs/pws
1029 '
1030
1031 test_expect_success 'stdin -z update ref fails with wrong old value' '
1032         printf $F "update $c" "$m" "$m~1" >stdin &&
1033         test_must_fail git update-ref -z --stdin <stdin 2>err &&
1034         grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
1035         test_must_fail git rev-parse --verify -q $c
1036 '
1037
1038 test_expect_success 'stdin -z update ref fails with bad old value' '
1039         printf $F "update $c" "$m" "does-not-exist" >stdin &&
1040         test_must_fail git update-ref -z --stdin <stdin 2>err &&
1041         grep "fatal: update $c: invalid <oldvalue>: does-not-exist" err &&
1042         test_must_fail git rev-parse --verify -q $c
1043 '
1044
1045 test_expect_success 'stdin -z create ref fails when ref exists' '
1046         git update-ref $c $m &&
1047         git rev-parse "$c" >expect &&
1048         printf $F "create $c" "$m~1" >stdin &&
1049         test_must_fail git update-ref -z --stdin <stdin 2>err &&
1050         grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
1051         git rev-parse "$c" >actual &&
1052         test_cmp expect actual
1053 '
1054
1055 test_expect_success 'stdin -z create ref fails with bad new value' '
1056         git update-ref -d "$c" &&
1057         printf $F "create $c" "does-not-exist" >stdin &&
1058         test_must_fail git update-ref -z --stdin <stdin 2>err &&
1059         grep "fatal: create $c: invalid <newvalue>: does-not-exist" err &&
1060         test_must_fail git rev-parse --verify -q $c
1061 '
1062
1063 test_expect_success 'stdin -z create ref fails with empty new value' '
1064         printf $F "create $c" "" >stdin &&
1065         test_must_fail git update-ref -z --stdin <stdin 2>err &&
1066         grep "fatal: create $c: missing <newvalue>" err &&
1067         test_must_fail git rev-parse --verify -q $c
1068 '
1069
1070 test_expect_success 'stdin -z update ref works with right old value' '
1071         printf $F "update $b" "$m~1" "$m" >stdin &&
1072         git update-ref -z --stdin <stdin &&
1073         git rev-parse $m~1 >expect &&
1074         git rev-parse $b >actual &&
1075         test_cmp expect actual
1076 '
1077
1078 test_expect_success 'stdin -z delete ref fails with wrong old value' '
1079         printf $F "delete $a" "$m~1" >stdin &&
1080         test_must_fail git update-ref -z --stdin <stdin 2>err &&
1081         grep "fatal: cannot lock ref '"'"'$a'"'"'" err &&
1082         git rev-parse $m >expect &&
1083         git rev-parse $a >actual &&
1084         test_cmp expect actual
1085 '
1086
1087 test_expect_success 'stdin -z delete ref fails with zero old value' '
1088         printf $F "delete $a" "$Z" >stdin &&
1089         test_must_fail git update-ref -z --stdin <stdin 2>err &&
1090         grep "fatal: delete $a: zero <oldvalue>" err &&
1091         git rev-parse $m >expect &&
1092         git rev-parse $a >actual &&
1093         test_cmp expect actual
1094 '
1095
1096 test_expect_success 'stdin -z update symref works option no-deref' '
1097         git symbolic-ref TESTSYMREF $b &&
1098         printf $F "option no-deref" "update TESTSYMREF" "$a" "$b" >stdin &&
1099         git update-ref -z --stdin <stdin &&
1100         git rev-parse TESTSYMREF >expect &&
1101         git rev-parse $a >actual &&
1102         test_cmp expect actual &&
1103         git rev-parse $m~1 >expect &&
1104         git rev-parse $b >actual &&
1105         test_cmp expect actual
1106 '
1107
1108 test_expect_success 'stdin -z delete symref works option no-deref' '
1109         git symbolic-ref TESTSYMREF $b &&
1110         printf $F "option no-deref" "delete TESTSYMREF" "$b" >stdin &&
1111         git update-ref -z --stdin <stdin &&
1112         test_must_fail git rev-parse --verify -q TESTSYMREF &&
1113         git rev-parse $m~1 >expect &&
1114         git rev-parse $b >actual &&
1115         test_cmp expect actual
1116 '
1117
1118 test_expect_success 'stdin -z delete ref works with right old value' '
1119         printf $F "delete $b" "$m~1" >stdin &&
1120         git update-ref -z --stdin <stdin &&
1121         test_must_fail git rev-parse --verify -q $b
1122 '
1123
1124 test_expect_success 'stdin -z update/create/verify combination works' '
1125         printf $F "update $a" "$m" "" "create $b" "$m" "verify $c" "" >stdin &&
1126         git update-ref -z --stdin <stdin &&
1127         git rev-parse $m >expect &&
1128         git rev-parse $a >actual &&
1129         test_cmp expect actual &&
1130         git rev-parse $b >actual &&
1131         test_cmp expect actual &&
1132         test_must_fail git rev-parse --verify -q $c
1133 '
1134
1135 test_expect_success 'stdin -z verify succeeds for correct value' '
1136         git rev-parse $m >expect &&
1137         printf $F "verify $m" "$m" >stdin &&
1138         git update-ref -z --stdin <stdin &&
1139         git rev-parse $m >actual &&
1140         test_cmp expect actual
1141 '
1142
1143 test_expect_success 'stdin -z verify succeeds for missing reference' '
1144         printf $F "verify refs/heads/missing" "$Z" >stdin &&
1145         git update-ref -z --stdin <stdin &&
1146         test_must_fail git rev-parse --verify -q refs/heads/missing
1147 '
1148
1149 test_expect_success 'stdin -z verify treats no value as missing' '
1150         printf $F "verify refs/heads/missing" "" >stdin &&
1151         git update-ref -z --stdin <stdin &&
1152         test_must_fail git rev-parse --verify -q refs/heads/missing
1153 '
1154
1155 test_expect_success 'stdin -z verify fails for wrong value' '
1156         git rev-parse $m >expect &&
1157         printf $F "verify $m" "$m~1" >stdin &&
1158         test_must_fail git update-ref -z --stdin <stdin &&
1159         git rev-parse $m >actual &&
1160         test_cmp expect actual
1161 '
1162
1163 test_expect_success 'stdin -z verify fails for mistaken null value' '
1164         git rev-parse $m >expect &&
1165         printf $F "verify $m" "$Z" >stdin &&
1166         test_must_fail git update-ref -z --stdin <stdin &&
1167         git rev-parse $m >actual &&
1168         test_cmp expect actual
1169 '
1170
1171 test_expect_success 'stdin -z verify fails for mistaken empty value' '
1172         M=$(git rev-parse $m) &&
1173         test_when_finished "git update-ref $m $M" &&
1174         git rev-parse $m >expect &&
1175         printf $F "verify $m" "" >stdin &&
1176         test_must_fail git update-ref -z --stdin <stdin &&
1177         git rev-parse $m >actual &&
1178         test_cmp expect actual
1179 '
1180
1181 test_expect_success 'stdin -z update refs works with identity updates' '
1182         printf $F "update $a" "$m" "$m" "update $b" "$m" "$m" "update $c" "$Z" "" >stdin &&
1183         git update-ref -z --stdin <stdin &&
1184         git rev-parse $m >expect &&
1185         git rev-parse $a >actual &&
1186         test_cmp expect actual &&
1187         git rev-parse $b >actual &&
1188         test_cmp expect actual &&
1189         test_must_fail git rev-parse --verify -q $c
1190 '
1191
1192 test_expect_success 'stdin -z update refs fails with wrong old value' '
1193         git update-ref $c $m &&
1194         printf $F "update $a" "$m" "$m" "update $b" "$m" "$m" "update $c" "$m" "$Z" >stdin &&
1195         test_must_fail git update-ref -z --stdin <stdin 2>err &&
1196         grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
1197         git rev-parse $m >expect &&
1198         git rev-parse $a >actual &&
1199         test_cmp expect actual &&
1200         git rev-parse $b >actual &&
1201         test_cmp expect actual &&
1202         git rev-parse $c >actual &&
1203         test_cmp expect actual
1204 '
1205
1206 test_expect_success 'stdin -z delete refs works with packed and loose refs' '
1207         git pack-refs --all &&
1208         git update-ref $c $m~1 &&
1209         printf $F "delete $a" "$m" "update $b" "$Z" "$m" "update $c" "" "$m~1" >stdin &&
1210         git update-ref -z --stdin <stdin &&
1211         test_must_fail git rev-parse --verify -q $a &&
1212         test_must_fail git rev-parse --verify -q $b &&
1213         test_must_fail git rev-parse --verify -q $c
1214 '
1215
1216 test_expect_success 'fails with duplicate HEAD update' '
1217         git branch target1 $A &&
1218         git checkout target1 &&
1219         cat >stdin <<-EOF &&
1220         update refs/heads/target1 $C
1221         option no-deref
1222         update HEAD $B
1223         EOF
1224         test_must_fail git update-ref --stdin <stdin 2>err &&
1225         grep "fatal: multiple updates for '\''HEAD'\'' (including one via its referent .refs/heads/target1.) are not allowed" err &&
1226         echo "refs/heads/target1" >expect &&
1227         git symbolic-ref HEAD >actual &&
1228         test_cmp expect actual &&
1229         echo "$A" >expect &&
1230         git rev-parse refs/heads/target1 >actual &&
1231         test_cmp expect actual
1232 '
1233
1234 test_expect_success 'fails with duplicate ref update via symref' '
1235         git branch target2 $A &&
1236         git symbolic-ref refs/heads/symref2 refs/heads/target2 &&
1237         cat >stdin <<-EOF &&
1238         update refs/heads/target2 $C
1239         update refs/heads/symref2 $B
1240         EOF
1241         test_must_fail git update-ref --stdin <stdin 2>err &&
1242         grep "fatal: multiple updates for '\''refs/heads/target2'\'' (including one via symref .refs/heads/symref2.) are not allowed" err &&
1243         echo "refs/heads/target2" >expect &&
1244         git symbolic-ref refs/heads/symref2 >actual &&
1245         test_cmp expect actual &&
1246         echo "$A" >expect &&
1247         git rev-parse refs/heads/target2 >actual &&
1248         test_cmp expect actual
1249 '
1250
1251 run_with_limited_open_files () {
1252         (ulimit -n 32 && "$@")
1253 }
1254
1255 test_lazy_prereq ULIMIT_FILE_DESCRIPTORS 'run_with_limited_open_files true'
1256
1257 test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction creating branches does not burst open file limit' '
1258 (
1259         for i in $(test_seq 33)
1260         do
1261                 echo "create refs/heads/$i HEAD"
1262         done >large_input &&
1263         run_with_limited_open_files git update-ref --stdin <large_input &&
1264         git rev-parse --verify -q refs/heads/33
1265 )
1266 '
1267
1268 test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction deleting branches does not burst open file limit' '
1269 (
1270         for i in $(test_seq 33)
1271         do
1272                 echo "delete refs/heads/$i HEAD"
1273         done >large_input &&
1274         run_with_limited_open_files git update-ref --stdin <large_input &&
1275         test_must_fail git rev-parse --verify -q refs/heads/33
1276 )
1277 '
1278
1279 test_expect_success 'handle per-worktree refs in refs/bisect' '
1280         git commit --allow-empty -m "initial commit" &&
1281         git worktree add -b branch worktree &&
1282         (
1283                 cd worktree &&
1284                 git commit --allow-empty -m "test commit"  &&
1285                 git for-each-ref >for-each-ref.out &&
1286                 ! grep refs/bisect for-each-ref.out &&
1287                 git update-ref refs/bisect/something HEAD &&
1288                 git rev-parse refs/bisect/something >../worktree-head &&
1289                 git for-each-ref | grep refs/bisect/something
1290         ) &&
1291         test_path_is_missing .git/refs/bisect &&
1292         test_must_fail git rev-parse refs/bisect/something &&
1293         git update-ref refs/bisect/something HEAD &&
1294         git rev-parse refs/bisect/something >main-head &&
1295         ! test_cmp main-head worktree-head
1296 '
1297
1298 test_done