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