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