3 # Copyright (c) 2006 Shawn Pearce
6 test_description
='Test git update-ref and basic ref logging'
17 create_test_commits
()
20 for name
in A B C D E F
23 T
=$
(git write-tree
) &&
24 sha1
=$
(echo $name | git commit-tree
$T) &&
29 test_expect_success setup
'
30 create_test_commits "" &&
34 create_test_commits "bare" &&
40 "git update-ref $m $A &&
41 test $A"' = $(cat .git/'"$m"')'
44 "git update-ref $m $B $A &&
45 test $B"' = $(cat .git/'"$m"')'
46 test_expect_success
"fail to delete $m with stale ref" '
47 test_must_fail git update-ref -d $m $A &&
48 test $B = "$(cat .git/$m)"
50 test_expect_success
"delete $m" '
51 git update-ref -d $m $B &&
56 test_expect_success
"delete $m without oldvalue verification" "
57 git update-ref $m $A &&
58 test $A = \$(cat .git/$m) &&
59 git update-ref -d $m &&
67 test_must_fail git update-ref $n $A >out 2>err"
68 rm -f .git
/$n_dir out err
71 "create $m (by HEAD)" \
72 "git update-ref HEAD $A &&
73 test $A"' = $(cat .git/'"$m"')'
75 "create $m (by HEAD)" \
76 "git update-ref HEAD $B $A &&
77 test $B"' = $(cat .git/'"$m"')'
78 test_expect_success
"fail to delete $m (by HEAD) with stale ref" '
79 test_must_fail git update-ref -d HEAD $A &&
80 test $B = $(cat .git/$m)
82 test_expect_success
"delete $m (by HEAD)" '
83 git update-ref -d HEAD $B &&
88 test_expect_success
"deleting current branch adds message to HEAD's log" '
89 git update-ref $m $A &&
90 git symbolic-ref HEAD $m &&
91 git update-ref -m delete-$m -d $m &&
93 grep "delete-$m$" .git/logs/HEAD
97 test_expect_success
"deleting by HEAD adds message to HEAD's log" '
98 git update-ref $m $A &&
99 git symbolic-ref HEAD $m &&
100 git update-ref -m delete-by-head -d HEAD &&
102 grep "delete-by-head$" .git/logs/HEAD
106 test_expect_success
'update-ref does not create reflogs by default' '
107 test_when_finished "git update-ref -d $outside" &&
108 git update-ref $outside $A &&
109 git rev-parse $A >expect &&
110 git rev-parse $outside >actual &&
111 test_cmp expect actual &&
112 test_must_fail git reflog exists $outside
115 test_expect_success
'update-ref creates reflogs with --create-reflog' '
116 test_when_finished "git update-ref -d $outside" &&
117 git update-ref --create-reflog $outside $A &&
118 git rev-parse $A >expect &&
119 git rev-parse $outside >actual &&
120 test_cmp expect actual &&
121 git reflog exists $outside
124 test_expect_success
'creates no reflog in bare repository' '
125 git -C $bare update-ref $m $bareA &&
126 git -C $bare rev-parse $bareA >expect &&
127 git -C $bare rev-parse $m >actual &&
128 test_cmp expect actual &&
129 test_must_fail git -C $bare reflog exists $m
132 test_expect_success
'core.logAllRefUpdates=true creates reflog in bare repository' '
133 test_when_finished "git -C $bare config --unset core.logAllRefUpdates && \
135 git -C $bare config core.logAllRefUpdates true &&
136 git -C $bare update-ref $m $bareB &&
137 git -C $bare rev-parse $bareB >expect &&
138 git -C $bare rev-parse $m >actual &&
139 test_cmp expect actual &&
140 git -C $bare reflog exists $m
143 test_expect_success
'core.logAllRefUpdates=true does not create reflog by default' '
144 test_config core.logAllRefUpdates true &&
145 test_when_finished "git update-ref -d $outside" &&
146 git update-ref $outside $A &&
147 git rev-parse $A >expect &&
148 git rev-parse $outside >actual &&
149 test_cmp expect actual &&
150 test_must_fail git reflog exists $outside
153 test_expect_success
'core.logAllRefUpdates=always creates reflog by default' '
154 test_config core.logAllRefUpdates always &&
155 test_when_finished "git update-ref -d $outside" &&
156 git update-ref $outside $A &&
157 git rev-parse $A >expect &&
158 git rev-parse $outside >actual &&
159 test_cmp expect actual &&
160 git reflog exists $outside
163 test_expect_success
'core.logAllRefUpdates=always creates no reflog for ORIG_HEAD' '
164 test_config core.logAllRefUpdates always &&
165 git update-ref ORIG_HEAD $A &&
166 test_must_fail git reflog exists ORIG_HEAD
169 test_expect_success
'--no-create-reflog overrides core.logAllRefUpdates=always' '
170 test_config core.logAllRefUpdates true &&
171 test_when_finished "git update-ref -d $outside" &&
172 git update-ref --no-create-reflog $outside $A &&
173 git rev-parse $A >expect &&
174 git rev-parse $outside >actual &&
175 test_cmp expect actual &&
176 test_must_fail git reflog exists $outside
179 test_expect_success \
180 "create $m (by HEAD)" \
181 "git update-ref HEAD $A &&
182 test $A"' = $(cat .git/'"$m"')'
183 test_expect_success \
185 "git pack-refs --all"
186 test_expect_success \
187 "move $m (by HEAD)" \
188 "git update-ref HEAD $B $A &&
189 test $B"' = $(cat .git/'"$m"')'
190 test_expect_success
"delete $m (by HEAD) should remove both packed and loose $m" '
191 git update-ref -d HEAD $B &&
192 ! grep "$m" .git/packed-refs &&
197 cp -f .git
/HEAD .git
/HEAD.orig
198 test_expect_success
"delete symref without dereference" '
199 git update-ref --no-deref -d HEAD &&
202 cp -f .git
/HEAD.orig .git
/HEAD
204 test_expect_success
"delete symref without dereference when the referred ref is packed" '
208 git pack-refs --all &&
209 git update-ref --no-deref -d HEAD &&
212 cp -f .git
/HEAD.orig .git
/HEAD
215 test_expect_success
'update-ref -d is not confused by self-reference' '
216 git symbolic-ref refs/heads/self refs/heads/self &&
217 test_when_finished "rm -f .git/refs/heads/self" &&
218 test_path_is_file .git/refs/heads/self &&
219 test_must_fail git update-ref -d refs/heads/self &&
220 test_path_is_file .git/refs/heads/self
223 test_expect_success
'update-ref --no-deref -d can delete 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 git update-ref --no-deref -d refs/heads/self &&
228 test_path_is_missing .git/refs/heads/self
231 test_expect_success
'update-ref --no-deref -d can delete reference to bad ref' '
232 >.git/refs/heads/bad &&
233 test_when_finished "rm -f .git/refs/heads/bad" &&
234 git symbolic-ref refs/heads/ref-to-bad refs/heads/bad &&
235 test_when_finished "rm -f .git/refs/heads/ref-to-bad" &&
236 test_path_is_file .git/refs/heads/ref-to-bad &&
237 git update-ref --no-deref -d refs/heads/ref-to-bad &&
238 test_path_is_missing .git/refs/heads/ref-to-bad
241 test_expect_success
'(not) create HEAD with old sha1' "
242 test_must_fail git update-ref HEAD $A $B
244 test_expect_success
"(not) prior created .git/$m" "
249 test_expect_success \
251 "git update-ref HEAD $A"
252 test_expect_success
'(not) change HEAD with wrong SHA1' "
253 test_must_fail git update-ref HEAD $B $Z
255 test_expect_success
"(not) changed .git/$m" "
256 ! test $B"' = $(cat .git/'"$m"')
260 rm -f .git
/logs
/refs
/heads
/master
261 test_expect_success \
262 "create $m (logged by touch)" \
263 'GIT_COMMITTER_DATE="2005-05-26 23:30" \
264 git update-ref --create-reflog HEAD '"$A"' -m "Initial Creation" &&
265 test '"$A"' = $(cat .git/'"$m"')'
266 test_expect_success \
267 "update $m (logged by touch)" \
268 'GIT_COMMITTER_DATE="2005-05-26 23:31" \
269 git update-ref HEAD'" $B $A "'-m "Switch" &&
270 test '"$B"' = $(cat .git/'"$m"')'
271 test_expect_success \
272 "set $m (logged by touch)" \
273 'GIT_COMMITTER_DATE="2005-05-26 23:41" \
274 git update-ref HEAD'" $A &&
275 test $A"' = $(cat .git/'"$m"')'
277 test_expect_success
"empty directory removal" '
278 git branch d1/d2/r1 HEAD &&
279 git branch d1/r2 HEAD &&
280 test -f .git/refs/heads/d1/d2/r1 &&
281 test -f .git/logs/refs/heads/d1/d2/r1 &&
282 git branch -d d1/d2/r1 &&
283 ! test -e .git/refs/heads/d1/d2 &&
284 ! test -e .git/logs/refs/heads/d1/d2 &&
285 test -f .git/refs/heads/d1/r2 &&
286 test -f .git/logs/refs/heads/d1/r2
289 test_expect_success
"symref empty directory removal" '
290 git branch e1/e2/r1 HEAD &&
291 git branch e1/r2 HEAD &&
292 git checkout e1/e2/r1 &&
293 test_when_finished "git checkout master" &&
294 test -f .git/refs/heads/e1/e2/r1 &&
295 test -f .git/logs/refs/heads/e1/e2/r1 &&
296 git update-ref -d HEAD &&
297 ! test -e .git/refs/heads/e1/e2 &&
298 ! test -e .git/logs/refs/heads/e1/e2 &&
299 test -f .git/refs/heads/e1/r2 &&
300 test -f .git/logs/refs/heads/e1/r2 &&
301 test -f .git/logs/HEAD
305 $Z $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 Initial Creation
306 $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150260 +0000 Switch
307 $B $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150860 +0000
309 test_expect_success \
310 "verifying $m's log" \
311 "test_cmp expect .git/logs/$m"
312 rm -rf .git
/$m .git
/logs expect
314 test_expect_success \
315 'enable core.logAllRefUpdates' \
316 'git config core.logAllRefUpdates true &&
317 test true = $(git config --bool --get core.logAllRefUpdates)'
319 test_expect_success \
320 "create $m (logged by config)" \
321 'GIT_COMMITTER_DATE="2005-05-26 23:32" \
322 git update-ref HEAD'" $A "'-m "Initial Creation" &&
323 test '"$A"' = $(cat .git/'"$m"')'
324 test_expect_success \
325 "update $m (logged by config)" \
326 'GIT_COMMITTER_DATE="2005-05-26 23:33" \
327 git update-ref HEAD'" $B $A "'-m "Switch" &&
328 test '"$B"' = $(cat .git/'"$m"')'
329 test_expect_success \
330 "set $m (logged by config)" \
331 'GIT_COMMITTER_DATE="2005-05-26 23:43" \
332 git update-ref HEAD '"$A &&
333 test $A"' = $(cat .git/'"$m"')'
336 $Z $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150320 +0000 Initial Creation
337 $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 +0000 Switch
338 $B $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 +0000
340 test_expect_success \
341 "verifying $m's log" \
342 'test_cmp expect .git/logs/$m'
343 rm -f .git
/$m .git
/logs
/$m expect
346 cat >.git
/logs
/$m <<EOF
347 0000000000000000000000000000000000000000 $C $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150320 -0500
348 $C $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150350 -0500
349 $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 -0500
350 $F $Z $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150680 -0500
351 $Z $E $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 -0500
354 ed
="Thu, 26 May 2005 18:32:00 -0500"
355 gd
="Thu, 26 May 2005 18:33:00 -0500"
356 ld
="Thu, 26 May 2005 18:43:00 -0500"
357 test_expect_success \
358 'Query "master@{May 25 2005}" (before history)' \
360 git rev-parse --verify "master@{May 25 2005}" >o 2>e &&
361 test '"$C"' = $(cat o) &&
362 test "warning: Log for '\'master
\'' only goes back to $ed." = "$(cat e)"'
363 test_expect_success \
364 "Query master@{2005-05-25} (before history)" \
366 git rev-parse --verify master@{2005-05-25} >o 2>e &&
367 test '"$C"' = $(cat o) &&
368 echo test "warning: Log for '\'master
\'' only goes back to $ed." = "$(cat e)"'
369 test_expect_success \
370 'Query "master@{May 26 2005 23:31:59}" (1 second before history)' \
372 git rev-parse --verify "master@{May 26 2005 23:31:59}" >o 2>e &&
373 test '"$C"' = $(cat o) &&
374 test "warning: Log for '\''master'\'' only goes back to $ed." = "$(cat e)"'
375 test_expect_success \
376 'Query "master@{May 26 2005 23:32:00}" (exactly history start)' \
378 git rev-parse --verify "master@{May 26 2005 23:32:00}" >o 2>e &&
379 test '"$C"' = $(cat o) &&
380 test "" = "$(cat e)"'
381 test_expect_success \
382 'Query "master@{May 26 2005 23:32:30}" (first non-creation change)' \
384 git rev-parse --verify "master@{May 26 2005 23:32:30}" >o 2>e &&
385 test '"$A"' = $(cat o) &&
386 test "" = "$(cat e)"'
387 test_expect_success \
388 'Query "master@{2005-05-26 23:33:01}" (middle of history with gap)' \
390 git rev-parse --verify "master@{2005-05-26 23:33:01}" >o 2>e &&
391 test '"$B"' = $(cat o) &&
392 test "warning: Log for ref '"$m has gap after $gd"'." = "$(cat e)"'
393 test_expect_success \
394 'Query "master@{2005-05-26 23:38:00}" (middle of history)' \
396 git rev-parse --verify "master@{2005-05-26 23:38:00}" >o 2>e &&
397 test '"$Z"' = $(cat o) &&
398 test "" = "$(cat e)"'
399 test_expect_success \
400 'Query "master@{2005-05-26 23:43:00}" (exact end of history)' \
402 git rev-parse --verify "master@{2005-05-26 23:43:00}" >o 2>e &&
403 test '"$E"' = $(cat o) &&
404 test "" = "$(cat e)"'
405 test_expect_success \
406 'Query "master@{2005-05-28}" (past end of history)' \
408 git rev-parse --verify "master@{2005-05-28}" >o 2>e &&
409 test '"$D"' = $(cat o) &&
410 test "warning: Log for ref '"$m unexpectedly ended on $ld"'." = "$(cat e)"'
413 rm -f .git
/$m .git
/logs
/$m expect
415 test_expect_success \
416 'creating initial files' \
419 GIT_AUTHOR_DATE="2005-05-26 23:30" \
420 GIT_COMMITTER_DATE="2005-05-26 23:30" git commit -m add -a &&
421 h_TEST=$(git rev-parse --verify HEAD) &&
422 echo The other day this did not work. >M &&
423 echo And then Bob told me how to fix it. >>M &&
425 GIT_AUTHOR_DATE="2005-05-26 23:41" \
426 GIT_COMMITTER_DATE="2005-05-26 23:41" git commit -F M -a &&
427 h_OTHER=$(git rev-parse --verify HEAD) &&
428 GIT_AUTHOR_DATE="2005-05-26 23:44" \
429 GIT_COMMITTER_DATE="2005-05-26 23:44" git commit --amend &&
430 h_FIXED=$(git rev-parse --verify HEAD) &&
431 echo Merged initial commit and a later commit. >M &&
432 echo $h_TEST >.git/MERGE_HEAD &&
433 GIT_AUTHOR_DATE="2005-05-26 23:45" \
434 GIT_COMMITTER_DATE="2005-05-26 23:45" git commit -F M &&
435 h_MERGED=$(git rev-parse --verify HEAD) &&
439 $Z $h_TEST $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 commit (initial): add
440 $h_TEST $h_OTHER $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150860 +0000 commit: The other day this did not work.
441 $h_OTHER $h_FIXED $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117151040 +0000 commit (amend): The other day this did not work.
442 $h_FIXED $h_MERGED $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117151100 +0000 commit (merge): Merged initial commit and a later commit.
444 test_expect_success \
445 'git commit logged updates' \
446 "test_cmp expect .git/logs/$m"
447 unset h_TEST h_OTHER h_FIXED h_MERGED
449 test_expect_success \
450 'git cat-file blob master:F (expect OTHER)' \
451 'test OTHER = $(git cat-file blob master:F)'
452 test_expect_success \
453 'git cat-file blob master@{2005-05-26 23:30}:F (expect TEST)' \
454 'test TEST = $(git cat-file blob "master@{2005-05-26 23:30}:F")'
455 test_expect_success \
456 'git cat-file blob master@{2005-05-26 23:42}:F (expect OTHER)' \
457 'test OTHER = $(git cat-file blob "master@{2005-05-26 23:42}:F")'
464 pws
='path with space'
466 test_expect_success
'stdin test setup' '
467 echo "$pws" >"$pws" &&
472 test_expect_success
'-z fails without --stdin' '
473 test_must_fail git update-ref -z $m $m $m 2>err &&
474 test_i18ngrep "usage: git update-ref" err
477 test_expect_success
'stdin works with no input' '
479 git update-ref --stdin <stdin &&
480 git rev-parse --verify -q $m
483 test_expect_success
'stdin fails on empty line' '
485 test_must_fail git update-ref --stdin <stdin 2>err &&
486 grep "fatal: empty command in input" err
489 test_expect_success
'stdin fails on only whitespace' '
491 test_must_fail git update-ref --stdin <stdin 2>err &&
492 grep "fatal: whitespace before command: " err
495 test_expect_success
'stdin fails on leading whitespace' '
496 echo " create $a $m" >stdin &&
497 test_must_fail git update-ref --stdin <stdin 2>err &&
498 grep "fatal: whitespace before command: create $a $m" err
501 test_expect_success
'stdin fails on unknown command' '
502 echo "unknown $a" >stdin &&
503 test_must_fail git update-ref --stdin <stdin 2>err &&
504 grep "fatal: unknown command: unknown $a" err
507 test_expect_success
'stdin fails on unbalanced quotes' '
508 echo "create $a \"master" >stdin &&
509 test_must_fail git update-ref --stdin <stdin 2>err &&
510 grep "fatal: badly quoted argument: \\\"master" err
513 test_expect_success
'stdin fails on invalid escape' '
514 echo "create $a \"ma\zter\"" >stdin &&
515 test_must_fail git update-ref --stdin <stdin 2>err &&
516 grep "fatal: badly quoted argument: \\\"ma\\\\zter\\\"" err
519 test_expect_success
'stdin fails on junk after quoted argument' '
520 echo "create \"$a\"master" >stdin &&
521 test_must_fail git update-ref --stdin <stdin 2>err &&
522 grep "fatal: unexpected character after quoted argument: \\\"$a\\\"master" err
525 test_expect_success
'stdin fails create with no ref' '
526 echo "create " >stdin &&
527 test_must_fail git update-ref --stdin <stdin 2>err &&
528 grep "fatal: create: missing <ref>" err
531 test_expect_success
'stdin fails create with no new value' '
532 echo "create $a" >stdin &&
533 test_must_fail git update-ref --stdin <stdin 2>err &&
534 grep "fatal: create $a: missing <newvalue>" err
537 test_expect_success
'stdin fails create with too many arguments' '
538 echo "create $a $m $m" >stdin &&
539 test_must_fail git update-ref --stdin <stdin 2>err &&
540 grep "fatal: create $a: extra input: $m" err
543 test_expect_success
'stdin fails update with no ref' '
544 echo "update " >stdin &&
545 test_must_fail git update-ref --stdin <stdin 2>err &&
546 grep "fatal: update: missing <ref>" err
549 test_expect_success
'stdin fails update with no new value' '
550 echo "update $a" >stdin &&
551 test_must_fail git update-ref --stdin <stdin 2>err &&
552 grep "fatal: update $a: missing <newvalue>" err
555 test_expect_success
'stdin fails update with too many arguments' '
556 echo "update $a $m $m $m" >stdin &&
557 test_must_fail git update-ref --stdin <stdin 2>err &&
558 grep "fatal: update $a: extra input: $m" err
561 test_expect_success
'stdin fails delete with no ref' '
562 echo "delete " >stdin &&
563 test_must_fail git update-ref --stdin <stdin 2>err &&
564 grep "fatal: delete: missing <ref>" err
567 test_expect_success
'stdin fails delete with too many arguments' '
568 echo "delete $a $m $m" >stdin &&
569 test_must_fail git update-ref --stdin <stdin 2>err &&
570 grep "fatal: delete $a: extra input: $m" err
573 test_expect_success
'stdin fails verify with too many arguments' '
574 echo "verify $a $m $m" >stdin &&
575 test_must_fail git update-ref --stdin <stdin 2>err &&
576 grep "fatal: verify $a: extra input: $m" err
579 test_expect_success
'stdin fails option with unknown name' '
580 echo "option unknown" >stdin &&
581 test_must_fail git update-ref --stdin <stdin 2>err &&
582 grep "fatal: option unknown: unknown" err
585 test_expect_success
'stdin fails with duplicate refs' '
591 test_must_fail git update-ref --stdin <stdin 2>err &&
592 grep "fatal: multiple updates for ref '"'"'$a'"'"' not allowed." err
595 test_expect_success
'stdin create ref works' '
596 echo "create $a $m" >stdin &&
597 git update-ref --stdin <stdin &&
598 git rev-parse $m >expect &&
599 git rev-parse $a >actual &&
600 test_cmp expect actual
603 test_expect_success
'stdin does not create reflogs by default' '
604 test_when_finished "git update-ref -d $outside" &&
605 echo "create $outside $m" >stdin &&
606 git update-ref --stdin <stdin &&
607 git rev-parse $m >expect &&
608 git rev-parse $outside >actual &&
609 test_cmp expect actual &&
610 test_must_fail git reflog exists $outside
613 test_expect_success
'stdin creates reflogs with --create-reflog' '
614 test_when_finished "git update-ref -d $outside" &&
615 echo "create $outside $m" >stdin &&
616 git update-ref --create-reflog --stdin <stdin &&
617 git rev-parse $m >expect &&
618 git rev-parse $outside >actual &&
619 test_cmp expect actual &&
620 git reflog exists $outside
623 test_expect_success
'stdin succeeds with quoted argument' '
624 git update-ref -d $a &&
625 echo "create $a \"$m\"" >stdin &&
626 git update-ref --stdin <stdin &&
627 git rev-parse $m >expect &&
628 git rev-parse $a >actual &&
629 test_cmp expect actual
632 test_expect_success
'stdin succeeds with escaped character' '
633 git update-ref -d $a &&
634 echo "create $a \"ma\\163ter\"" >stdin &&
635 git update-ref --stdin <stdin &&
636 git rev-parse $m >expect &&
637 git rev-parse $a >actual &&
638 test_cmp expect actual
641 test_expect_success
'stdin update ref creates with zero old value' '
642 echo "update $b $m $Z" >stdin &&
643 git update-ref --stdin <stdin &&
644 git rev-parse $m >expect &&
645 git rev-parse $b >actual &&
646 test_cmp expect actual &&
650 test_expect_success
'stdin update ref creates with empty old value' '
651 echo "update $b $m $E" >stdin &&
652 git update-ref --stdin <stdin &&
653 git rev-parse $m >expect &&
654 git rev-parse $b >actual &&
655 test_cmp expect actual
658 test_expect_success
'stdin create ref works with path with space to blob' '
659 echo "create refs/blobs/pws \"$m:$pws\"" >stdin &&
660 git update-ref --stdin <stdin &&
661 git rev-parse "$m:$pws" >expect &&
662 git rev-parse refs/blobs/pws >actual &&
663 test_cmp expect actual &&
664 git update-ref -d refs/blobs/pws
667 test_expect_success
'stdin update ref fails with wrong old value' '
668 echo "update $c $m $m~1" >stdin &&
669 test_must_fail git update-ref --stdin <stdin 2>err &&
670 grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
671 test_must_fail git rev-parse --verify -q $c
674 test_expect_success
'stdin update ref fails with bad old value' '
675 echo "update $c $m does-not-exist" >stdin &&
676 test_must_fail git update-ref --stdin <stdin 2>err &&
677 grep "fatal: update $c: invalid <oldvalue>: does-not-exist" err &&
678 test_must_fail git rev-parse --verify -q $c
681 test_expect_success
'stdin create ref fails with bad new value' '
682 echo "create $c does-not-exist" >stdin &&
683 test_must_fail git update-ref --stdin <stdin 2>err &&
684 grep "fatal: create $c: invalid <newvalue>: does-not-exist" err &&
685 test_must_fail git rev-parse --verify -q $c
688 test_expect_success
'stdin create ref fails with zero new value' '
689 echo "create $c " >stdin &&
690 test_must_fail git update-ref --stdin <stdin 2>err &&
691 grep "fatal: create $c: zero <newvalue>" err &&
692 test_must_fail git rev-parse --verify -q $c
695 test_expect_success
'stdin update ref works with right old value' '
696 echo "update $b $m~1 $m" >stdin &&
697 git update-ref --stdin <stdin &&
698 git rev-parse $m~1 >expect &&
699 git rev-parse $b >actual &&
700 test_cmp expect actual
703 test_expect_success
'stdin delete ref fails with wrong old value' '
704 echo "delete $a $m~1" >stdin &&
705 test_must_fail git update-ref --stdin <stdin 2>err &&
706 grep "fatal: cannot lock ref '"'"'$a'"'"'" err &&
707 git rev-parse $m >expect &&
708 git rev-parse $a >actual &&
709 test_cmp expect actual
712 test_expect_success
'stdin delete ref fails with zero old value' '
713 echo "delete $a " >stdin &&
714 test_must_fail git update-ref --stdin <stdin 2>err &&
715 grep "fatal: delete $a: zero <oldvalue>" err &&
716 git rev-parse $m >expect &&
717 git rev-parse $a >actual &&
718 test_cmp expect actual
721 test_expect_success
'stdin update symref works option no-deref' '
722 git symbolic-ref TESTSYMREF $b &&
725 update TESTSYMREF $a $b
727 git update-ref --stdin <stdin &&
728 git rev-parse TESTSYMREF >expect &&
729 git rev-parse $a >actual &&
730 test_cmp expect actual &&
731 git rev-parse $m~1 >expect &&
732 git rev-parse $b >actual &&
733 test_cmp expect actual
736 test_expect_success
'stdin delete symref works option no-deref' '
737 git symbolic-ref TESTSYMREF $b &&
742 git update-ref --stdin <stdin &&
743 test_must_fail git rev-parse --verify -q TESTSYMREF &&
744 git rev-parse $m~1 >expect &&
745 git rev-parse $b >actual &&
746 test_cmp expect actual
749 test_expect_success
'stdin delete ref works with right old value' '
750 echo "delete $b $m~1" >stdin &&
751 git update-ref --stdin <stdin &&
752 test_must_fail git rev-parse --verify -q $b
755 test_expect_success
'stdin update/create/verify combination works' '
761 git update-ref --stdin <stdin &&
762 git rev-parse $m >expect &&
763 git rev-parse $a >actual &&
764 test_cmp expect actual &&
765 git rev-parse $b >actual &&
766 test_cmp expect actual &&
767 test_must_fail git rev-parse --verify -q $c
770 test_expect_success
'stdin verify succeeds for correct value' '
771 git rev-parse $m >expect &&
772 echo "verify $m $m" >stdin &&
773 git update-ref --stdin <stdin &&
774 git rev-parse $m >actual &&
775 test_cmp expect actual
778 test_expect_success
'stdin verify succeeds for missing reference' '
779 echo "verify refs/heads/missing $Z" >stdin &&
780 git update-ref --stdin <stdin &&
781 test_must_fail git rev-parse --verify -q refs/heads/missing
784 test_expect_success
'stdin verify treats no value as missing' '
785 echo "verify refs/heads/missing" >stdin &&
786 git update-ref --stdin <stdin &&
787 test_must_fail git rev-parse --verify -q refs/heads/missing
790 test_expect_success
'stdin verify fails for wrong value' '
791 git rev-parse $m >expect &&
792 echo "verify $m $m~1" >stdin &&
793 test_must_fail git update-ref --stdin <stdin &&
794 git rev-parse $m >actual &&
795 test_cmp expect actual
798 test_expect_success
'stdin verify fails for mistaken null value' '
799 git rev-parse $m >expect &&
800 echo "verify $m $Z" >stdin &&
801 test_must_fail git update-ref --stdin <stdin &&
802 git rev-parse $m >actual &&
803 test_cmp expect actual
806 test_expect_success
'stdin verify fails for mistaken empty value' '
807 M=$(git rev-parse $m) &&
808 test_when_finished "git update-ref $m $M" &&
809 git rev-parse $m >expect &&
810 echo "verify $m" >stdin &&
811 test_must_fail git update-ref --stdin <stdin &&
812 git rev-parse $m >actual &&
813 test_cmp expect actual
816 test_expect_success
'stdin update refs works with identity updates' '
822 git update-ref --stdin <stdin &&
823 git rev-parse $m >expect &&
824 git rev-parse $a >actual &&
825 test_cmp expect actual &&
826 git rev-parse $b >actual &&
827 test_cmp expect actual &&
828 test_must_fail git rev-parse --verify -q $c
831 test_expect_success
'stdin update refs fails with wrong old value' '
832 git update-ref $c $m &&
838 test_must_fail git update-ref --stdin <stdin 2>err &&
839 grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
840 git rev-parse $m >expect &&
841 git rev-parse $a >actual &&
842 test_cmp expect actual &&
843 git rev-parse $b >actual &&
844 test_cmp expect actual &&
845 git rev-parse $c >actual &&
846 test_cmp expect actual
849 test_expect_success
'stdin delete refs works with packed and loose refs' '
850 git pack-refs --all &&
851 git update-ref $c $m~1 &&
857 git update-ref --stdin <stdin &&
858 test_must_fail git rev-parse --verify -q $a &&
859 test_must_fail git rev-parse --verify -q $b &&
860 test_must_fail git rev-parse --verify -q $c
863 test_expect_success
'stdin -z works on empty input' '
865 git update-ref -z --stdin <stdin &&
866 git rev-parse --verify -q $m
869 test_expect_success
'stdin -z fails on empty line' '
871 test_must_fail git update-ref -z --stdin <stdin 2>err &&
872 grep "fatal: whitespace before command: " err
875 test_expect_success
'stdin -z fails on empty command' '
876 printf $F "" >stdin &&
877 test_must_fail git update-ref -z --stdin <stdin 2>err &&
878 grep "fatal: empty command in input" err
881 test_expect_success
'stdin -z fails on only whitespace' '
882 printf $F " " >stdin &&
883 test_must_fail git update-ref -z --stdin <stdin 2>err &&
884 grep "fatal: whitespace before command: " err
887 test_expect_success
'stdin -z fails on leading whitespace' '
888 printf $F " create $a" "$m" >stdin &&
889 test_must_fail git update-ref -z --stdin <stdin 2>err &&
890 grep "fatal: whitespace before command: create $a" err
893 test_expect_success
'stdin -z fails on unknown command' '
894 printf $F "unknown $a" >stdin &&
895 test_must_fail git update-ref -z --stdin <stdin 2>err &&
896 grep "fatal: unknown command: unknown $a" err
899 test_expect_success
'stdin -z fails create with no ref' '
900 printf $F "create " >stdin &&
901 test_must_fail git update-ref -z --stdin <stdin 2>err &&
902 grep "fatal: create: missing <ref>" err
905 test_expect_success
'stdin -z fails create with no new value' '
906 printf $F "create $a" >stdin &&
907 test_must_fail git update-ref -z --stdin <stdin 2>err &&
908 grep "fatal: create $a: unexpected end of input when reading <newvalue>" err
911 test_expect_success
'stdin -z fails create with too many arguments' '
912 printf $F "create $a" "$m" "$m" >stdin &&
913 test_must_fail git update-ref -z --stdin <stdin 2>err &&
914 grep "fatal: unknown command: $m" err
917 test_expect_success
'stdin -z fails update with no ref' '
918 printf $F "update " >stdin &&
919 test_must_fail git update-ref -z --stdin <stdin 2>err &&
920 grep "fatal: update: missing <ref>" err
923 test_expect_success
'stdin -z fails update with too few args' '
924 printf $F "update $a" "$m" >stdin &&
925 test_must_fail git update-ref -z --stdin <stdin 2>err &&
926 grep "fatal: update $a: unexpected end of input when reading <oldvalue>" err
929 test_expect_success
'stdin -z emits warning with empty new value' '
930 git update-ref $a $m &&
931 printf $F "update $a" "" "" >stdin &&
932 git update-ref -z --stdin <stdin 2>err &&
933 grep "warning: update $a: missing <newvalue>, treating as zero" err &&
934 test_must_fail git rev-parse --verify -q $a
937 test_expect_success
'stdin -z fails update with no new value' '
938 printf $F "update $a" >stdin &&
939 test_must_fail git update-ref -z --stdin <stdin 2>err &&
940 grep "fatal: update $a: unexpected end of input when reading <newvalue>" err
943 test_expect_success
'stdin -z fails update with no old value' '
944 printf $F "update $a" "$m" >stdin &&
945 test_must_fail git update-ref -z --stdin <stdin 2>err &&
946 grep "fatal: update $a: unexpected end of input when reading <oldvalue>" err
949 test_expect_success
'stdin -z fails update with too many arguments' '
950 printf $F "update $a" "$m" "$m" "$m" >stdin &&
951 test_must_fail git update-ref -z --stdin <stdin 2>err &&
952 grep "fatal: unknown command: $m" err
955 test_expect_success
'stdin -z fails delete with no ref' '
956 printf $F "delete " >stdin &&
957 test_must_fail git update-ref -z --stdin <stdin 2>err &&
958 grep "fatal: delete: missing <ref>" err
961 test_expect_success
'stdin -z fails delete with no old value' '
962 printf $F "delete $a" >stdin &&
963 test_must_fail git update-ref -z --stdin <stdin 2>err &&
964 grep "fatal: delete $a: unexpected end of input when reading <oldvalue>" err
967 test_expect_success
'stdin -z fails delete with too many arguments' '
968 printf $F "delete $a" "$m" "$m" >stdin &&
969 test_must_fail git update-ref -z --stdin <stdin 2>err &&
970 grep "fatal: unknown command: $m" err
973 test_expect_success
'stdin -z fails verify with too many arguments' '
974 printf $F "verify $a" "$m" "$m" >stdin &&
975 test_must_fail git update-ref -z --stdin <stdin 2>err &&
976 grep "fatal: unknown command: $m" err
979 test_expect_success
'stdin -z fails verify with no old value' '
980 printf $F "verify $a" >stdin &&
981 test_must_fail git update-ref -z --stdin <stdin 2>err &&
982 grep "fatal: verify $a: unexpected end of input when reading <oldvalue>" err
985 test_expect_success
'stdin -z fails option with unknown name' '
986 printf $F "option unknown" >stdin &&
987 test_must_fail git update-ref -z --stdin <stdin 2>err &&
988 grep "fatal: option unknown: unknown" err
991 test_expect_success
'stdin -z fails with duplicate refs' '
992 printf $F "create $a" "$m" "create $b" "$m" "create $a" "$m" >stdin &&
993 test_must_fail git update-ref -z --stdin <stdin 2>err &&
994 grep "fatal: multiple updates for ref '"'"'$a'"'"' not allowed." err
997 test_expect_success
'stdin -z create ref works' '
998 printf $F "create $a" "$m" >stdin &&
999 git update-ref -z --stdin <stdin &&
1000 git rev-parse $m >expect &&
1001 git rev-parse $a >actual &&
1002 test_cmp expect actual
1005 test_expect_success
'stdin -z update ref creates with zero old value' '
1006 printf $F "update $b" "$m" "$Z" >stdin &&
1007 git update-ref -z --stdin <stdin &&
1008 git rev-parse $m >expect &&
1009 git rev-parse $b >actual &&
1010 test_cmp expect actual &&
1011 git update-ref -d $b
1014 test_expect_success
'stdin -z update ref creates with empty old value' '
1015 printf $F "update $b" "$m" "" >stdin &&
1016 git update-ref -z --stdin <stdin &&
1017 git rev-parse $m >expect &&
1018 git rev-parse $b >actual &&
1019 test_cmp expect actual
1022 test_expect_success
'stdin -z create ref works with path with space to blob' '
1023 printf $F "create refs/blobs/pws" "$m:$pws" >stdin &&
1024 git update-ref -z --stdin <stdin &&
1025 git rev-parse "$m:$pws" >expect &&
1026 git rev-parse refs/blobs/pws >actual &&
1027 test_cmp expect actual &&
1028 git update-ref -d refs/blobs/pws
1031 test_expect_success
'stdin -z update ref fails with wrong old value' '
1032 printf $F "update $c" "$m" "$m~1" >stdin &&
1033 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1034 grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
1035 test_must_fail git rev-parse --verify -q $c
1038 test_expect_success
'stdin -z update ref fails with bad old value' '
1039 printf $F "update $c" "$m" "does-not-exist" >stdin &&
1040 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1041 grep "fatal: update $c: invalid <oldvalue>: does-not-exist" err &&
1042 test_must_fail git rev-parse --verify -q $c
1045 test_expect_success
'stdin -z create ref fails when ref exists' '
1046 git update-ref $c $m &&
1047 git rev-parse "$c" >expect &&
1048 printf $F "create $c" "$m~1" >stdin &&
1049 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1050 grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
1051 git rev-parse "$c" >actual &&
1052 test_cmp expect actual
1055 test_expect_success
'stdin -z create ref fails with bad new value' '
1056 git update-ref -d "$c" &&
1057 printf $F "create $c" "does-not-exist" >stdin &&
1058 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1059 grep "fatal: create $c: invalid <newvalue>: does-not-exist" err &&
1060 test_must_fail git rev-parse --verify -q $c
1063 test_expect_success
'stdin -z create ref fails with empty new value' '
1064 printf $F "create $c" "" >stdin &&
1065 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1066 grep "fatal: create $c: missing <newvalue>" err &&
1067 test_must_fail git rev-parse --verify -q $c
1070 test_expect_success
'stdin -z update ref works with right old value' '
1071 printf $F "update $b" "$m~1" "$m" >stdin &&
1072 git update-ref -z --stdin <stdin &&
1073 git rev-parse $m~1 >expect &&
1074 git rev-parse $b >actual &&
1075 test_cmp expect actual
1078 test_expect_success
'stdin -z delete ref fails with wrong old value' '
1079 printf $F "delete $a" "$m~1" >stdin &&
1080 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1081 grep "fatal: cannot lock ref '"'"'$a'"'"'" err &&
1082 git rev-parse $m >expect &&
1083 git rev-parse $a >actual &&
1084 test_cmp expect actual
1087 test_expect_success
'stdin -z delete ref fails with zero old value' '
1088 printf $F "delete $a" "$Z" >stdin &&
1089 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1090 grep "fatal: delete $a: zero <oldvalue>" err &&
1091 git rev-parse $m >expect &&
1092 git rev-parse $a >actual &&
1093 test_cmp expect actual
1096 test_expect_success
'stdin -z update symref works option no-deref' '
1097 git symbolic-ref TESTSYMREF $b &&
1098 printf $F "option no-deref" "update TESTSYMREF" "$a" "$b" >stdin &&
1099 git update-ref -z --stdin <stdin &&
1100 git rev-parse TESTSYMREF >expect &&
1101 git rev-parse $a >actual &&
1102 test_cmp expect actual &&
1103 git rev-parse $m~1 >expect &&
1104 git rev-parse $b >actual &&
1105 test_cmp expect actual
1108 test_expect_success
'stdin -z delete symref works option no-deref' '
1109 git symbolic-ref TESTSYMREF $b &&
1110 printf $F "option no-deref" "delete TESTSYMREF" "$b" >stdin &&
1111 git update-ref -z --stdin <stdin &&
1112 test_must_fail git rev-parse --verify -q TESTSYMREF &&
1113 git rev-parse $m~1 >expect &&
1114 git rev-parse $b >actual &&
1115 test_cmp expect actual
1118 test_expect_success
'stdin -z delete ref works with right old value' '
1119 printf $F "delete $b" "$m~1" >stdin &&
1120 git update-ref -z --stdin <stdin &&
1121 test_must_fail git rev-parse --verify -q $b
1124 test_expect_success
'stdin -z update/create/verify combination works' '
1125 printf $F "update $a" "$m" "" "create $b" "$m" "verify $c" "" >stdin &&
1126 git update-ref -z --stdin <stdin &&
1127 git rev-parse $m >expect &&
1128 git rev-parse $a >actual &&
1129 test_cmp expect actual &&
1130 git rev-parse $b >actual &&
1131 test_cmp expect actual &&
1132 test_must_fail git rev-parse --verify -q $c
1135 test_expect_success
'stdin -z verify succeeds for correct value' '
1136 git rev-parse $m >expect &&
1137 printf $F "verify $m" "$m" >stdin &&
1138 git update-ref -z --stdin <stdin &&
1139 git rev-parse $m >actual &&
1140 test_cmp expect actual
1143 test_expect_success
'stdin -z verify succeeds for missing reference' '
1144 printf $F "verify refs/heads/missing" "$Z" >stdin &&
1145 git update-ref -z --stdin <stdin &&
1146 test_must_fail git rev-parse --verify -q refs/heads/missing
1149 test_expect_success
'stdin -z verify treats no value as missing' '
1150 printf $F "verify refs/heads/missing" "" >stdin &&
1151 git update-ref -z --stdin <stdin &&
1152 test_must_fail git rev-parse --verify -q refs/heads/missing
1155 test_expect_success
'stdin -z verify fails for wrong value' '
1156 git rev-parse $m >expect &&
1157 printf $F "verify $m" "$m~1" >stdin &&
1158 test_must_fail git update-ref -z --stdin <stdin &&
1159 git rev-parse $m >actual &&
1160 test_cmp expect actual
1163 test_expect_success
'stdin -z verify fails for mistaken null value' '
1164 git rev-parse $m >expect &&
1165 printf $F "verify $m" "$Z" >stdin &&
1166 test_must_fail git update-ref -z --stdin <stdin &&
1167 git rev-parse $m >actual &&
1168 test_cmp expect actual
1171 test_expect_success
'stdin -z verify fails for mistaken empty value' '
1172 M=$(git rev-parse $m) &&
1173 test_when_finished "git update-ref $m $M" &&
1174 git rev-parse $m >expect &&
1175 printf $F "verify $m" "" >stdin &&
1176 test_must_fail git update-ref -z --stdin <stdin &&
1177 git rev-parse $m >actual &&
1178 test_cmp expect actual
1181 test_expect_success
'stdin -z update refs works with identity updates' '
1182 printf $F "update $a" "$m" "$m" "update $b" "$m" "$m" "update $c" "$Z" "" >stdin &&
1183 git update-ref -z --stdin <stdin &&
1184 git rev-parse $m >expect &&
1185 git rev-parse $a >actual &&
1186 test_cmp expect actual &&
1187 git rev-parse $b >actual &&
1188 test_cmp expect actual &&
1189 test_must_fail git rev-parse --verify -q $c
1192 test_expect_success
'stdin -z update refs fails with wrong old value' '
1193 git update-ref $c $m &&
1194 printf $F "update $a" "$m" "$m" "update $b" "$m" "$m" "update $c" "$m" "$Z" >stdin &&
1195 test_must_fail git update-ref -z --stdin <stdin 2>err &&
1196 grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
1197 git rev-parse $m >expect &&
1198 git rev-parse $a >actual &&
1199 test_cmp expect actual &&
1200 git rev-parse $b >actual &&
1201 test_cmp expect actual &&
1202 git rev-parse $c >actual &&
1203 test_cmp expect actual
1206 test_expect_success
'stdin -z delete refs works with packed and loose refs' '
1207 git pack-refs --all &&
1208 git update-ref $c $m~1 &&
1209 printf $F "delete $a" "$m" "update $b" "$Z" "$m" "update $c" "" "$m~1" >stdin &&
1210 git update-ref -z --stdin <stdin &&
1211 test_must_fail git rev-parse --verify -q $a &&
1212 test_must_fail git rev-parse --verify -q $b &&
1213 test_must_fail git rev-parse --verify -q $c
1216 test_expect_success
'fails with duplicate HEAD update' '
1217 git branch target1 $A &&
1218 git checkout target1 &&
1219 cat >stdin <<-EOF &&
1220 update refs/heads/target1 $C
1224 test_must_fail git update-ref --stdin <stdin 2>err &&
1225 grep "fatal: multiple updates for '\''HEAD'\'' (including one via its referent .refs/heads/target1.) are not allowed" err &&
1226 echo "refs/heads/target1" >expect &&
1227 git symbolic-ref HEAD >actual &&
1228 test_cmp expect actual &&
1229 echo "$A" >expect &&
1230 git rev-parse refs/heads/target1 >actual &&
1231 test_cmp expect actual
1234 test_expect_success
'fails with duplicate ref update via symref' '
1235 git branch target2 $A &&
1236 git symbolic-ref refs/heads/symref2 refs/heads/target2 &&
1237 cat >stdin <<-EOF &&
1238 update refs/heads/target2 $C
1239 update refs/heads/symref2 $B
1241 test_must_fail git update-ref --stdin <stdin 2>err &&
1242 grep "fatal: multiple updates for '\''refs/heads/target2'\'' (including one via symref .refs/heads/symref2.) are not allowed" err &&
1243 echo "refs/heads/target2" >expect &&
1244 git symbolic-ref refs/heads/symref2 >actual &&
1245 test_cmp expect actual &&
1246 echo "$A" >expect &&
1247 git rev-parse refs/heads/target2 >actual &&
1248 test_cmp expect actual
1251 run_with_limited_open_files
() {
1252 (ulimit -n 32 && "$@")
1255 test_lazy_prereq ULIMIT_FILE_DESCRIPTORS
'run_with_limited_open_files true'
1257 test_expect_success ULIMIT_FILE_DESCRIPTORS
'large transaction creating branches does not burst open file limit' '
1259 for i in $(test_seq 33)
1261 echo "create refs/heads/$i HEAD"
1262 done >large_input &&
1263 run_with_limited_open_files git update-ref --stdin <large_input &&
1264 git rev-parse --verify -q refs/heads/33
1268 test_expect_success ULIMIT_FILE_DESCRIPTORS
'large transaction deleting branches does not burst open file limit' '
1270 for i in $(test_seq 33)
1272 echo "delete refs/heads/$i HEAD"
1273 done >large_input &&
1274 run_with_limited_open_files git update-ref --stdin <large_input &&
1275 test_must_fail git rev-parse --verify -q refs/heads/33
1279 test_expect_success
'handle per-worktree refs in refs/bisect' '
1280 git commit --allow-empty -m "initial commit" &&
1281 git worktree add -b branch worktree &&
1284 git commit --allow-empty -m "test commit" &&
1285 git for-each-ref >for-each-ref.out &&
1286 ! grep refs/bisect for-each-ref.out &&
1287 git update-ref refs/bisect/something HEAD &&
1288 git rev-parse refs/bisect/something >../worktree-head &&
1289 git for-each-ref | grep refs/bisect/something
1291 test_path_is_missing .git/refs/bisect &&
1292 test_must_fail git rev-parse refs/bisect/something &&
1293 git update-ref refs/bisect/something HEAD &&
1294 git rev-parse refs/bisect/something >main-head &&
1295 ! test_cmp main-head worktree-head