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