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