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