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