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