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