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