t / t1400-update-ref.shon commit parse-options: drop OPT_DATE() (0a8a16a)
   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
 349$Z $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        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 update symref works flag --no-deref' '
 811        git symbolic-ref TESTSYMREFONE $b &&
 812        git symbolic-ref TESTSYMREFTWO $b &&
 813        cat >stdin <<-EOF &&
 814        update TESTSYMREFONE $a $b
 815        update TESTSYMREFTWO $a $b
 816        EOF
 817        git update-ref --no-deref --stdin <stdin &&
 818        git rev-parse TESTSYMREFONE TESTSYMREFTWO >expect &&
 819        git rev-parse $a $a >actual &&
 820        test_cmp expect actual &&
 821        git rev-parse $m~1 >expect &&
 822        git rev-parse $b >actual &&
 823        test_cmp expect actual
 824'
 825
 826test_expect_success 'stdin delete symref works flag --no-deref' '
 827        git symbolic-ref TESTSYMREFONE $b &&
 828        git symbolic-ref TESTSYMREFTWO $b &&
 829        cat >stdin <<-EOF &&
 830        delete TESTSYMREFONE $b
 831        delete TESTSYMREFTWO $b
 832        EOF
 833        git update-ref --no-deref --stdin <stdin &&
 834        test_must_fail git rev-parse --verify -q TESTSYMREFONE &&
 835        test_must_fail git rev-parse --verify -q TESTSYMREFTWO &&
 836        git rev-parse $m~1 >expect &&
 837        git rev-parse $b >actual &&
 838        test_cmp expect actual
 839'
 840
 841test_expect_success 'stdin delete ref works with right old value' '
 842        echo "delete $b $m~1" >stdin &&
 843        git update-ref --stdin <stdin &&
 844        test_must_fail git rev-parse --verify -q $b
 845'
 846
 847test_expect_success 'stdin update/create/verify combination works' '
 848        cat >stdin <<-EOF &&
 849        update $a $m
 850        create $b $m
 851        verify $c
 852        EOF
 853        git update-ref --stdin <stdin &&
 854        git rev-parse $m >expect &&
 855        git rev-parse $a >actual &&
 856        test_cmp expect actual &&
 857        git rev-parse $b >actual &&
 858        test_cmp expect actual &&
 859        test_must_fail git rev-parse --verify -q $c
 860'
 861
 862test_expect_success 'stdin verify succeeds for correct value' '
 863        git rev-parse $m >expect &&
 864        echo "verify $m $m" >stdin &&
 865        git update-ref --stdin <stdin &&
 866        git rev-parse $m >actual &&
 867        test_cmp expect actual
 868'
 869
 870test_expect_success 'stdin verify succeeds for missing reference' '
 871        echo "verify refs/heads/missing $Z" >stdin &&
 872        git update-ref --stdin <stdin &&
 873        test_must_fail git rev-parse --verify -q refs/heads/missing
 874'
 875
 876test_expect_success 'stdin verify treats no value as missing' '
 877        echo "verify refs/heads/missing" >stdin &&
 878        git update-ref --stdin <stdin &&
 879        test_must_fail git rev-parse --verify -q refs/heads/missing
 880'
 881
 882test_expect_success 'stdin verify fails for wrong value' '
 883        git rev-parse $m >expect &&
 884        echo "verify $m $m~1" >stdin &&
 885        test_must_fail git update-ref --stdin <stdin &&
 886        git rev-parse $m >actual &&
 887        test_cmp expect actual
 888'
 889
 890test_expect_success 'stdin verify fails for mistaken null value' '
 891        git rev-parse $m >expect &&
 892        echo "verify $m $Z" >stdin &&
 893        test_must_fail git update-ref --stdin <stdin &&
 894        git rev-parse $m >actual &&
 895        test_cmp expect actual
 896'
 897
 898test_expect_success 'stdin verify fails for mistaken empty value' '
 899        M=$(git rev-parse $m) &&
 900        test_when_finished "git update-ref $m $M" &&
 901        git rev-parse $m >expect &&
 902        echo "verify $m" >stdin &&
 903        test_must_fail git update-ref --stdin <stdin &&
 904        git rev-parse $m >actual &&
 905        test_cmp expect actual
 906'
 907
 908test_expect_success 'stdin update refs works with identity updates' '
 909        cat >stdin <<-EOF &&
 910        update $a $m $m
 911        update $b $m $m
 912        update $c $Z $E
 913        EOF
 914        git update-ref --stdin <stdin &&
 915        git rev-parse $m >expect &&
 916        git rev-parse $a >actual &&
 917        test_cmp expect actual &&
 918        git rev-parse $b >actual &&
 919        test_cmp expect actual &&
 920        test_must_fail git rev-parse --verify -q $c
 921'
 922
 923test_expect_success 'stdin update refs fails with wrong old value' '
 924        git update-ref $c $m &&
 925        cat >stdin <<-EOF &&
 926        update $a $m $m
 927        update $b $m $m
 928        update $c  ''
 929        EOF
 930        test_must_fail git update-ref --stdin <stdin 2>err &&
 931        grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
 932        git rev-parse $m >expect &&
 933        git rev-parse $a >actual &&
 934        test_cmp expect actual &&
 935        git rev-parse $b >actual &&
 936        test_cmp expect actual &&
 937        git rev-parse $c >actual &&
 938        test_cmp expect actual
 939'
 940
 941test_expect_success 'stdin delete refs works with packed and loose refs' '
 942        git pack-refs --all &&
 943        git update-ref $c $m~1 &&
 944        cat >stdin <<-EOF &&
 945        delete $a $m
 946        update $b $Z $m
 947        update $c $E $m~1
 948        EOF
 949        git update-ref --stdin <stdin &&
 950        test_must_fail git rev-parse --verify -q $a &&
 951        test_must_fail git rev-parse --verify -q $b &&
 952        test_must_fail git rev-parse --verify -q $c
 953'
 954
 955test_expect_success 'stdin -z works on empty input' '
 956        >stdin &&
 957        git update-ref -z --stdin <stdin &&
 958        git rev-parse --verify -q $m
 959'
 960
 961test_expect_success 'stdin -z fails on empty line' '
 962        echo "" >stdin &&
 963        test_must_fail git update-ref -z --stdin <stdin 2>err &&
 964        grep "fatal: whitespace before command: " err
 965'
 966
 967test_expect_success 'stdin -z fails on empty command' '
 968        printf $F "" >stdin &&
 969        test_must_fail git update-ref -z --stdin <stdin 2>err &&
 970        grep "fatal: empty command in input" err
 971'
 972
 973test_expect_success 'stdin -z fails on only whitespace' '
 974        printf $F " " >stdin &&
 975        test_must_fail git update-ref -z --stdin <stdin 2>err &&
 976        grep "fatal: whitespace before command:  " err
 977'
 978
 979test_expect_success 'stdin -z fails on leading whitespace' '
 980        printf $F " create $a" "$m" >stdin &&
 981        test_must_fail git update-ref -z --stdin <stdin 2>err &&
 982        grep "fatal: whitespace before command:  create $a" err
 983'
 984
 985test_expect_success 'stdin -z fails on unknown command' '
 986        printf $F "unknown $a" >stdin &&
 987        test_must_fail git update-ref -z --stdin <stdin 2>err &&
 988        grep "fatal: unknown command: unknown $a" err
 989'
 990
 991test_expect_success 'stdin -z fails create with no ref' '
 992        printf $F "create " >stdin &&
 993        test_must_fail git update-ref -z --stdin <stdin 2>err &&
 994        grep "fatal: create: missing <ref>" err
 995'
 996
 997test_expect_success 'stdin -z fails create with no new value' '
 998        printf $F "create $a" >stdin &&
 999        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1000        grep "fatal: create $a: unexpected end of input when reading <newvalue>" err
1001'
1002
1003test_expect_success 'stdin -z fails create with too many arguments' '
1004        printf $F "create $a" "$m" "$m" >stdin &&
1005        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1006        grep "fatal: unknown command: $m" err
1007'
1008
1009test_expect_success 'stdin -z fails update with no ref' '
1010        printf $F "update " >stdin &&
1011        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1012        grep "fatal: update: missing <ref>" err
1013'
1014
1015test_expect_success 'stdin -z fails update with too few args' '
1016        printf $F "update $a" "$m" >stdin &&
1017        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1018        grep "fatal: update $a: unexpected end of input when reading <oldvalue>" err
1019'
1020
1021test_expect_success 'stdin -z emits warning with empty new value' '
1022        git update-ref $a $m &&
1023        printf $F "update $a" "" "" >stdin &&
1024        git update-ref -z --stdin <stdin 2>err &&
1025        grep "warning: update $a: missing <newvalue>, treating as zero" err &&
1026        test_must_fail git rev-parse --verify -q $a
1027'
1028
1029test_expect_success 'stdin -z fails update with no new value' '
1030        printf $F "update $a" >stdin &&
1031        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1032        grep "fatal: update $a: unexpected end of input when reading <newvalue>" err
1033'
1034
1035test_expect_success 'stdin -z fails update with no old value' '
1036        printf $F "update $a" "$m" >stdin &&
1037        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1038        grep "fatal: update $a: unexpected end of input when reading <oldvalue>" err
1039'
1040
1041test_expect_success 'stdin -z fails update with too many arguments' '
1042        printf $F "update $a" "$m" "$m" "$m" >stdin &&
1043        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1044        grep "fatal: unknown command: $m" err
1045'
1046
1047test_expect_success 'stdin -z fails delete with no ref' '
1048        printf $F "delete " >stdin &&
1049        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1050        grep "fatal: delete: missing <ref>" err
1051'
1052
1053test_expect_success 'stdin -z fails delete with no old value' '
1054        printf $F "delete $a" >stdin &&
1055        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1056        grep "fatal: delete $a: unexpected end of input when reading <oldvalue>" err
1057'
1058
1059test_expect_success 'stdin -z fails delete with too many arguments' '
1060        printf $F "delete $a" "$m" "$m" >stdin &&
1061        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1062        grep "fatal: unknown command: $m" err
1063'
1064
1065test_expect_success 'stdin -z fails verify with too many arguments' '
1066        printf $F "verify $a" "$m" "$m" >stdin &&
1067        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1068        grep "fatal: unknown command: $m" err
1069'
1070
1071test_expect_success 'stdin -z fails verify with no old value' '
1072        printf $F "verify $a" >stdin &&
1073        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1074        grep "fatal: verify $a: unexpected end of input when reading <oldvalue>" err
1075'
1076
1077test_expect_success 'stdin -z fails option with unknown name' '
1078        printf $F "option unknown" >stdin &&
1079        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1080        grep "fatal: option unknown: unknown" err
1081'
1082
1083test_expect_success 'stdin -z fails with duplicate refs' '
1084        printf $F "create $a" "$m" "create $b" "$m" "create $a" "$m" >stdin &&
1085        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1086        test_i18ngrep "fatal: multiple updates for ref '"'"'$a'"'"' not allowed" err
1087'
1088
1089test_expect_success 'stdin -z create ref works' '
1090        printf $F "create $a" "$m" >stdin &&
1091        git update-ref -z --stdin <stdin &&
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 ref creates with zero old value' '
1098        printf $F "update $b" "$m" "$Z" >stdin &&
1099        git update-ref -z --stdin <stdin &&
1100        git rev-parse $m >expect &&
1101        git rev-parse $b >actual &&
1102        test_cmp expect actual &&
1103        git update-ref -d $b
1104'
1105
1106test_expect_success 'stdin -z update ref creates with empty old value' '
1107        printf $F "update $b" "$m" "" >stdin &&
1108        git update-ref -z --stdin <stdin &&
1109        git rev-parse $m >expect &&
1110        git rev-parse $b >actual &&
1111        test_cmp expect actual
1112'
1113
1114test_expect_success 'stdin -z create ref works with path with space to blob' '
1115        printf $F "create refs/blobs/pws" "$m:$pws" >stdin &&
1116        git update-ref -z --stdin <stdin &&
1117        git rev-parse "$m:$pws" >expect &&
1118        git rev-parse refs/blobs/pws >actual &&
1119        test_cmp expect actual &&
1120        git update-ref -d refs/blobs/pws
1121'
1122
1123test_expect_success 'stdin -z update ref fails with wrong old value' '
1124        printf $F "update $c" "$m" "$m~1" >stdin &&
1125        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1126        grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
1127        test_must_fail git rev-parse --verify -q $c
1128'
1129
1130test_expect_success 'stdin -z update ref fails with bad old value' '
1131        printf $F "update $c" "$m" "does-not-exist" >stdin &&
1132        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1133        grep "fatal: update $c: invalid <oldvalue>: does-not-exist" err &&
1134        test_must_fail git rev-parse --verify -q $c
1135'
1136
1137test_expect_success 'stdin -z create ref fails when ref exists' '
1138        git update-ref $c $m &&
1139        git rev-parse "$c" >expect &&
1140        printf $F "create $c" "$m~1" >stdin &&
1141        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1142        grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
1143        git rev-parse "$c" >actual &&
1144        test_cmp expect actual
1145'
1146
1147test_expect_success 'stdin -z create ref fails with bad new value' '
1148        git update-ref -d "$c" &&
1149        printf $F "create $c" "does-not-exist" >stdin &&
1150        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1151        grep "fatal: create $c: invalid <newvalue>: does-not-exist" err &&
1152        test_must_fail git rev-parse --verify -q $c
1153'
1154
1155test_expect_success 'stdin -z create ref fails with empty new value' '
1156        printf $F "create $c" "" >stdin &&
1157        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1158        grep "fatal: create $c: missing <newvalue>" err &&
1159        test_must_fail git rev-parse --verify -q $c
1160'
1161
1162test_expect_success 'stdin -z update ref works with right old value' '
1163        printf $F "update $b" "$m~1" "$m" >stdin &&
1164        git update-ref -z --stdin <stdin &&
1165        git rev-parse $m~1 >expect &&
1166        git rev-parse $b >actual &&
1167        test_cmp expect actual
1168'
1169
1170test_expect_success 'stdin -z delete ref fails with wrong old value' '
1171        printf $F "delete $a" "$m~1" >stdin &&
1172        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1173        grep "fatal: cannot lock ref '"'"'$a'"'"'" err &&
1174        git rev-parse $m >expect &&
1175        git rev-parse $a >actual &&
1176        test_cmp expect actual
1177'
1178
1179test_expect_success 'stdin -z delete ref fails with zero old value' '
1180        printf $F "delete $a" "$Z" >stdin &&
1181        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1182        grep "fatal: delete $a: zero <oldvalue>" err &&
1183        git rev-parse $m >expect &&
1184        git rev-parse $a >actual &&
1185        test_cmp expect actual
1186'
1187
1188test_expect_success 'stdin -z update symref works option no-deref' '
1189        git symbolic-ref TESTSYMREF $b &&
1190        printf $F "option no-deref" "update TESTSYMREF" "$a" "$b" >stdin &&
1191        git update-ref -z --stdin <stdin &&
1192        git rev-parse TESTSYMREF >expect &&
1193        git rev-parse $a >actual &&
1194        test_cmp expect actual &&
1195        git rev-parse $m~1 >expect &&
1196        git rev-parse $b >actual &&
1197        test_cmp expect actual
1198'
1199
1200test_expect_success 'stdin -z delete symref works option no-deref' '
1201        git symbolic-ref TESTSYMREF $b &&
1202        printf $F "option no-deref" "delete TESTSYMREF" "$b" >stdin &&
1203        git update-ref -z --stdin <stdin &&
1204        test_must_fail git rev-parse --verify -q TESTSYMREF &&
1205        git rev-parse $m~1 >expect &&
1206        git rev-parse $b >actual &&
1207        test_cmp expect actual
1208'
1209
1210test_expect_success 'stdin -z delete ref works with right old value' '
1211        printf $F "delete $b" "$m~1" >stdin &&
1212        git update-ref -z --stdin <stdin &&
1213        test_must_fail git rev-parse --verify -q $b
1214'
1215
1216test_expect_success 'stdin -z update/create/verify combination works' '
1217        printf $F "update $a" "$m" "" "create $b" "$m" "verify $c" "" >stdin &&
1218        git update-ref -z --stdin <stdin &&
1219        git rev-parse $m >expect &&
1220        git rev-parse $a >actual &&
1221        test_cmp expect actual &&
1222        git rev-parse $b >actual &&
1223        test_cmp expect actual &&
1224        test_must_fail git rev-parse --verify -q $c
1225'
1226
1227test_expect_success 'stdin -z verify succeeds for correct value' '
1228        git rev-parse $m >expect &&
1229        printf $F "verify $m" "$m" >stdin &&
1230        git update-ref -z --stdin <stdin &&
1231        git rev-parse $m >actual &&
1232        test_cmp expect actual
1233'
1234
1235test_expect_success 'stdin -z verify succeeds for missing reference' '
1236        printf $F "verify refs/heads/missing" "$Z" >stdin &&
1237        git update-ref -z --stdin <stdin &&
1238        test_must_fail git rev-parse --verify -q refs/heads/missing
1239'
1240
1241test_expect_success 'stdin -z verify treats no value as missing' '
1242        printf $F "verify refs/heads/missing" "" >stdin &&
1243        git update-ref -z --stdin <stdin &&
1244        test_must_fail git rev-parse --verify -q refs/heads/missing
1245'
1246
1247test_expect_success 'stdin -z verify fails for wrong value' '
1248        git rev-parse $m >expect &&
1249        printf $F "verify $m" "$m~1" >stdin &&
1250        test_must_fail git update-ref -z --stdin <stdin &&
1251        git rev-parse $m >actual &&
1252        test_cmp expect actual
1253'
1254
1255test_expect_success 'stdin -z verify fails for mistaken null value' '
1256        git rev-parse $m >expect &&
1257        printf $F "verify $m" "$Z" >stdin &&
1258        test_must_fail git update-ref -z --stdin <stdin &&
1259        git rev-parse $m >actual &&
1260        test_cmp expect actual
1261'
1262
1263test_expect_success 'stdin -z verify fails for mistaken empty value' '
1264        M=$(git rev-parse $m) &&
1265        test_when_finished "git update-ref $m $M" &&
1266        git rev-parse $m >expect &&
1267        printf $F "verify $m" "" >stdin &&
1268        test_must_fail git update-ref -z --stdin <stdin &&
1269        git rev-parse $m >actual &&
1270        test_cmp expect actual
1271'
1272
1273test_expect_success 'stdin -z update refs works with identity updates' '
1274        printf $F "update $a" "$m" "$m" "update $b" "$m" "$m" "update $c" "$Z" "" >stdin &&
1275        git update-ref -z --stdin <stdin &&
1276        git rev-parse $m >expect &&
1277        git rev-parse $a >actual &&
1278        test_cmp expect actual &&
1279        git rev-parse $b >actual &&
1280        test_cmp expect actual &&
1281        test_must_fail git rev-parse --verify -q $c
1282'
1283
1284test_expect_success 'stdin -z update refs fails with wrong old value' '
1285        git update-ref $c $m &&
1286        printf $F "update $a" "$m" "$m" "update $b" "$m" "$m" "update $c" "$m" "$Z" >stdin &&
1287        test_must_fail git update-ref -z --stdin <stdin 2>err &&
1288        grep "fatal: cannot lock ref '"'"'$c'"'"'" err &&
1289        git rev-parse $m >expect &&
1290        git rev-parse $a >actual &&
1291        test_cmp expect actual &&
1292        git rev-parse $b >actual &&
1293        test_cmp expect actual &&
1294        git rev-parse $c >actual &&
1295        test_cmp expect actual
1296'
1297
1298test_expect_success 'stdin -z delete refs works with packed and loose refs' '
1299        git pack-refs --all &&
1300        git update-ref $c $m~1 &&
1301        printf $F "delete $a" "$m" "update $b" "$Z" "$m" "update $c" "" "$m~1" >stdin &&
1302        git update-ref -z --stdin <stdin &&
1303        test_must_fail git rev-parse --verify -q $a &&
1304        test_must_fail git rev-parse --verify -q $b &&
1305        test_must_fail git rev-parse --verify -q $c
1306'
1307
1308test_expect_success 'fails with duplicate HEAD update' '
1309        git branch target1 $A &&
1310        git checkout target1 &&
1311        cat >stdin <<-EOF &&
1312        update refs/heads/target1 $C
1313        option no-deref
1314        update HEAD $B
1315        EOF
1316        test_must_fail git update-ref --stdin <stdin 2>err &&
1317        test_i18ngrep "fatal: multiple updates for '\''HEAD'\'' (including one via its referent .refs/heads/target1.) are not allowed" err &&
1318        echo "refs/heads/target1" >expect &&
1319        git symbolic-ref HEAD >actual &&
1320        test_cmp expect actual &&
1321        echo "$A" >expect &&
1322        git rev-parse refs/heads/target1 >actual &&
1323        test_cmp expect actual
1324'
1325
1326test_expect_success 'fails with duplicate ref update via symref' '
1327        git branch target2 $A &&
1328        git symbolic-ref refs/heads/symref2 refs/heads/target2 &&
1329        cat >stdin <<-EOF &&
1330        update refs/heads/target2 $C
1331        update refs/heads/symref2 $B
1332        EOF
1333        test_must_fail git update-ref --stdin <stdin 2>err &&
1334        test_i18ngrep "fatal: multiple updates for '\''refs/heads/target2'\'' (including one via symref .refs/heads/symref2.) are not allowed" err &&
1335        echo "refs/heads/target2" >expect &&
1336        git symbolic-ref refs/heads/symref2 >actual &&
1337        test_cmp expect actual &&
1338        echo "$A" >expect &&
1339        git rev-parse refs/heads/target2 >actual &&
1340        test_cmp expect actual
1341'
1342
1343run_with_limited_open_files () {
1344        (ulimit -n 32 && "$@")
1345}
1346
1347test_lazy_prereq ULIMIT_FILE_DESCRIPTORS '
1348        test_have_prereq !MINGW,!CYGWIN &&
1349        run_with_limited_open_files true
1350'
1351
1352test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction creating branches does not burst open file limit' '
1353(
1354        for i in $(test_seq 33)
1355        do
1356                echo "create refs/heads/$i HEAD"
1357        done >large_input &&
1358        run_with_limited_open_files git update-ref --stdin <large_input &&
1359        git rev-parse --verify -q refs/heads/33
1360)
1361'
1362
1363test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction deleting branches does not burst open file limit' '
1364(
1365        for i in $(test_seq 33)
1366        do
1367                echo "delete refs/heads/$i HEAD"
1368        done >large_input &&
1369        run_with_limited_open_files git update-ref --stdin <large_input &&
1370        test_must_fail git rev-parse --verify -q refs/heads/33
1371)
1372'
1373
1374test_expect_success 'handle per-worktree refs in refs/bisect' '
1375        git commit --allow-empty -m "initial commit" &&
1376        git worktree add -b branch worktree &&
1377        (
1378                cd worktree &&
1379                git commit --allow-empty -m "test commit"  &&
1380                git for-each-ref >for-each-ref.out &&
1381                ! grep refs/bisect for-each-ref.out &&
1382                git update-ref refs/bisect/something HEAD &&
1383                git rev-parse refs/bisect/something >../worktree-head &&
1384                git for-each-ref | grep refs/bisect/something
1385        ) &&
1386        test_path_is_missing .git/refs/bisect &&
1387        test_must_fail git rev-parse refs/bisect/something &&
1388        git update-ref refs/bisect/something HEAD &&
1389        git rev-parse refs/bisect/something >main-head &&
1390        ! test_cmp main-head worktree-head
1391'
1392
1393test_done