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