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