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