t / t1400-update-ref.shon commit bundle: dup() output descriptor closer to point-of-use (2c8ee1f)
   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=$ZERO_OID
  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_i18ngrep -F "warning: log for ref $m has gap after $gd" 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_i18ngrep -F "warning: log for ref $m unexpectedly ended on $ld" 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
 460# Test adding and deleting pseudorefs
 461
 462test_expect_success 'given old value for missing pseudoref, do not create' '
 463        test_must_fail git update-ref PSEUDOREF $A $B 2>err &&
 464        test_path_is_missing .git/PSEUDOREF &&
 465        test_i18ngrep "could not read ref" err
 466'
 467
 468test_expect_success 'create pseudoref' '
 469        git update-ref PSEUDOREF $A &&
 470        test $A = $(cat .git/PSEUDOREF)
 471'
 472
 473test_expect_success 'overwrite pseudoref with no old value given' '
 474        git update-ref PSEUDOREF $B &&
 475        test $B = $(cat .git/PSEUDOREF)
 476'
 477
 478test_expect_success 'overwrite pseudoref with correct old value' '
 479        git update-ref PSEUDOREF $C $B &&
 480        test $C = $(cat .git/PSEUDOREF)
 481'
 482
 483test_expect_success 'do not overwrite pseudoref with wrong old value' '
 484        test_must_fail git update-ref PSEUDOREF $D $E 2>err &&
 485        test $C = $(cat .git/PSEUDOREF) &&
 486        test_i18ngrep "unexpected object ID" err
 487'
 488
 489test_expect_success 'delete pseudoref' '
 490        git update-ref -d PSEUDOREF &&
 491        test_path_is_missing .git/PSEUDOREF
 492'
 493
 494test_expect_success 'do not delete pseudoref with wrong old value' '
 495        git update-ref PSEUDOREF $A &&
 496        test_must_fail git update-ref -d PSEUDOREF $B 2>err &&
 497        test $A = $(cat .git/PSEUDOREF) &&
 498        test_i18ngrep "unexpected object ID" err
 499'
 500
 501test_expect_success 'delete pseudoref with correct old value' '
 502        git update-ref -d PSEUDOREF $A &&
 503        test_path_is_missing .git/PSEUDOREF
 504'
 505
 506test_expect_success 'create pseudoref with old OID zero' '
 507        git update-ref PSEUDOREF $A $Z &&
 508        test $A = $(cat .git/PSEUDOREF)
 509'
 510
 511test_expect_success 'do not overwrite pseudoref with old OID zero' '
 512        test_when_finished git update-ref -d PSEUDOREF &&
 513        test_must_fail git update-ref PSEUDOREF $B $Z 2>err &&
 514        test $A = $(cat .git/PSEUDOREF) &&
 515        test_i18ngrep "already exists" err
 516'
 517
 518# Test --stdin
 519
 520a=refs/heads/a
 521b=refs/heads/b
 522c=refs/heads/c
 523E='""'
 524F='%s\0'
 525pws='path with space'
 526
 527test_expect_success 'stdin test setup' '
 528        echo "$pws" >"$pws" &&
 529        git add -- "$pws" &&
 530        git commit -m "$pws"
 531'
 532
 533test_expect_success '-z fails without --stdin' '
 534        test_must_fail git update-ref -z $m $m $m 2>err &&
 535        test_i18ngrep "usage: git update-ref" err
 536'
 537
 538test_expect_success 'stdin works with no input' '
 539        >stdin &&
 540        git update-ref --stdin <stdin &&
 541        git rev-parse --verify -q $m
 542'
 543
 544test_expect_success 'stdin fails on empty line' '
 545        echo "" >stdin &&
 546        test_must_fail git update-ref --stdin <stdin 2>err &&
 547        grep "fatal: empty command in input" err
 548'
 549
 550test_expect_success 'stdin fails on only whitespace' '
 551        echo " " >stdin &&
 552        test_must_fail git update-ref --stdin <stdin 2>err &&
 553        grep "fatal: whitespace before command:  " err
 554'
 555
 556test_expect_success 'stdin fails on leading whitespace' '
 557        echo " create $a $m" >stdin &&
 558        test_must_fail git update-ref --stdin <stdin 2>err &&
 559        grep "fatal: whitespace before command:  create $a $m" err
 560'
 561
 562test_expect_success 'stdin fails on unknown command' '
 563        echo "unknown $a" >stdin &&
 564        test_must_fail git update-ref --stdin <stdin 2>err &&
 565        grep "fatal: unknown command: unknown $a" err
 566'
 567
 568test_expect_success 'stdin fails on unbalanced quotes' '
 569        echo "create $a \"master" >stdin &&
 570        test_must_fail git update-ref --stdin <stdin 2>err &&
 571        grep "fatal: badly quoted argument: \\\"master" err
 572'
 573
 574test_expect_success 'stdin fails on invalid escape' '
 575        echo "create $a \"ma\zter\"" >stdin &&
 576        test_must_fail git update-ref --stdin <stdin 2>err &&
 577        grep "fatal: badly quoted argument: \\\"ma\\\\zter\\\"" err
 578'
 579
 580test_expect_success 'stdin fails on junk after quoted argument' '
 581        echo "create \"$a\"master" >stdin &&
 582        test_must_fail git update-ref --stdin <stdin 2>err &&
 583        grep "fatal: unexpected character after quoted argument: \\\"$a\\\"master" err
 584'
 585
 586test_expect_success 'stdin fails create with no ref' '
 587        echo "create " >stdin &&
 588        test_must_fail git update-ref --stdin <stdin 2>err &&
 589        grep "fatal: create: missing <ref>" err
 590'
 591
 592test_expect_success 'stdin fails create with no new value' '
 593        echo "create $a" >stdin &&
 594        test_must_fail git update-ref --stdin <stdin 2>err &&
 595        grep "fatal: create $a: missing <newvalue>" err
 596'
 597
 598test_expect_success 'stdin fails create with too many arguments' '
 599        echo "create $a $m $m" >stdin &&
 600        test_must_fail git update-ref --stdin <stdin 2>err &&
 601        grep "fatal: create $a: extra input:  $m" err
 602'
 603
 604test_expect_success 'stdin fails update with no ref' '
 605        echo "update " >stdin &&
 606        test_must_fail git update-ref --stdin <stdin 2>err &&
 607        grep "fatal: update: missing <ref>" err
 608'
 609
 610test_expect_success 'stdin fails update with no new value' '
 611        echo "update $a" >stdin &&
 612        test_must_fail git update-ref --stdin <stdin 2>err &&
 613        grep "fatal: update $a: missing <newvalue>" err
 614'
 615
 616test_expect_success 'stdin fails update with too many arguments' '
 617        echo "update $a $m $m $m" >stdin &&
 618        test_must_fail git update-ref --stdin <stdin 2>err &&
 619        grep "fatal: update $a: extra input:  $m" err
 620'
 621
 622test_expect_success 'stdin fails delete with no ref' '
 623        echo "delete " >stdin &&
 624        test_must_fail git update-ref --stdin <stdin 2>err &&
 625        grep "fatal: delete: missing <ref>" err
 626'
 627
 628test_expect_success 'stdin fails delete with too many arguments' '
 629        echo "delete $a $m $m" >stdin &&
 630        test_must_fail git update-ref --stdin <stdin 2>err &&
 631        grep "fatal: delete $a: extra input:  $m" err
 632'
 633
 634test_expect_success 'stdin fails verify with too many arguments' '
 635        echo "verify $a $m $m" >stdin &&
 636        test_must_fail git update-ref --stdin <stdin 2>err &&
 637        grep "fatal: verify $a: extra input:  $m" err
 638'
 639
 640test_expect_success 'stdin fails option with unknown name' '
 641        echo "option unknown" >stdin &&
 642        test_must_fail git update-ref --stdin <stdin 2>err &&
 643        grep "fatal: option unknown: unknown" err
 644'
 645
 646test_expect_success 'stdin fails with duplicate refs' '
 647        cat >stdin <<-EOF &&
 648        create $a $m
 649        create $b $m
 650        create $a $m
 651        EOF
 652        test_must_fail git update-ref --stdin <stdin 2>err &&
 653        test_i18ngrep "fatal: multiple updates for ref '"'"'$a'"'"' not allowed" err
 654'
 655
 656test_expect_success 'stdin create ref works' '
 657        echo "create $a $m" >stdin &&
 658        git update-ref --stdin <stdin &&
 659        git rev-parse $m >expect &&
 660        git rev-parse $a >actual &&
 661        test_cmp expect actual
 662'
 663
 664test_expect_success 'stdin does not create reflogs by default' '
 665        test_when_finished "git update-ref -d $outside" &&
 666        echo "create $outside $m" >stdin &&
 667        git update-ref --stdin <stdin &&
 668        git rev-parse $m >expect &&
 669        git rev-parse $outside >actual &&
 670        test_cmp expect actual &&
 671        test_must_fail git reflog exists $outside
 672'
 673
 674test_expect_success 'stdin creates reflogs with --create-reflog' '
 675        test_when_finished "git update-ref -d $outside" &&
 676        echo "create $outside $m" >stdin &&
 677        git update-ref --create-reflog --stdin <stdin &&
 678        git rev-parse $m >expect &&
 679        git rev-parse $outside >actual &&
 680        test_cmp expect actual &&
 681        git reflog exists $outside
 682'
 683
 684test_expect_success 'stdin succeeds with quoted argument' '
 685        git update-ref -d $a &&
 686        echo "create $a \"$m\"" >stdin &&
 687        git update-ref --stdin <stdin &&
 688        git rev-parse $m >expect &&
 689        git rev-parse $a >actual &&
 690        test_cmp expect actual
 691'
 692
 693test_expect_success 'stdin succeeds with escaped character' '
 694        git update-ref -d $a &&
 695        echo "create $a \"ma\\163ter\"" >stdin &&
 696        git update-ref --stdin <stdin &&
 697        git rev-parse $m >expect &&
 698        git rev-parse $a >actual &&
 699        test_cmp expect actual
 700'
 701
 702test_expect_success 'stdin update ref creates with zero old value' '
 703        echo "update $b $m $Z" >stdin &&
 704        git update-ref --stdin <stdin &&
 705        git rev-parse $m >expect &&
 706        git rev-parse $b >actual &&
 707        test_cmp expect actual &&
 708        git update-ref -d $b
 709'
 710
 711test_expect_success 'stdin update ref creates with empty old value' '
 712        echo "update $b $m $E" >stdin &&
 713        git update-ref --stdin <stdin &&
 714        git rev-parse $m >expect &&
 715        git rev-parse $b >actual &&
 716        test_cmp expect actual
 717'
 718
 719test_expect_success 'stdin create ref works with path with space to blob' '
 720        echo "create refs/blobs/pws \"$m:$pws\"" >stdin &&
 721        git update-ref --stdin <stdin &&
 722        git rev-parse "$m:$pws" >expect &&
 723        git rev-parse refs/blobs/pws >actual &&
 724        test_cmp expect actual &&
 725        git update-ref -d refs/blobs/pws
 726'
 727
 728test_expect_success 'stdin update ref fails with wrong old value' '
 729        echo "update $c $m $m~1" >stdin &&
 730        test_must_fail git update-ref --stdin <stdin 2>err &&
 731        grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
 732        test_must_fail git rev-parse --verify -q $c
 733'
 734
 735test_expect_success 'stdin update ref fails with bad old value' '
 736        echo "update $c $m does-not-exist" >stdin &&
 737        test_must_fail git update-ref --stdin <stdin 2>err &&
 738        grep "fatal: update $c: invalid <oldvalue>: does-not-exist" err &&
 739        test_must_fail git rev-parse --verify -q $c
 740'
 741
 742test_expect_success 'stdin create ref fails with bad new value' '
 743        echo "create $c does-not-exist" >stdin &&
 744        test_must_fail git update-ref --stdin <stdin 2>err &&
 745        grep "fatal: create $c: invalid <newvalue>: does-not-exist" err &&
 746        test_must_fail git rev-parse --verify -q $c
 747'
 748
 749test_expect_success 'stdin create ref fails with zero new value' '
 750        echo "create $c " >stdin &&
 751        test_must_fail git update-ref --stdin <stdin 2>err &&
 752        grep "fatal: create $c: zero <newvalue>" err &&
 753        test_must_fail git rev-parse --verify -q $c
 754'
 755
 756test_expect_success 'stdin update ref works with right old value' '
 757        echo "update $b $m~1 $m" >stdin &&
 758        git update-ref --stdin <stdin &&
 759        git rev-parse $m~1 >expect &&
 760        git rev-parse $b >actual &&
 761        test_cmp expect actual
 762'
 763
 764test_expect_success 'stdin delete ref fails with wrong old value' '
 765        echo "delete $a $m~1" >stdin &&
 766        test_must_fail git update-ref --stdin <stdin 2>err &&
 767        grep "fatal: cannot lock ref '"'"'$a'"'"'" err &&
 768        git rev-parse $m >expect &&
 769        git rev-parse $a >actual &&
 770        test_cmp expect actual
 771'
 772
 773test_expect_success 'stdin delete ref fails with zero old value' '
 774        echo "delete $a " >stdin &&
 775        test_must_fail git update-ref --stdin <stdin 2>err &&
 776        grep "fatal: delete $a: zero <oldvalue>" err &&
 777        git rev-parse $m >expect &&
 778        git rev-parse $a >actual &&
 779        test_cmp expect actual
 780'
 781
 782test_expect_success 'stdin update symref works option no-deref' '
 783        git symbolic-ref TESTSYMREF $b &&
 784        cat >stdin <<-EOF &&
 785        option no-deref
 786        update TESTSYMREF $a $b
 787        EOF
 788        git update-ref --stdin <stdin &&
 789        git rev-parse TESTSYMREF >expect &&
 790        git rev-parse $a >actual &&
 791        test_cmp expect actual &&
 792        git rev-parse $m~1 >expect &&
 793        git rev-parse $b >actual &&
 794        test_cmp expect actual
 795'
 796
 797test_expect_success 'stdin delete symref works option no-deref' '
 798        git symbolic-ref TESTSYMREF $b &&
 799        cat >stdin <<-EOF &&
 800        option no-deref
 801        delete TESTSYMREF $b
 802        EOF
 803        git update-ref --stdin <stdin &&
 804        test_must_fail git rev-parse --verify -q TESTSYMREF &&
 805        git rev-parse $m~1 >expect &&
 806        git rev-parse $b >actual &&
 807        test_cmp expect actual
 808'
 809
 810test_expect_success 'stdin delete ref works with right old value' '
 811        echo "delete $b $m~1" >stdin &&
 812        git update-ref --stdin <stdin &&
 813        test_must_fail git rev-parse --verify -q $b
 814'
 815
 816test_expect_success 'stdin update/create/verify combination works' '
 817        cat >stdin <<-EOF &&
 818        update $a $m
 819        create $b $m
 820        verify $c
 821        EOF
 822        git update-ref --stdin <stdin &&
 823        git rev-parse $m >expect &&
 824        git rev-parse $a >actual &&
 825        test_cmp expect actual &&
 826        git rev-parse $b >actual &&
 827        test_cmp expect actual &&
 828        test_must_fail git rev-parse --verify -q $c
 829'
 830
 831test_expect_success 'stdin verify succeeds for correct value' '
 832        git rev-parse $m >expect &&
 833        echo "verify $m $m" >stdin &&
 834        git update-ref --stdin <stdin &&
 835        git rev-parse $m >actual &&
 836        test_cmp expect actual
 837'
 838
 839test_expect_success 'stdin verify succeeds for missing reference' '
 840        echo "verify refs/heads/missing $Z" >stdin &&
 841        git update-ref --stdin <stdin &&
 842        test_must_fail git rev-parse --verify -q refs/heads/missing
 843'
 844
 845test_expect_success 'stdin verify treats no value as missing' '
 846        echo "verify refs/heads/missing" >stdin &&
 847        git update-ref --stdin <stdin &&
 848        test_must_fail git rev-parse --verify -q refs/heads/missing
 849'
 850
 851test_expect_success 'stdin verify fails for wrong value' '
 852        git rev-parse $m >expect &&
 853        echo "verify $m $m~1" >stdin &&
 854        test_must_fail git update-ref --stdin <stdin &&
 855        git rev-parse $m >actual &&
 856        test_cmp expect actual
 857'
 858
 859test_expect_success 'stdin verify fails for mistaken null value' '
 860        git rev-parse $m >expect &&
 861        echo "verify $m $Z" >stdin &&
 862        test_must_fail git update-ref --stdin <stdin &&
 863        git rev-parse $m >actual &&
 864        test_cmp expect actual
 865'
 866
 867test_expect_success 'stdin verify fails for mistaken empty value' '
 868        M=$(git rev-parse $m) &&
 869        test_when_finished "git update-ref $m $M" &&
 870        git rev-parse $m >expect &&
 871        echo "verify $m" >stdin &&
 872        test_must_fail git update-ref --stdin <stdin &&
 873        git rev-parse $m >actual &&
 874        test_cmp expect actual
 875'
 876
 877test_expect_success 'stdin update refs works with identity updates' '
 878        cat >stdin <<-EOF &&
 879        update $a $m $m
 880        update $b $m $m
 881        update $c $Z $E
 882        EOF
 883        git update-ref --stdin <stdin &&
 884        git rev-parse $m >expect &&
 885        git rev-parse $a >actual &&
 886        test_cmp expect actual &&
 887        git rev-parse $b >actual &&
 888        test_cmp expect actual &&
 889        test_must_fail git rev-parse --verify -q $c
 890'
 891
 892test_expect_success 'stdin update refs fails with wrong old value' '
 893        git update-ref $c $m &&
 894        cat >stdin <<-EOF &&
 895        update $a $m $m
 896        update $b $m $m
 897        update $c  ''
 898        EOF
 899        test_must_fail git update-ref --stdin <stdin 2>err &&
 900        grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
 901        git rev-parse $m >expect &&
 902        git rev-parse $a >actual &&
 903        test_cmp expect actual &&
 904        git rev-parse $b >actual &&
 905        test_cmp expect actual &&
 906        git rev-parse $c >actual &&
 907        test_cmp expect actual
 908'
 909
 910test_expect_success 'stdin delete refs works with packed and loose refs' '
 911        git pack-refs --all &&
 912        git update-ref $c $m~1 &&
 913        cat >stdin <<-EOF &&
 914        delete $a $m
 915        update $b $Z $m
 916        update $c $E $m~1
 917        EOF
 918        git update-ref --stdin <stdin &&
 919        test_must_fail git rev-parse --verify -q $a &&
 920        test_must_fail git rev-parse --verify -q $b &&
 921        test_must_fail git rev-parse --verify -q $c
 922'
 923
 924test_expect_success 'stdin -z works on empty input' '
 925        >stdin &&
 926        git update-ref -z --stdin <stdin &&
 927        git rev-parse --verify -q $m
 928'
 929
 930test_expect_success 'stdin -z fails on empty line' '
 931        echo "" >stdin &&
 932        test_must_fail git update-ref -z --stdin <stdin 2>err &&
 933        grep "fatal: whitespace before command: " err
 934'
 935
 936test_expect_success 'stdin -z fails on empty command' '
 937        printf $F "" >stdin &&
 938        test_must_fail git update-ref -z --stdin <stdin 2>err &&
 939        grep "fatal: empty command in input" err
 940'
 941
 942test_expect_success 'stdin -z fails on only whitespace' '
 943        printf $F " " >stdin &&
 944        test_must_fail git update-ref -z --stdin <stdin 2>err &&
 945        grep "fatal: whitespace before command:  " err
 946'
 947
 948test_expect_success 'stdin -z fails on leading whitespace' '
 949        printf $F " create $a" "$m" >stdin &&
 950        test_must_fail git update-ref -z --stdin <stdin 2>err &&
 951        grep "fatal: whitespace before command:  create $a" err
 952'
 953
 954test_expect_success 'stdin -z fails on unknown command' '
 955        printf $F "unknown $a" >stdin &&
 956        test_must_fail git update-ref -z --stdin <stdin 2>err &&
 957        grep "fatal: unknown command: unknown $a" err
 958'
 959
 960test_expect_success 'stdin -z fails create with no ref' '
 961        printf $F "create " >stdin &&
 962        test_must_fail git update-ref -z --stdin <stdin 2>err &&
 963        grep "fatal: create: missing <ref>" err
 964'
 965
 966test_expect_success 'stdin -z fails create with no new value' '
 967        printf $F "create $a" >stdin &&
 968        test_must_fail git update-ref -z --stdin <stdin 2>err &&
 969        grep "fatal: create $a: unexpected end of input when reading <newvalue>" err
 970'
 971
 972test_expect_success 'stdin -z fails create with too many arguments' '
 973        printf $F "create $a" "$m" "$m" >stdin &&
 974        test_must_fail git update-ref -z --stdin <stdin 2>err &&
 975        grep "fatal: unknown command: $m" err
 976'
 977
 978test_expect_success 'stdin -z fails update with no ref' '
 979        printf $F "update " >stdin &&
 980        test_must_fail git update-ref -z --stdin <stdin 2>err &&
 981        grep "fatal: update: missing <ref>" err
 982'
 983
 984test_expect_success 'stdin -z fails update with too few args' '
 985        printf $F "update $a" "$m" >stdin &&
 986        test_must_fail git update-ref -z --stdin <stdin 2>err &&
 987        grep "fatal: update $a: unexpected end of input when reading <oldvalue>" err
 988'
 989
 990test_expect_success 'stdin -z emits warning with empty new value' '
 991        git update-ref $a $m &&
 992        printf $F "update $a" "" "" >stdin &&
 993        git update-ref -z --stdin <stdin 2>err &&
 994        grep "warning: update $a: missing <newvalue>, treating as zero" err &&
 995        test_must_fail git rev-parse --verify -q $a
 996'
 997
 998test_expect_success 'stdin -z fails update with no new value' '
 999        printf $F "update $a" >stdin &&
1000        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1001        grep "fatal: update $a: unexpected end of input when reading <newvalue>" err
1002'
1003
1004test_expect_success 'stdin -z fails update with no old value' '
1005        printf $F "update $a" "$m" >stdin &&
1006        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1007        grep "fatal: update $a: unexpected end of input when reading <oldvalue>" err
1008'
1009
1010test_expect_success 'stdin -z fails update with too many arguments' '
1011        printf $F "update $a" "$m" "$m" "$m" >stdin &&
1012        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1013        grep "fatal: unknown command: $m" err
1014'
1015
1016test_expect_success 'stdin -z fails delete with no ref' '
1017        printf $F "delete " >stdin &&
1018        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1019        grep "fatal: delete: missing <ref>" err
1020'
1021
1022test_expect_success 'stdin -z fails delete with no old value' '
1023        printf $F "delete $a" >stdin &&
1024        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1025        grep "fatal: delete $a: unexpected end of input when reading <oldvalue>" err
1026'
1027
1028test_expect_success 'stdin -z fails delete with too many arguments' '
1029        printf $F "delete $a" "$m" "$m" >stdin &&
1030        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1031        grep "fatal: unknown command: $m" err
1032'
1033
1034test_expect_success 'stdin -z fails verify with too many arguments' '
1035        printf $F "verify $a" "$m" "$m" >stdin &&
1036        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1037        grep "fatal: unknown command: $m" err
1038'
1039
1040test_expect_success 'stdin -z fails verify with no old value' '
1041        printf $F "verify $a" >stdin &&
1042        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1043        grep "fatal: verify $a: unexpected end of input when reading <oldvalue>" err
1044'
1045
1046test_expect_success 'stdin -z fails option with unknown name' '
1047        printf $F "option unknown" >stdin &&
1048        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1049        grep "fatal: option unknown: unknown" err
1050'
1051
1052test_expect_success 'stdin -z fails with duplicate refs' '
1053        printf $F "create $a" "$m" "create $b" "$m" "create $a" "$m" >stdin &&
1054        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1055        test_i18ngrep "fatal: multiple updates for ref '"'"'$a'"'"' not allowed" err
1056'
1057
1058test_expect_success 'stdin -z create ref works' '
1059        printf $F "create $a" "$m" >stdin &&
1060        git update-ref -z --stdin <stdin &&
1061        git rev-parse $m >expect &&
1062        git rev-parse $a >actual &&
1063        test_cmp expect actual
1064'
1065
1066test_expect_success 'stdin -z update ref creates with zero old value' '
1067        printf $F "update $b" "$m" "$Z" >stdin &&
1068        git update-ref -z --stdin <stdin &&
1069        git rev-parse $m >expect &&
1070        git rev-parse $b >actual &&
1071        test_cmp expect actual &&
1072        git update-ref -d $b
1073'
1074
1075test_expect_success 'stdin -z update ref creates with empty old value' '
1076        printf $F "update $b" "$m" "" >stdin &&
1077        git update-ref -z --stdin <stdin &&
1078        git rev-parse $m >expect &&
1079        git rev-parse $b >actual &&
1080        test_cmp expect actual
1081'
1082
1083test_expect_success 'stdin -z create ref works with path with space to blob' '
1084        printf $F "create refs/blobs/pws" "$m:$pws" >stdin &&
1085        git update-ref -z --stdin <stdin &&
1086        git rev-parse "$m:$pws" >expect &&
1087        git rev-parse refs/blobs/pws >actual &&
1088        test_cmp expect actual &&
1089        git update-ref -d refs/blobs/pws
1090'
1091
1092test_expect_success 'stdin -z update ref fails with wrong old value' '
1093        printf $F "update $c" "$m" "$m~1" >stdin &&
1094        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1095        grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
1096        test_must_fail git rev-parse --verify -q $c
1097'
1098
1099test_expect_success 'stdin -z update ref fails with bad old value' '
1100        printf $F "update $c" "$m" "does-not-exist" >stdin &&
1101        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1102        grep "fatal: update $c: invalid <oldvalue>: does-not-exist" err &&
1103        test_must_fail git rev-parse --verify -q $c
1104'
1105
1106test_expect_success 'stdin -z create ref fails when ref exists' '
1107        git update-ref $c $m &&
1108        git rev-parse "$c" >expect &&
1109        printf $F "create $c" "$m~1" >stdin &&
1110        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1111        grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
1112        git rev-parse "$c" >actual &&
1113        test_cmp expect actual
1114'
1115
1116test_expect_success 'stdin -z create ref fails with bad new value' '
1117        git update-ref -d "$c" &&
1118        printf $F "create $c" "does-not-exist" >stdin &&
1119        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1120        grep "fatal: create $c: invalid <newvalue>: does-not-exist" err &&
1121        test_must_fail git rev-parse --verify -q $c
1122'
1123
1124test_expect_success 'stdin -z create ref fails with empty new value' '
1125        printf $F "create $c" "" >stdin &&
1126        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1127        grep "fatal: create $c: missing <newvalue>" err &&
1128        test_must_fail git rev-parse --verify -q $c
1129'
1130
1131test_expect_success 'stdin -z update ref works with right old value' '
1132        printf $F "update $b" "$m~1" "$m" >stdin &&
1133        git update-ref -z --stdin <stdin &&
1134        git rev-parse $m~1 >expect &&
1135        git rev-parse $b >actual &&
1136        test_cmp expect actual
1137'
1138
1139test_expect_success 'stdin -z delete ref fails with wrong old value' '
1140        printf $F "delete $a" "$m~1" >stdin &&
1141        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1142        grep "fatal: cannot lock ref '"'"'$a'"'"'" err &&
1143        git rev-parse $m >expect &&
1144        git rev-parse $a >actual &&
1145        test_cmp expect actual
1146'
1147
1148test_expect_success 'stdin -z delete ref fails with zero old value' '
1149        printf $F "delete $a" "$Z" >stdin &&
1150        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1151        grep "fatal: delete $a: zero <oldvalue>" err &&
1152        git rev-parse $m >expect &&
1153        git rev-parse $a >actual &&
1154        test_cmp expect actual
1155'
1156
1157test_expect_success 'stdin -z update symref works option no-deref' '
1158        git symbolic-ref TESTSYMREF $b &&
1159        printf $F "option no-deref" "update TESTSYMREF" "$a" "$b" >stdin &&
1160        git update-ref -z --stdin <stdin &&
1161        git rev-parse TESTSYMREF >expect &&
1162        git rev-parse $a >actual &&
1163        test_cmp expect actual &&
1164        git rev-parse $m~1 >expect &&
1165        git rev-parse $b >actual &&
1166        test_cmp expect actual
1167'
1168
1169test_expect_success 'stdin -z delete symref works option no-deref' '
1170        git symbolic-ref TESTSYMREF $b &&
1171        printf $F "option no-deref" "delete TESTSYMREF" "$b" >stdin &&
1172        git update-ref -z --stdin <stdin &&
1173        test_must_fail git rev-parse --verify -q TESTSYMREF &&
1174        git rev-parse $m~1 >expect &&
1175        git rev-parse $b >actual &&
1176        test_cmp expect actual
1177'
1178
1179test_expect_success 'stdin -z delete ref works with right old value' '
1180        printf $F "delete $b" "$m~1" >stdin &&
1181        git update-ref -z --stdin <stdin &&
1182        test_must_fail git rev-parse --verify -q $b
1183'
1184
1185test_expect_success 'stdin -z update/create/verify combination works' '
1186        printf $F "update $a" "$m" "" "create $b" "$m" "verify $c" "" >stdin &&
1187        git update-ref -z --stdin <stdin &&
1188        git rev-parse $m >expect &&
1189        git rev-parse $a >actual &&
1190        test_cmp expect actual &&
1191        git rev-parse $b >actual &&
1192        test_cmp expect actual &&
1193        test_must_fail git rev-parse --verify -q $c
1194'
1195
1196test_expect_success 'stdin -z verify succeeds for correct value' '
1197        git rev-parse $m >expect &&
1198        printf $F "verify $m" "$m" >stdin &&
1199        git update-ref -z --stdin <stdin &&
1200        git rev-parse $m >actual &&
1201        test_cmp expect actual
1202'
1203
1204test_expect_success 'stdin -z verify succeeds for missing reference' '
1205        printf $F "verify refs/heads/missing" "$Z" >stdin &&
1206        git update-ref -z --stdin <stdin &&
1207        test_must_fail git rev-parse --verify -q refs/heads/missing
1208'
1209
1210test_expect_success 'stdin -z verify treats no value as missing' '
1211        printf $F "verify refs/heads/missing" "" >stdin &&
1212        git update-ref -z --stdin <stdin &&
1213        test_must_fail git rev-parse --verify -q refs/heads/missing
1214'
1215
1216test_expect_success 'stdin -z verify fails for wrong value' '
1217        git rev-parse $m >expect &&
1218        printf $F "verify $m" "$m~1" >stdin &&
1219        test_must_fail git update-ref -z --stdin <stdin &&
1220        git rev-parse $m >actual &&
1221        test_cmp expect actual
1222'
1223
1224test_expect_success 'stdin -z verify fails for mistaken null value' '
1225        git rev-parse $m >expect &&
1226        printf $F "verify $m" "$Z" >stdin &&
1227        test_must_fail git update-ref -z --stdin <stdin &&
1228        git rev-parse $m >actual &&
1229        test_cmp expect actual
1230'
1231
1232test_expect_success 'stdin -z verify fails for mistaken empty value' '
1233        M=$(git rev-parse $m) &&
1234        test_when_finished "git update-ref $m $M" &&
1235        git rev-parse $m >expect &&
1236        printf $F "verify $m" "" >stdin &&
1237        test_must_fail git update-ref -z --stdin <stdin &&
1238        git rev-parse $m >actual &&
1239        test_cmp expect actual
1240'
1241
1242test_expect_success 'stdin -z update refs works with identity updates' '
1243        printf $F "update $a" "$m" "$m" "update $b" "$m" "$m" "update $c" "$Z" "" >stdin &&
1244        git update-ref -z --stdin <stdin &&
1245        git rev-parse $m >expect &&
1246        git rev-parse $a >actual &&
1247        test_cmp expect actual &&
1248        git rev-parse $b >actual &&
1249        test_cmp expect actual &&
1250        test_must_fail git rev-parse --verify -q $c
1251'
1252
1253test_expect_success 'stdin -z update refs fails with wrong old value' '
1254        git update-ref $c $m &&
1255        printf $F "update $a" "$m" "$m" "update $b" "$m" "$m" "update $c" "$m" "$Z" >stdin &&
1256        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1257        grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
1258        git rev-parse $m >expect &&
1259        git rev-parse $a >actual &&
1260        test_cmp expect actual &&
1261        git rev-parse $b >actual &&
1262        test_cmp expect actual &&
1263        git rev-parse $c >actual &&
1264        test_cmp expect actual
1265'
1266
1267test_expect_success 'stdin -z delete refs works with packed and loose refs' '
1268        git pack-refs --all &&
1269        git update-ref $c $m~1 &&
1270        printf $F "delete $a" "$m" "update $b" "$Z" "$m" "update $c" "" "$m~1" >stdin &&
1271        git update-ref -z --stdin <stdin &&
1272        test_must_fail git rev-parse --verify -q $a &&
1273        test_must_fail git rev-parse --verify -q $b &&
1274        test_must_fail git rev-parse --verify -q $c
1275'
1276
1277test_expect_success 'fails with duplicate HEAD update' '
1278        git branch target1 $A &&
1279        git checkout target1 &&
1280        cat >stdin <<-EOF &&
1281        update refs/heads/target1 $C
1282        option no-deref
1283        update HEAD $B
1284        EOF
1285        test_must_fail git update-ref --stdin <stdin 2>err &&
1286        test_i18ngrep "fatal: multiple updates for '\''HEAD'\'' (including one via its referent .refs/heads/target1.) are not allowed" err &&
1287        echo "refs/heads/target1" >expect &&
1288        git symbolic-ref HEAD >actual &&
1289        test_cmp expect actual &&
1290        echo "$A" >expect &&
1291        git rev-parse refs/heads/target1 >actual &&
1292        test_cmp expect actual
1293'
1294
1295test_expect_success 'fails with duplicate ref update via symref' '
1296        git branch target2 $A &&
1297        git symbolic-ref refs/heads/symref2 refs/heads/target2 &&
1298        cat >stdin <<-EOF &&
1299        update refs/heads/target2 $C
1300        update refs/heads/symref2 $B
1301        EOF
1302        test_must_fail git update-ref --stdin <stdin 2>err &&
1303        test_i18ngrep "fatal: multiple updates for '\''refs/heads/target2'\'' (including one via symref .refs/heads/symref2.) are not allowed" err &&
1304        echo "refs/heads/target2" >expect &&
1305        git symbolic-ref refs/heads/symref2 >actual &&
1306        test_cmp expect actual &&
1307        echo "$A" >expect &&
1308        git rev-parse refs/heads/target2 >actual &&
1309        test_cmp expect actual
1310'
1311
1312run_with_limited_open_files () {
1313        (ulimit -n 32 && "$@")
1314}
1315
1316test_lazy_prereq ULIMIT_FILE_DESCRIPTORS '
1317        test_have_prereq !MINGW,!CYGWIN &&
1318        run_with_limited_open_files true
1319'
1320
1321test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction creating branches does not burst open file limit' '
1322(
1323        for i in $(test_seq 33)
1324        do
1325                echo "create refs/heads/$i HEAD"
1326        done >large_input &&
1327        run_with_limited_open_files git update-ref --stdin <large_input &&
1328        git rev-parse --verify -q refs/heads/33
1329)
1330'
1331
1332test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction deleting branches does not burst open file limit' '
1333(
1334        for i in $(test_seq 33)
1335        do
1336                echo "delete refs/heads/$i HEAD"
1337        done >large_input &&
1338        run_with_limited_open_files git update-ref --stdin <large_input &&
1339        test_must_fail git rev-parse --verify -q refs/heads/33
1340)
1341'
1342
1343test_expect_success 'handle per-worktree refs in refs/bisect' '
1344        git commit --allow-empty -m "initial commit" &&
1345        git worktree add -b branch worktree &&
1346        (
1347                cd worktree &&
1348                git commit --allow-empty -m "test commit"  &&
1349                git for-each-ref >for-each-ref.out &&
1350                ! grep refs/bisect for-each-ref.out &&
1351                git update-ref refs/bisect/something HEAD &&
1352                git rev-parse refs/bisect/something >../worktree-head &&
1353                git for-each-ref | grep refs/bisect/something
1354        ) &&
1355        test_path_is_missing .git/refs/bisect &&
1356        test_must_fail git rev-parse refs/bisect/something &&
1357        git update-ref refs/bisect/something HEAD &&
1358        git rev-parse refs/bisect/something >main-head &&
1359        ! test_cmp main-head worktree-head
1360'
1361
1362test_done