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