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