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