update-ref and tag: add --create-reflog arg
[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=$_z40
10
11 test_expect_success setup '
12
13         for name in A B C D E F
14         do
15                 test_tick &&
16                 T=$(git write-tree) &&
17                 sha1=$(echo $name | git commit-tree $T) &&
18                 eval $name=$sha1
19         done
20
21 '
22
23 m=refs/heads/master
24 n_dir=refs/heads/gu
25 n=$n_dir/fixes
26 outside=foo
27
28 test_expect_success \
29         "create $m" \
30         "git update-ref $m $A &&
31          test $A"' = $(cat .git/'"$m"')'
32 test_expect_success \
33         "create $m" \
34         "git update-ref $m $B $A &&
35          test $B"' = $(cat .git/'"$m"')'
36 test_expect_success "fail to delete $m with stale ref" '
37         test_must_fail git update-ref -d $m $A &&
38         test $B = "$(cat .git/$m)"
39 '
40 test_expect_success "delete $m" '
41         git update-ref -d $m $B &&
42         ! test -f .git/$m
43 '
44 rm -f .git/$m
45
46 test_expect_success "delete $m without oldvalue verification" "
47         git update-ref $m $A &&
48         test $A = \$(cat .git/$m) &&
49         git update-ref -d $m &&
50         ! test -f .git/$m
51 "
52 rm -f .git/$m
53
54 test_expect_success \
55         "fail to create $n" \
56         "touch .git/$n_dir &&
57          test_must_fail git update-ref $n $A >out 2>err"
58 rm -f .git/$n_dir out err
59
60 test_expect_success \
61         "create $m (by HEAD)" \
62         "git update-ref HEAD $A &&
63          test $A"' = $(cat .git/'"$m"')'
64 test_expect_success \
65         "create $m (by HEAD)" \
66         "git update-ref HEAD $B $A &&
67          test $B"' = $(cat .git/'"$m"')'
68 test_expect_success "fail to delete $m (by HEAD) with stale ref" '
69         test_must_fail git update-ref -d HEAD $A &&
70         test $B = $(cat .git/$m)
71 '
72 test_expect_success "delete $m (by HEAD)" '
73         git update-ref -d HEAD $B &&
74         ! test -f .git/$m
75 '
76 rm -f .git/$m
77
78 test_expect_success 'update-ref does not create reflogs by default' '
79         test_when_finished "git update-ref -d $outside" &&
80         git update-ref $outside $A &&
81         git rev-parse $A >expect &&
82         git rev-parse $outside >actual &&
83         test_cmp expect actual &&
84         test_must_fail git reflog exists $outside
85 '
86
87 test_expect_success 'update-ref creates reflogs with --create-reflog' '
88         test_when_finished "git update-ref -d $outside" &&
89         git update-ref --create-reflog $outside $A &&
90         git rev-parse $A >expect &&
91         git rev-parse $outside >actual &&
92         test_cmp expect actual &&
93         git reflog exists $outside
94 '
95
96 test_expect_success \
97         "create $m (by HEAD)" \
98         "git update-ref HEAD $A &&
99          test $A"' = $(cat .git/'"$m"')'
100 test_expect_success \
101         "pack refs" \
102         "git pack-refs --all"
103 test_expect_success \
104         "move $m (by HEAD)" \
105         "git update-ref HEAD $B $A &&
106          test $B"' = $(cat .git/'"$m"')'
107 test_expect_success "delete $m (by HEAD) should remove both packed and loose $m" '
108         git update-ref -d HEAD $B &&
109         ! grep "$m" .git/packed-refs &&
110         ! test -f .git/$m
111 '
112 rm -f .git/$m
113
114 cp -f .git/HEAD .git/HEAD.orig
115 test_expect_success "delete symref without dereference" '
116         git update-ref --no-deref -d HEAD &&
117         ! test -f .git/HEAD
118 '
119 cp -f .git/HEAD.orig .git/HEAD
120
121 test_expect_success "delete symref without dereference when the referred ref is packed" '
122         echo foo >foo.c &&
123         git add foo.c &&
124         git commit -m foo &&
125         git pack-refs --all &&
126         git update-ref --no-deref -d HEAD &&
127         ! test -f .git/HEAD
128 '
129 cp -f .git/HEAD.orig .git/HEAD
130 git update-ref -d $m
131
132 test_expect_success 'update-ref -d is not confused by self-reference' '
133         git symbolic-ref refs/heads/self refs/heads/self &&
134         test_when_finished "rm -f .git/refs/heads/self" &&
135         test_path_is_file .git/refs/heads/self &&
136         test_must_fail git update-ref -d refs/heads/self &&
137         test_path_is_file .git/refs/heads/self
138 '
139
140 test_expect_success 'update-ref --no-deref -d can delete self-reference' '
141         git symbolic-ref refs/heads/self refs/heads/self &&
142         test_when_finished "rm -f .git/refs/heads/self" &&
143         test_path_is_file .git/refs/heads/self &&
144         git update-ref --no-deref -d refs/heads/self &&
145         test_path_is_missing .git/refs/heads/self
146 '
147
148 test_expect_success 'update-ref --no-deref -d can delete reference to bad ref' '
149         >.git/refs/heads/bad &&
150         test_when_finished "rm -f .git/refs/heads/bad" &&
151         git symbolic-ref refs/heads/ref-to-bad refs/heads/bad &&
152         test_when_finished "rm -f .git/refs/heads/ref-to-bad" &&
153         test_path_is_file .git/refs/heads/ref-to-bad &&
154         git update-ref --no-deref -d refs/heads/ref-to-bad &&
155         test_path_is_missing .git/refs/heads/ref-to-bad
156 '
157
158 test_expect_success '(not) create HEAD with old sha1' "
159         test_must_fail git update-ref HEAD $A $B
160 "
161 test_expect_success "(not) prior created .git/$m" "
162         ! test -f .git/$m
163 "
164 rm -f .git/$m
165
166 test_expect_success \
167         "create HEAD" \
168         "git update-ref HEAD $A"
169 test_expect_success '(not) change HEAD with wrong SHA1' "
170         test_must_fail git update-ref HEAD $B $Z
171 "
172 test_expect_success "(not) changed .git/$m" "
173         ! test $B"' = $(cat .git/'"$m"')
174 '
175 rm -f .git/$m
176
177 : a repository with working tree always has reflog these days...
178 : >.git/logs/refs/heads/master
179 test_expect_success \
180         "create $m (logged by touch)" \
181         'GIT_COMMITTER_DATE="2005-05-26 23:30" \
182          git update-ref HEAD '"$A"' -m "Initial Creation" &&
183          test '"$A"' = $(cat .git/'"$m"')'
184 test_expect_success \
185         "update $m (logged by touch)" \
186         'GIT_COMMITTER_DATE="2005-05-26 23:31" \
187          git update-ref HEAD'" $B $A "'-m "Switch" &&
188          test '"$B"' = $(cat .git/'"$m"')'
189 test_expect_success \
190         "set $m (logged by touch)" \
191         'GIT_COMMITTER_DATE="2005-05-26 23:41" \
192          git update-ref HEAD'" $A &&
193          test $A"' = $(cat .git/'"$m"')'
194
195 cat >expect <<EOF
196 $Z $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000       Initial Creation
197 $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150260 +0000       Switch
198 $B $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150860 +0000
199 EOF
200 test_expect_success \
201         "verifying $m's log" \
202         "test_cmp expect .git/logs/$m"
203 rm -rf .git/$m .git/logs expect
204
205 test_expect_success \
206         'enable core.logAllRefUpdates' \
207         'git config core.logAllRefUpdates true &&
208          test true = $(git config --bool --get core.logAllRefUpdates)'
209
210 test_expect_success \
211         "create $m (logged by config)" \
212         'GIT_COMMITTER_DATE="2005-05-26 23:32" \
213          git update-ref HEAD'" $A "'-m "Initial Creation" &&
214          test '"$A"' = $(cat .git/'"$m"')'
215 test_expect_success \
216         "update $m (logged by config)" \
217         'GIT_COMMITTER_DATE="2005-05-26 23:33" \
218          git update-ref HEAD'" $B $A "'-m "Switch" &&
219          test '"$B"' = $(cat .git/'"$m"')'
220 test_expect_success \
221         "set $m (logged by config)" \
222         'GIT_COMMITTER_DATE="2005-05-26 23:43" \
223          git update-ref HEAD '"$A &&
224          test $A"' = $(cat .git/'"$m"')'
225
226 cat >expect <<EOF
227 $Z $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150320 +0000       Initial Creation
228 $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 +0000       Switch
229 $B $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 +0000
230 EOF
231 test_expect_success \
232         "verifying $m's log" \
233         'test_cmp expect .git/logs/$m'
234 rm -f .git/$m .git/logs/$m expect
235
236 git update-ref $m $D
237 cat >.git/logs/$m <<EOF
238 0000000000000000000000000000000000000000 $C $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150320 -0500
239 $C $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150350 -0500
240 $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 -0500
241 $F $Z $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150680 -0500
242 $Z $E $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 -0500
243 EOF
244
245 ed="Thu, 26 May 2005 18:32:00 -0500"
246 gd="Thu, 26 May 2005 18:33:00 -0500"
247 ld="Thu, 26 May 2005 18:43:00 -0500"
248 test_expect_success \
249         'Query "master@{May 25 2005}" (before history)' \
250         'rm -f o e &&
251          git rev-parse --verify "master@{May 25 2005}" >o 2>e &&
252          test '"$C"' = $(cat o) &&
253          test "warning: Log for '\'master\'' only goes back to $ed." = "$(cat e)"'
254 test_expect_success \
255         "Query master@{2005-05-25} (before history)" \
256         'rm -f o e &&
257          git rev-parse --verify master@{2005-05-25} >o 2>e &&
258          test '"$C"' = $(cat o) &&
259          echo test "warning: Log for '\'master\'' only goes back to $ed." = "$(cat e)"'
260 test_expect_success \
261         'Query "master@{May 26 2005 23:31:59}" (1 second before history)' \
262         'rm -f o e &&
263          git rev-parse --verify "master@{May 26 2005 23:31:59}" >o 2>e &&
264          test '"$C"' = $(cat o) &&
265          test "warning: Log for '\''master'\'' only goes back to $ed." = "$(cat e)"'
266 test_expect_success \
267         'Query "master@{May 26 2005 23:32:00}" (exactly history start)' \
268         'rm -f o e &&
269          git rev-parse --verify "master@{May 26 2005 23:32:00}" >o 2>e &&
270          test '"$C"' = $(cat o) &&
271          test "" = "$(cat e)"'
272 test_expect_success \
273         'Query "master@{May 26 2005 23:32:30}" (first non-creation change)' \
274         'rm -f o e &&
275          git rev-parse --verify "master@{May 26 2005 23:32:30}" >o 2>e &&
276          test '"$A"' = $(cat o) &&
277          test "" = "$(cat e)"'
278 test_expect_success \
279         'Query "master@{2005-05-26 23:33:01}" (middle of history with gap)' \
280         'rm -f o e &&
281          git rev-parse --verify "master@{2005-05-26 23:33:01}" >o 2>e &&
282          test '"$B"' = $(cat o) &&
283          test "warning: Log for ref '"$m has gap after $gd"'." = "$(cat e)"'
284 test_expect_success \
285         'Query "master@{2005-05-26 23:38:00}" (middle of history)' \
286         'rm -f o e &&
287          git rev-parse --verify "master@{2005-05-26 23:38:00}" >o 2>e &&
288          test '"$Z"' = $(cat o) &&
289          test "" = "$(cat e)"'
290 test_expect_success \
291         'Query "master@{2005-05-26 23:43:00}" (exact end of history)' \
292         'rm -f o e &&
293          git rev-parse --verify "master@{2005-05-26 23:43:00}" >o 2>e &&
294          test '"$E"' = $(cat o) &&
295          test "" = "$(cat e)"'
296 test_expect_success \
297         'Query "master@{2005-05-28}" (past end of history)' \
298         'rm -f o e &&
299          git rev-parse --verify "master@{2005-05-28}" >o 2>e &&
300          test '"$D"' = $(cat o) &&
301          test "warning: Log for ref '"$m unexpectedly ended on $ld"'." = "$(cat e)"'
302
303
304 rm -f .git/$m .git/logs/$m expect
305
306 test_expect_success \
307     'creating initial files' \
308     'echo TEST >F &&
309      git add F &&
310          GIT_AUTHOR_DATE="2005-05-26 23:30" \
311          GIT_COMMITTER_DATE="2005-05-26 23:30" git commit -m add -a &&
312          h_TEST=$(git rev-parse --verify HEAD) &&
313          echo The other day this did not work. >M &&
314          echo And then Bob told me how to fix it. >>M &&
315          echo OTHER >F &&
316          GIT_AUTHOR_DATE="2005-05-26 23:41" \
317          GIT_COMMITTER_DATE="2005-05-26 23:41" git commit -F M -a &&
318          h_OTHER=$(git rev-parse --verify HEAD) &&
319          GIT_AUTHOR_DATE="2005-05-26 23:44" \
320          GIT_COMMITTER_DATE="2005-05-26 23:44" git commit --amend &&
321          h_FIXED=$(git rev-parse --verify HEAD) &&
322          echo Merged initial commit and a later commit. >M &&
323          echo $h_TEST >.git/MERGE_HEAD &&
324          GIT_AUTHOR_DATE="2005-05-26 23:45" \
325          GIT_COMMITTER_DATE="2005-05-26 23:45" git commit -F M &&
326          h_MERGED=$(git rev-parse --verify HEAD) &&
327          rm -f M'
328
329 cat >expect <<EOF
330 $Z $h_TEST $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000  commit (initial): add
331 $h_TEST $h_OTHER $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150860 +0000    commit: The other day this did not work.
332 $h_OTHER $h_FIXED $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117151040 +0000   commit (amend): The other day this did not work.
333 $h_FIXED $h_MERGED $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117151100 +0000  commit (merge): Merged initial commit and a later commit.
334 EOF
335 test_expect_success \
336         'git commit logged updates' \
337         "test_cmp expect .git/logs/$m"
338 unset h_TEST h_OTHER h_FIXED h_MERGED
339
340 test_expect_success \
341         'git cat-file blob master:F (expect OTHER)' \
342         'test OTHER = $(git cat-file blob master:F)'
343 test_expect_success \
344         'git cat-file blob master@{2005-05-26 23:30}:F (expect TEST)' \
345         'test TEST = $(git cat-file blob "master@{2005-05-26 23:30}:F")'
346 test_expect_success \
347         'git cat-file blob master@{2005-05-26 23:42}:F (expect OTHER)' \
348         'test OTHER = $(git cat-file blob "master@{2005-05-26 23:42}:F")'
349
350 a=refs/heads/a
351 b=refs/heads/b
352 c=refs/heads/c
353 E='""'
354 F='%s\0'
355 pws='path with space'
356
357 test_expect_success 'stdin test setup' '
358         echo "$pws" >"$pws" &&
359         git add -- "$pws" &&
360         git commit -m "$pws"
361 '
362
363 test_expect_success '-z fails without --stdin' '
364         test_must_fail git update-ref -z $m $m $m 2>err &&
365         grep "usage: git update-ref" err
366 '
367
368 test_expect_success 'stdin works with no input' '
369         >stdin &&
370         git update-ref --stdin <stdin &&
371         git rev-parse --verify -q $m
372 '
373
374 test_expect_success 'stdin fails on empty line' '
375         echo "" >stdin &&
376         test_must_fail git update-ref --stdin <stdin 2>err &&
377         grep "fatal: empty command in input" err
378 '
379
380 test_expect_success 'stdin fails on only whitespace' '
381         echo " " >stdin &&
382         test_must_fail git update-ref --stdin <stdin 2>err &&
383         grep "fatal: whitespace before command:  " err
384 '
385
386 test_expect_success 'stdin fails on leading whitespace' '
387         echo " create $a $m" >stdin &&
388         test_must_fail git update-ref --stdin <stdin 2>err &&
389         grep "fatal: whitespace before command:  create $a $m" err
390 '
391
392 test_expect_success 'stdin fails on unknown command' '
393         echo "unknown $a" >stdin &&
394         test_must_fail git update-ref --stdin <stdin 2>err &&
395         grep "fatal: unknown command: unknown $a" err
396 '
397
398 test_expect_success 'stdin fails on unbalanced quotes' '
399         echo "create $a \"master" >stdin &&
400         test_must_fail git update-ref --stdin <stdin 2>err &&
401         grep "fatal: badly quoted argument: \\\"master" err
402 '
403
404 test_expect_success 'stdin fails on invalid escape' '
405         echo "create $a \"ma\zter\"" >stdin &&
406         test_must_fail git update-ref --stdin <stdin 2>err &&
407         grep "fatal: badly quoted argument: \\\"ma\\\\zter\\\"" err
408 '
409
410 test_expect_success 'stdin fails on junk after quoted argument' '
411         echo "create \"$a\"master" >stdin &&
412         test_must_fail git update-ref --stdin <stdin 2>err &&
413         grep "fatal: unexpected character after quoted argument: \\\"$a\\\"master" err
414 '
415
416 test_expect_success 'stdin fails create with no ref' '
417         echo "create " >stdin &&
418         test_must_fail git update-ref --stdin <stdin 2>err &&
419         grep "fatal: create: missing <ref>" err
420 '
421
422 test_expect_success 'stdin fails create with no new value' '
423         echo "create $a" >stdin &&
424         test_must_fail git update-ref --stdin <stdin 2>err &&
425         grep "fatal: create $a: missing <newvalue>" err
426 '
427
428 test_expect_success 'stdin fails create with too many arguments' '
429         echo "create $a $m $m" >stdin &&
430         test_must_fail git update-ref --stdin <stdin 2>err &&
431         grep "fatal: create $a: extra input:  $m" err
432 '
433
434 test_expect_success 'stdin fails update with no ref' '
435         echo "update " >stdin &&
436         test_must_fail git update-ref --stdin <stdin 2>err &&
437         grep "fatal: update: missing <ref>" err
438 '
439
440 test_expect_success 'stdin fails update with no new value' '
441         echo "update $a" >stdin &&
442         test_must_fail git update-ref --stdin <stdin 2>err &&
443         grep "fatal: update $a: missing <newvalue>" err
444 '
445
446 test_expect_success 'stdin fails update with too many arguments' '
447         echo "update $a $m $m $m" >stdin &&
448         test_must_fail git update-ref --stdin <stdin 2>err &&
449         grep "fatal: update $a: extra input:  $m" err
450 '
451
452 test_expect_success 'stdin fails delete with no ref' '
453         echo "delete " >stdin &&
454         test_must_fail git update-ref --stdin <stdin 2>err &&
455         grep "fatal: delete: missing <ref>" err
456 '
457
458 test_expect_success 'stdin fails delete with too many arguments' '
459         echo "delete $a $m $m" >stdin &&
460         test_must_fail git update-ref --stdin <stdin 2>err &&
461         grep "fatal: delete $a: extra input:  $m" err
462 '
463
464 test_expect_success 'stdin fails verify with too many arguments' '
465         echo "verify $a $m $m" >stdin &&
466         test_must_fail git update-ref --stdin <stdin 2>err &&
467         grep "fatal: verify $a: extra input:  $m" err
468 '
469
470 test_expect_success 'stdin fails option with unknown name' '
471         echo "option unknown" >stdin &&
472         test_must_fail git update-ref --stdin <stdin 2>err &&
473         grep "fatal: option unknown: unknown" err
474 '
475
476 test_expect_success 'stdin fails with duplicate refs' '
477         cat >stdin <<-EOF &&
478         create $a $m
479         create $b $m
480         create $a $m
481         EOF
482         test_must_fail git update-ref --stdin <stdin 2>err &&
483         grep "fatal: Multiple updates for ref '"'"'$a'"'"' not allowed." err
484 '
485
486 test_expect_success 'stdin create ref works' '
487         echo "create $a $m" >stdin &&
488         git update-ref --stdin <stdin &&
489         git rev-parse $m >expect &&
490         git rev-parse $a >actual &&
491         test_cmp expect actual
492 '
493
494 test_expect_success 'stdin does not create reflogs by default' '
495         test_when_finished "git update-ref -d $outside" &&
496         echo "create $outside $m" >stdin &&
497         git update-ref --stdin <stdin &&
498         git rev-parse $m >expect &&
499         git rev-parse $outside >actual &&
500         test_cmp expect actual &&
501         test_must_fail git reflog exists $outside
502 '
503
504 test_expect_success 'stdin creates reflogs with --create-reflog' '
505         echo "create $outside $m" >stdin &&
506         git update-ref --create-reflog --stdin <stdin &&
507         git rev-parse $m >expect &&
508         git rev-parse $outside >actual &&
509         test_cmp expect actual &&
510         git reflog exists $outside
511 '
512
513 test_expect_success 'stdin succeeds with quoted argument' '
514         git update-ref -d $a &&
515         echo "create $a \"$m\"" >stdin &&
516         git update-ref --stdin <stdin &&
517         git rev-parse $m >expect &&
518         git rev-parse $a >actual &&
519         test_cmp expect actual
520 '
521
522 test_expect_success 'stdin succeeds with escaped character' '
523         git update-ref -d $a &&
524         echo "create $a \"ma\\163ter\"" >stdin &&
525         git update-ref --stdin <stdin &&
526         git rev-parse $m >expect &&
527         git rev-parse $a >actual &&
528         test_cmp expect actual
529 '
530
531 test_expect_success 'stdin update ref creates with zero old value' '
532         echo "update $b $m $Z" >stdin &&
533         git update-ref --stdin <stdin &&
534         git rev-parse $m >expect &&
535         git rev-parse $b >actual &&
536         test_cmp expect actual &&
537         git update-ref -d $b
538 '
539
540 test_expect_success 'stdin update ref creates with empty old value' '
541         echo "update $b $m $E" >stdin &&
542         git update-ref --stdin <stdin &&
543         git rev-parse $m >expect &&
544         git rev-parse $b >actual &&
545         test_cmp expect actual
546 '
547
548 test_expect_success 'stdin create ref works with path with space to blob' '
549         echo "create refs/blobs/pws \"$m:$pws\"" >stdin &&
550         git update-ref --stdin <stdin &&
551         git rev-parse "$m:$pws" >expect &&
552         git rev-parse refs/blobs/pws >actual &&
553         test_cmp expect actual &&
554         git update-ref -d refs/blobs/pws
555 '
556
557 test_expect_success 'stdin update ref fails with wrong old value' '
558         echo "update $c $m $m~1" >stdin &&
559         test_must_fail git update-ref --stdin <stdin 2>err &&
560         grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
561         test_must_fail git rev-parse --verify -q $c
562 '
563
564 test_expect_success 'stdin update ref fails with bad old value' '
565         echo "update $c $m does-not-exist" >stdin &&
566         test_must_fail git update-ref --stdin <stdin 2>err &&
567         grep "fatal: update $c: invalid <oldvalue>: does-not-exist" err &&
568         test_must_fail git rev-parse --verify -q $c
569 '
570
571 test_expect_success 'stdin create ref fails with bad new value' '
572         echo "create $c does-not-exist" >stdin &&
573         test_must_fail git update-ref --stdin <stdin 2>err &&
574         grep "fatal: create $c: invalid <newvalue>: does-not-exist" err &&
575         test_must_fail git rev-parse --verify -q $c
576 '
577
578 test_expect_success 'stdin create ref fails with zero new value' '
579         echo "create $c " >stdin &&
580         test_must_fail git update-ref --stdin <stdin 2>err &&
581         grep "fatal: create $c: zero <newvalue>" err &&
582         test_must_fail git rev-parse --verify -q $c
583 '
584
585 test_expect_success 'stdin update ref works with right old value' '
586         echo "update $b $m~1 $m" >stdin &&
587         git update-ref --stdin <stdin &&
588         git rev-parse $m~1 >expect &&
589         git rev-parse $b >actual &&
590         test_cmp expect actual
591 '
592
593 test_expect_success 'stdin delete ref fails with wrong old value' '
594         echo "delete $a $m~1" >stdin &&
595         test_must_fail git update-ref --stdin <stdin 2>err &&
596         grep "fatal: cannot lock ref '"'"'$a'"'"'" err &&
597         git rev-parse $m >expect &&
598         git rev-parse $a >actual &&
599         test_cmp expect actual
600 '
601
602 test_expect_success 'stdin delete ref fails with zero old value' '
603         echo "delete $a " >stdin &&
604         test_must_fail git update-ref --stdin <stdin 2>err &&
605         grep "fatal: delete $a: zero <oldvalue>" err &&
606         git rev-parse $m >expect &&
607         git rev-parse $a >actual &&
608         test_cmp expect actual
609 '
610
611 test_expect_success 'stdin update symref works option no-deref' '
612         git symbolic-ref TESTSYMREF $b &&
613         cat >stdin <<-EOF &&
614         option no-deref
615         update TESTSYMREF $a $b
616         EOF
617         git update-ref --stdin <stdin &&
618         git rev-parse TESTSYMREF >expect &&
619         git rev-parse $a >actual &&
620         test_cmp expect actual &&
621         git rev-parse $m~1 >expect &&
622         git rev-parse $b >actual &&
623         test_cmp expect actual
624 '
625
626 test_expect_success 'stdin delete symref works option no-deref' '
627         git symbolic-ref TESTSYMREF $b &&
628         cat >stdin <<-EOF &&
629         option no-deref
630         delete TESTSYMREF $b
631         EOF
632         git update-ref --stdin <stdin &&
633         test_must_fail git rev-parse --verify -q TESTSYMREF &&
634         git rev-parse $m~1 >expect &&
635         git rev-parse $b >actual &&
636         test_cmp expect actual
637 '
638
639 test_expect_success 'stdin delete ref works with right old value' '
640         echo "delete $b $m~1" >stdin &&
641         git update-ref --stdin <stdin &&
642         test_must_fail git rev-parse --verify -q $b
643 '
644
645 test_expect_success 'stdin update/create/verify combination works' '
646         cat >stdin <<-EOF &&
647         update $a $m
648         create $b $m
649         verify $c
650         EOF
651         git update-ref --stdin <stdin &&
652         git rev-parse $m >expect &&
653         git rev-parse $a >actual &&
654         test_cmp expect actual &&
655         git rev-parse $b >actual &&
656         test_cmp expect actual &&
657         test_must_fail git rev-parse --verify -q $c
658 '
659
660 test_expect_success 'stdin verify succeeds for correct value' '
661         git rev-parse $m >expect &&
662         echo "verify $m $m" >stdin &&
663         git update-ref --stdin <stdin &&
664         git rev-parse $m >actual &&
665         test_cmp expect actual
666 '
667
668 test_expect_success 'stdin verify succeeds for missing reference' '
669         echo "verify refs/heads/missing $Z" >stdin &&
670         git update-ref --stdin <stdin &&
671         test_must_fail git rev-parse --verify -q refs/heads/missing
672 '
673
674 test_expect_success 'stdin verify treats no value as missing' '
675         echo "verify refs/heads/missing" >stdin &&
676         git update-ref --stdin <stdin &&
677         test_must_fail git rev-parse --verify -q refs/heads/missing
678 '
679
680 test_expect_success 'stdin verify fails for wrong value' '
681         git rev-parse $m >expect &&
682         echo "verify $m $m~1" >stdin &&
683         test_must_fail git update-ref --stdin <stdin &&
684         git rev-parse $m >actual &&
685         test_cmp expect actual
686 '
687
688 test_expect_success 'stdin verify fails for mistaken null value' '
689         git rev-parse $m >expect &&
690         echo "verify $m $Z" >stdin &&
691         test_must_fail git update-ref --stdin <stdin &&
692         git rev-parse $m >actual &&
693         test_cmp expect actual
694 '
695
696 test_expect_success 'stdin verify fails for mistaken empty value' '
697         M=$(git rev-parse $m) &&
698         test_when_finished "git update-ref $m $M" &&
699         git rev-parse $m >expect &&
700         echo "verify $m" >stdin &&
701         test_must_fail git update-ref --stdin <stdin &&
702         git rev-parse $m >actual &&
703         test_cmp expect actual
704 '
705
706 test_expect_success 'stdin update refs works with identity updates' '
707         cat >stdin <<-EOF &&
708         update $a $m $m
709         update $b $m $m
710         update $c $Z $E
711         EOF
712         git update-ref --stdin <stdin &&
713         git rev-parse $m >expect &&
714         git rev-parse $a >actual &&
715         test_cmp expect actual &&
716         git rev-parse $b >actual &&
717         test_cmp expect actual &&
718         test_must_fail git rev-parse --verify -q $c
719 '
720
721 test_expect_success 'stdin update refs fails with wrong old value' '
722         git update-ref $c $m &&
723         cat >stdin <<-EOF &&
724         update $a $m $m
725         update $b $m $m
726         update $c  ''
727         EOF
728         test_must_fail git update-ref --stdin <stdin 2>err &&
729         grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
730         git rev-parse $m >expect &&
731         git rev-parse $a >actual &&
732         test_cmp expect actual &&
733         git rev-parse $b >actual &&
734         test_cmp expect actual &&
735         git rev-parse $c >actual &&
736         test_cmp expect actual
737 '
738
739 test_expect_success 'stdin delete refs works with packed and loose refs' '
740         git pack-refs --all &&
741         git update-ref $c $m~1 &&
742         cat >stdin <<-EOF &&
743         delete $a $m
744         update $b $Z $m
745         update $c $E $m~1
746         EOF
747         git update-ref --stdin <stdin &&
748         test_must_fail git rev-parse --verify -q $a &&
749         test_must_fail git rev-parse --verify -q $b &&
750         test_must_fail git rev-parse --verify -q $c
751 '
752
753 test_expect_success 'stdin -z works on empty input' '
754         >stdin &&
755         git update-ref -z --stdin <stdin &&
756         git rev-parse --verify -q $m
757 '
758
759 test_expect_success 'stdin -z fails on empty line' '
760         echo "" >stdin &&
761         test_must_fail git update-ref -z --stdin <stdin 2>err &&
762         grep "fatal: whitespace before command: " err
763 '
764
765 test_expect_success 'stdin -z fails on empty command' '
766         printf $F "" >stdin &&
767         test_must_fail git update-ref -z --stdin <stdin 2>err &&
768         grep "fatal: empty command in input" err
769 '
770
771 test_expect_success 'stdin -z fails on only whitespace' '
772         printf $F " " >stdin &&
773         test_must_fail git update-ref -z --stdin <stdin 2>err &&
774         grep "fatal: whitespace before command:  " err
775 '
776
777 test_expect_success 'stdin -z fails on leading whitespace' '
778         printf $F " create $a" "$m" >stdin &&
779         test_must_fail git update-ref -z --stdin <stdin 2>err &&
780         grep "fatal: whitespace before command:  create $a" err
781 '
782
783 test_expect_success 'stdin -z fails on unknown command' '
784         printf $F "unknown $a" >stdin &&
785         test_must_fail git update-ref -z --stdin <stdin 2>err &&
786         grep "fatal: unknown command: unknown $a" err
787 '
788
789 test_expect_success 'stdin -z fails create with no ref' '
790         printf $F "create " >stdin &&
791         test_must_fail git update-ref -z --stdin <stdin 2>err &&
792         grep "fatal: create: missing <ref>" err
793 '
794
795 test_expect_success 'stdin -z fails create with no new value' '
796         printf $F "create $a" >stdin &&
797         test_must_fail git update-ref -z --stdin <stdin 2>err &&
798         grep "fatal: create $a: unexpected end of input when reading <newvalue>" err
799 '
800
801 test_expect_success 'stdin -z fails create with too many arguments' '
802         printf $F "create $a" "$m" "$m" >stdin &&
803         test_must_fail git update-ref -z --stdin <stdin 2>err &&
804         grep "fatal: unknown command: $m" err
805 '
806
807 test_expect_success 'stdin -z fails update with no ref' '
808         printf $F "update " >stdin &&
809         test_must_fail git update-ref -z --stdin <stdin 2>err &&
810         grep "fatal: update: missing <ref>" err
811 '
812
813 test_expect_success 'stdin -z fails update with too few args' '
814         printf $F "update $a" "$m" >stdin &&
815         test_must_fail git update-ref -z --stdin <stdin 2>err &&
816         grep "fatal: update $a: unexpected end of input when reading <oldvalue>" err
817 '
818
819 test_expect_success 'stdin -z emits warning with empty new value' '
820         git update-ref $a $m &&
821         printf $F "update $a" "" "" >stdin &&
822         git update-ref -z --stdin <stdin 2>err &&
823         grep "warning: update $a: missing <newvalue>, treating as zero" err &&
824         test_must_fail git rev-parse --verify -q $a
825 '
826
827 test_expect_success 'stdin -z fails update with no new value' '
828         printf $F "update $a" >stdin &&
829         test_must_fail git update-ref -z --stdin <stdin 2>err &&
830         grep "fatal: update $a: unexpected end of input when reading <newvalue>" err
831 '
832
833 test_expect_success 'stdin -z fails update with no old value' '
834         printf $F "update $a" "$m" >stdin &&
835         test_must_fail git update-ref -z --stdin <stdin 2>err &&
836         grep "fatal: update $a: unexpected end of input when reading <oldvalue>" err
837 '
838
839 test_expect_success 'stdin -z fails update with too many arguments' '
840         printf $F "update $a" "$m" "$m" "$m" >stdin &&
841         test_must_fail git update-ref -z --stdin <stdin 2>err &&
842         grep "fatal: unknown command: $m" err
843 '
844
845 test_expect_success 'stdin -z fails delete with no ref' '
846         printf $F "delete " >stdin &&
847         test_must_fail git update-ref -z --stdin <stdin 2>err &&
848         grep "fatal: delete: missing <ref>" err
849 '
850
851 test_expect_success 'stdin -z fails delete with no old value' '
852         printf $F "delete $a" >stdin &&
853         test_must_fail git update-ref -z --stdin <stdin 2>err &&
854         grep "fatal: delete $a: unexpected end of input when reading <oldvalue>" err
855 '
856
857 test_expect_success 'stdin -z fails delete with too many arguments' '
858         printf $F "delete $a" "$m" "$m" >stdin &&
859         test_must_fail git update-ref -z --stdin <stdin 2>err &&
860         grep "fatal: unknown command: $m" err
861 '
862
863 test_expect_success 'stdin -z fails verify with too many arguments' '
864         printf $F "verify $a" "$m" "$m" >stdin &&
865         test_must_fail git update-ref -z --stdin <stdin 2>err &&
866         grep "fatal: unknown command: $m" err
867 '
868
869 test_expect_success 'stdin -z fails verify with no old value' '
870         printf $F "verify $a" >stdin &&
871         test_must_fail git update-ref -z --stdin <stdin 2>err &&
872         grep "fatal: verify $a: unexpected end of input when reading <oldvalue>" err
873 '
874
875 test_expect_success 'stdin -z fails option with unknown name' '
876         printf $F "option unknown" >stdin &&
877         test_must_fail git update-ref -z --stdin <stdin 2>err &&
878         grep "fatal: option unknown: unknown" err
879 '
880
881 test_expect_success 'stdin -z fails with duplicate refs' '
882         printf $F "create $a" "$m" "create $b" "$m" "create $a" "$m" >stdin &&
883         test_must_fail git update-ref -z --stdin <stdin 2>err &&
884         grep "fatal: Multiple updates for ref '"'"'$a'"'"' not allowed." err
885 '
886
887 test_expect_success 'stdin -z create ref works' '
888         printf $F "create $a" "$m" >stdin &&
889         git update-ref -z --stdin <stdin &&
890         git rev-parse $m >expect &&
891         git rev-parse $a >actual &&
892         test_cmp expect actual
893 '
894
895 test_expect_success 'stdin -z update ref creates with zero old value' '
896         printf $F "update $b" "$m" "$Z" >stdin &&
897         git update-ref -z --stdin <stdin &&
898         git rev-parse $m >expect &&
899         git rev-parse $b >actual &&
900         test_cmp expect actual &&
901         git update-ref -d $b
902 '
903
904 test_expect_success 'stdin -z update ref creates with empty old value' '
905         printf $F "update $b" "$m" "" >stdin &&
906         git update-ref -z --stdin <stdin &&
907         git rev-parse $m >expect &&
908         git rev-parse $b >actual &&
909         test_cmp expect actual
910 '
911
912 test_expect_success 'stdin -z create ref works with path with space to blob' '
913         printf $F "create refs/blobs/pws" "$m:$pws" >stdin &&
914         git update-ref -z --stdin <stdin &&
915         git rev-parse "$m:$pws" >expect &&
916         git rev-parse refs/blobs/pws >actual &&
917         test_cmp expect actual &&
918         git update-ref -d refs/blobs/pws
919 '
920
921 test_expect_success 'stdin -z update ref fails with wrong old value' '
922         printf $F "update $c" "$m" "$m~1" >stdin &&
923         test_must_fail git update-ref -z --stdin <stdin 2>err &&
924         grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
925         test_must_fail git rev-parse --verify -q $c
926 '
927
928 test_expect_success 'stdin -z update ref fails with bad old value' '
929         printf $F "update $c" "$m" "does-not-exist" >stdin &&
930         test_must_fail git update-ref -z --stdin <stdin 2>err &&
931         grep "fatal: update $c: invalid <oldvalue>: does-not-exist" err &&
932         test_must_fail git rev-parse --verify -q $c
933 '
934
935 test_expect_success 'stdin -z create ref fails when ref exists' '
936         git update-ref $c $m &&
937         git rev-parse "$c" >expect &&
938         printf $F "create $c" "$m~1" >stdin &&
939         test_must_fail git update-ref -z --stdin <stdin 2>err &&
940         grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
941         git rev-parse "$c" >actual &&
942         test_cmp expect actual
943 '
944
945 test_expect_success 'stdin -z create ref fails with bad new value' '
946         git update-ref -d "$c" &&
947         printf $F "create $c" "does-not-exist" >stdin &&
948         test_must_fail git update-ref -z --stdin <stdin 2>err &&
949         grep "fatal: create $c: invalid <newvalue>: does-not-exist" err &&
950         test_must_fail git rev-parse --verify -q $c
951 '
952
953 test_expect_success 'stdin -z create ref fails with empty new value' '
954         printf $F "create $c" "" >stdin &&
955         test_must_fail git update-ref -z --stdin <stdin 2>err &&
956         grep "fatal: create $c: missing <newvalue>" err &&
957         test_must_fail git rev-parse --verify -q $c
958 '
959
960 test_expect_success 'stdin -z update ref works with right old value' '
961         printf $F "update $b" "$m~1" "$m" >stdin &&
962         git update-ref -z --stdin <stdin &&
963         git rev-parse $m~1 >expect &&
964         git rev-parse $b >actual &&
965         test_cmp expect actual
966 '
967
968 test_expect_success 'stdin -z delete ref fails with wrong old value' '
969         printf $F "delete $a" "$m~1" >stdin &&
970         test_must_fail git update-ref -z --stdin <stdin 2>err &&
971         grep "fatal: cannot lock ref '"'"'$a'"'"'" err &&
972         git rev-parse $m >expect &&
973         git rev-parse $a >actual &&
974         test_cmp expect actual
975 '
976
977 test_expect_success 'stdin -z delete ref fails with zero old value' '
978         printf $F "delete $a" "$Z" >stdin &&
979         test_must_fail git update-ref -z --stdin <stdin 2>err &&
980         grep "fatal: delete $a: zero <oldvalue>" err &&
981         git rev-parse $m >expect &&
982         git rev-parse $a >actual &&
983         test_cmp expect actual
984 '
985
986 test_expect_success 'stdin -z update symref works option no-deref' '
987         git symbolic-ref TESTSYMREF $b &&
988         printf $F "option no-deref" "update TESTSYMREF" "$a" "$b" >stdin &&
989         git update-ref -z --stdin <stdin &&
990         git rev-parse TESTSYMREF >expect &&
991         git rev-parse $a >actual &&
992         test_cmp expect actual &&
993         git rev-parse $m~1 >expect &&
994         git rev-parse $b >actual &&
995         test_cmp expect actual
996 '
997
998 test_expect_success 'stdin -z delete symref works option no-deref' '
999         git symbolic-ref TESTSYMREF $b &&
1000         printf $F "option no-deref" "delete TESTSYMREF" "$b" >stdin &&
1001         git update-ref -z --stdin <stdin &&
1002         test_must_fail git rev-parse --verify -q TESTSYMREF &&
1003         git rev-parse $m~1 >expect &&
1004         git rev-parse $b >actual &&
1005         test_cmp expect actual
1006 '
1007
1008 test_expect_success 'stdin -z delete ref works with right old value' '
1009         printf $F "delete $b" "$m~1" >stdin &&
1010         git update-ref -z --stdin <stdin &&
1011         test_must_fail git rev-parse --verify -q $b
1012 '
1013
1014 test_expect_success 'stdin -z update/create/verify combination works' '
1015         printf $F "update $a" "$m" "" "create $b" "$m" "verify $c" "" >stdin &&
1016         git update-ref -z --stdin <stdin &&
1017         git rev-parse $m >expect &&
1018         git rev-parse $a >actual &&
1019         test_cmp expect actual &&
1020         git rev-parse $b >actual &&
1021         test_cmp expect actual &&
1022         test_must_fail git rev-parse --verify -q $c
1023 '
1024
1025 test_expect_success 'stdin -z verify succeeds for correct value' '
1026         git rev-parse $m >expect &&
1027         printf $F "verify $m" "$m" >stdin &&
1028         git update-ref -z --stdin <stdin &&
1029         git rev-parse $m >actual &&
1030         test_cmp expect actual
1031 '
1032
1033 test_expect_success 'stdin -z verify succeeds for missing reference' '
1034         printf $F "verify refs/heads/missing" "$Z" >stdin &&
1035         git update-ref -z --stdin <stdin &&
1036         test_must_fail git rev-parse --verify -q refs/heads/missing
1037 '
1038
1039 test_expect_success 'stdin -z verify treats no value as missing' '
1040         printf $F "verify refs/heads/missing" "" >stdin &&
1041         git update-ref -z --stdin <stdin &&
1042         test_must_fail git rev-parse --verify -q refs/heads/missing
1043 '
1044
1045 test_expect_success 'stdin -z verify fails for wrong value' '
1046         git rev-parse $m >expect &&
1047         printf $F "verify $m" "$m~1" >stdin &&
1048         test_must_fail git update-ref -z --stdin <stdin &&
1049         git rev-parse $m >actual &&
1050         test_cmp expect actual
1051 '
1052
1053 test_expect_success 'stdin -z verify fails for mistaken null value' '
1054         git rev-parse $m >expect &&
1055         printf $F "verify $m" "$Z" >stdin &&
1056         test_must_fail git update-ref -z --stdin <stdin &&
1057         git rev-parse $m >actual &&
1058         test_cmp expect actual
1059 '
1060
1061 test_expect_success 'stdin -z verify fails for mistaken empty value' '
1062         M=$(git rev-parse $m) &&
1063         test_when_finished "git update-ref $m $M" &&
1064         git rev-parse $m >expect &&
1065         printf $F "verify $m" "" >stdin &&
1066         test_must_fail git update-ref -z --stdin <stdin &&
1067         git rev-parse $m >actual &&
1068         test_cmp expect actual
1069 '
1070
1071 test_expect_success 'stdin -z update refs works with identity updates' '
1072         printf $F "update $a" "$m" "$m" "update $b" "$m" "$m" "update $c" "$Z" "" >stdin &&
1073         git update-ref -z --stdin <stdin &&
1074         git rev-parse $m >expect &&
1075         git rev-parse $a >actual &&
1076         test_cmp expect actual &&
1077         git rev-parse $b >actual &&
1078         test_cmp expect actual &&
1079         test_must_fail git rev-parse --verify -q $c
1080 '
1081
1082 test_expect_success 'stdin -z update refs fails with wrong old value' '
1083         git update-ref $c $m &&
1084         printf $F "update $a" "$m" "$m" "update $b" "$m" "$m" "update $c" "$m" "$Z" >stdin &&
1085         test_must_fail git update-ref -z --stdin <stdin 2>err &&
1086         grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
1087         git rev-parse $m >expect &&
1088         git rev-parse $a >actual &&
1089         test_cmp expect actual &&
1090         git rev-parse $b >actual &&
1091         test_cmp expect actual &&
1092         git rev-parse $c >actual &&
1093         test_cmp expect actual
1094 '
1095
1096 test_expect_success 'stdin -z delete refs works with packed and loose refs' '
1097         git pack-refs --all &&
1098         git update-ref $c $m~1 &&
1099         printf $F "delete $a" "$m" "update $b" "$Z" "$m" "update $c" "" "$m~1" >stdin &&
1100         git update-ref -z --stdin <stdin &&
1101         test_must_fail git rev-parse --verify -q $a &&
1102         test_must_fail git rev-parse --verify -q $b &&
1103         test_must_fail git rev-parse --verify -q $c
1104 '
1105
1106 run_with_limited_open_files () {
1107         (ulimit -n 32 && "$@")
1108 }
1109
1110 test_lazy_prereq ULIMIT_FILE_DESCRIPTORS 'run_with_limited_open_files true'
1111
1112 test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction creating branches does not burst open file limit' '
1113 (
1114         for i in $(test_seq 33)
1115         do
1116                 echo "create refs/heads/$i HEAD"
1117         done >large_input &&
1118         run_with_limited_open_files git update-ref --stdin <large_input &&
1119         git rev-parse --verify -q refs/heads/33
1120 )
1121 '
1122
1123 test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction deleting branches does not burst open file limit' '
1124 (
1125         for i in $(test_seq 33)
1126         do
1127                 echo "delete refs/heads/$i HEAD"
1128         done >large_input &&
1129         run_with_limited_open_files git update-ref --stdin <large_input &&
1130         test_must_fail git rev-parse --verify -q refs/heads/33
1131 )
1132 '
1133
1134 test_done