675c2a2cfe2b20050ad68e58e1befd414cdd4866
   1#!/bin/sh
   2#
   3# Copyright (c) 2007 Andy Parkins
   4#
   5
   6test_description='for-each-ref test'
   7
   8. ./test-lib.sh
   9. "$TEST_DIRECTORY"/lib-gpg.sh
  10
  11# Mon Jul 3 15:18:43 2006 +0000
  12datestamp=1151939923
  13setdate_and_increment () {
  14    GIT_COMMITTER_DATE="$datestamp +0200"
  15    datestamp=$(expr "$datestamp" + 1)
  16    GIT_AUTHOR_DATE="$datestamp +0200"
  17    datestamp=$(expr "$datestamp" + 1)
  18    export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
  19}
  20
  21test_expect_success setup '
  22        setdate_and_increment &&
  23        echo "Using $datestamp" > one &&
  24        git add one &&
  25        git commit -m "Initial" &&
  26        setdate_and_increment &&
  27        git tag -a -m "Tagging at $datestamp" testtag &&
  28        git update-ref refs/remotes/origin/master master &&
  29        git remote add origin nowhere &&
  30        git config branch.master.remote origin &&
  31        git config branch.master.merge refs/heads/master
  32'
  33
  34test_atom() {
  35        case "$1" in
  36                head) ref=refs/heads/master ;;
  37                 tag) ref=refs/tags/testtag ;;
  38                   *) ref=$1 ;;
  39        esac
  40        printf '%s\n' "$3" >expected
  41        test_expect_${4:-success} $PREREQ "basic atom: $1 $2" "
  42                git for-each-ref --format='%($2)' $ref >actual &&
  43                sanitize_pgp <actual >actual.clean &&
  44                test_cmp expected actual.clean
  45        "
  46}
  47
  48test_atom head refname refs/heads/master
  49test_atom head upstream refs/remotes/origin/master
  50test_atom head objecttype commit
  51test_atom head objectsize 171
  52test_atom head objectname $(git rev-parse refs/heads/master)
  53test_atom head tree $(git rev-parse refs/heads/master^{tree})
  54test_atom head parent ''
  55test_atom head numparent 0
  56test_atom head object ''
  57test_atom head type ''
  58test_atom head author 'A U Thor <author@example.com> 1151939924 +0200'
  59test_atom head authorname 'A U Thor'
  60test_atom head authoremail '<author@example.com>'
  61test_atom head authordate 'Mon Jul 3 17:18:44 2006 +0200'
  62test_atom head committer 'C O Mitter <committer@example.com> 1151939923 +0200'
  63test_atom head committername 'C O Mitter'
  64test_atom head committeremail '<committer@example.com>'
  65test_atom head committerdate 'Mon Jul 3 17:18:43 2006 +0200'
  66test_atom head tag ''
  67test_atom head tagger ''
  68test_atom head taggername ''
  69test_atom head taggeremail ''
  70test_atom head taggerdate ''
  71test_atom head creator 'C O Mitter <committer@example.com> 1151939923 +0200'
  72test_atom head creatordate 'Mon Jul 3 17:18:43 2006 +0200'
  73test_atom head subject 'Initial'
  74test_atom head contents:subject 'Initial'
  75test_atom head body ''
  76test_atom head contents:body ''
  77test_atom head contents:signature ''
  78test_atom head contents 'Initial
  79'
  80
  81test_atom tag refname refs/tags/testtag
  82test_atom tag upstream ''
  83test_atom tag objecttype tag
  84test_atom tag objectsize 154
  85test_atom tag objectname $(git rev-parse refs/tags/testtag)
  86test_atom tag tree ''
  87test_atom tag parent ''
  88test_atom tag numparent ''
  89test_atom tag object $(git rev-parse refs/tags/testtag^0)
  90test_atom tag type 'commit'
  91test_atom tag author ''
  92test_atom tag authorname ''
  93test_atom tag authoremail ''
  94test_atom tag authordate ''
  95test_atom tag committer ''
  96test_atom tag committername ''
  97test_atom tag committeremail ''
  98test_atom tag committerdate ''
  99test_atom tag tag 'testtag'
 100test_atom tag tagger 'C O Mitter <committer@example.com> 1151939925 +0200'
 101test_atom tag taggername 'C O Mitter'
 102test_atom tag taggeremail '<committer@example.com>'
 103test_atom tag taggerdate 'Mon Jul 3 17:18:45 2006 +0200'
 104test_atom tag creator 'C O Mitter <committer@example.com> 1151939925 +0200'
 105test_atom tag creatordate 'Mon Jul 3 17:18:45 2006 +0200'
 106test_atom tag subject 'Tagging at 1151939927'
 107test_atom tag contents:subject 'Tagging at 1151939927'
 108test_atom tag body ''
 109test_atom tag contents:body ''
 110test_atom tag contents:signature ''
 111test_atom tag contents 'Tagging at 1151939927
 112'
 113
 114test_expect_success 'Check invalid atoms names are errors' '
 115        test_must_fail git for-each-ref --format="%(INVALID)" refs/heads
 116'
 117
 118test_expect_success 'Check format specifiers are ignored in naming date atoms' '
 119        git for-each-ref --format="%(authordate)" refs/heads &&
 120        git for-each-ref --format="%(authordate:default) %(authordate)" refs/heads &&
 121        git for-each-ref --format="%(authordate) %(authordate:default)" refs/heads &&
 122        git for-each-ref --format="%(authordate:default) %(authordate:default)" refs/heads
 123'
 124
 125test_expect_success 'Check valid format specifiers for date fields' '
 126        git for-each-ref --format="%(authordate:default)" refs/heads &&
 127        git for-each-ref --format="%(authordate:relative)" refs/heads &&
 128        git for-each-ref --format="%(authordate:short)" refs/heads &&
 129        git for-each-ref --format="%(authordate:local)" refs/heads &&
 130        git for-each-ref --format="%(authordate:iso8601)" refs/heads &&
 131        git for-each-ref --format="%(authordate:rfc2822)" refs/heads
 132'
 133
 134test_expect_success 'Check invalid format specifiers are errors' '
 135        test_must_fail git for-each-ref --format="%(authordate:INVALID)" refs/heads
 136'
 137
 138cat >expected <<\EOF
 139'refs/heads/master' 'Mon Jul 3 17:18:43 2006 +0200' 'Mon Jul 3 17:18:44 2006 +0200'
 140'refs/tags/testtag' 'Mon Jul 3 17:18:45 2006 +0200'
 141EOF
 142
 143test_expect_success 'Check unformatted date fields output' '
 144        (git for-each-ref --shell --format="%(refname) %(committerdate) %(authordate)" refs/heads &&
 145        git for-each-ref --shell --format="%(refname) %(taggerdate)" refs/tags) >actual &&
 146        test_cmp expected actual
 147'
 148
 149test_expect_success 'Check format "default" formatted date fields output' '
 150        f=default &&
 151        (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads &&
 152        git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual &&
 153        test_cmp expected actual
 154'
 155
 156# Don't know how to do relative check because I can't know when this script
 157# is going to be run and can't fake the current time to git, and hence can't
 158# provide expected output.  Instead, I'll just make sure that "relative"
 159# doesn't exit in error
 160#
 161#cat >expected <<\EOF
 162#
 163#EOF
 164#
 165test_expect_success 'Check format "relative" date fields output' '
 166        f=relative &&
 167        (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads &&
 168        git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual
 169'
 170
 171cat >expected <<\EOF
 172'refs/heads/master' '2006-07-03' '2006-07-03'
 173'refs/tags/testtag' '2006-07-03'
 174EOF
 175
 176test_expect_success 'Check format "short" date fields output' '
 177        f=short &&
 178        (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads &&
 179        git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual &&
 180        test_cmp expected actual
 181'
 182
 183cat >expected <<\EOF
 184'refs/heads/master' 'Mon Jul 3 15:18:43 2006' 'Mon Jul 3 15:18:44 2006'
 185'refs/tags/testtag' 'Mon Jul 3 15:18:45 2006'
 186EOF
 187
 188test_expect_success 'Check format "local" date fields output' '
 189        f=local &&
 190        (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads &&
 191        git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual &&
 192        test_cmp expected actual
 193'
 194
 195cat >expected <<\EOF
 196'refs/heads/master' '2006-07-03 17:18:43 +0200' '2006-07-03 17:18:44 +0200'
 197'refs/tags/testtag' '2006-07-03 17:18:45 +0200'
 198EOF
 199
 200test_expect_success 'Check format "iso8601" date fields output' '
 201        f=iso8601 &&
 202        (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads &&
 203        git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual &&
 204        test_cmp expected actual
 205'
 206
 207cat >expected <<\EOF
 208'refs/heads/master' 'Mon, 3 Jul 2006 17:18:43 +0200' 'Mon, 3 Jul 2006 17:18:44 +0200'
 209'refs/tags/testtag' 'Mon, 3 Jul 2006 17:18:45 +0200'
 210EOF
 211
 212test_expect_success 'Check format "rfc2822" date fields output' '
 213        f=rfc2822 &&
 214        (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads &&
 215        git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual &&
 216        test_cmp expected actual
 217'
 218
 219cat >expected <<\EOF
 220refs/heads/master
 221refs/remotes/origin/master
 222refs/tags/testtag
 223EOF
 224
 225test_expect_success 'Verify ascending sort' '
 226        git for-each-ref --format="%(refname)" --sort=refname >actual &&
 227        test_cmp expected actual
 228'
 229
 230
 231cat >expected <<\EOF
 232refs/tags/testtag
 233refs/remotes/origin/master
 234refs/heads/master
 235EOF
 236
 237test_expect_success 'Verify descending sort' '
 238        git for-each-ref --format="%(refname)" --sort=-refname >actual &&
 239        test_cmp expected actual
 240'
 241
 242cat >expected <<\EOF
 243'refs/heads/master'
 244'refs/remotes/origin/master'
 245'refs/tags/testtag'
 246EOF
 247
 248test_expect_success 'Quoting style: shell' '
 249        git for-each-ref --shell --format="%(refname)" >actual &&
 250        test_cmp expected actual
 251'
 252
 253test_expect_success 'Quoting style: perl' '
 254        git for-each-ref --perl --format="%(refname)" >actual &&
 255        test_cmp expected actual
 256'
 257
 258test_expect_success 'Quoting style: python' '
 259        git for-each-ref --python --format="%(refname)" >actual &&
 260        test_cmp expected actual
 261'
 262
 263cat >expected <<\EOF
 264"refs/heads/master"
 265"refs/remotes/origin/master"
 266"refs/tags/testtag"
 267EOF
 268
 269test_expect_success 'Quoting style: tcl' '
 270        git for-each-ref --tcl --format="%(refname)" >actual &&
 271        test_cmp expected actual
 272'
 273
 274for i in "--perl --shell" "-s --python" "--python --tcl" "--tcl --perl"; do
 275        test_expect_success "more than one quoting style: $i" "
 276                git for-each-ref $i 2>&1 | (read line &&
 277                case \$line in
 278                \"error: more than one quoting style\"*) : happy;;
 279                *) false
 280                esac)
 281        "
 282done
 283
 284cat >expected <<\EOF
 285master
 286testtag
 287EOF
 288
 289test_expect_success 'Check short refname format' '
 290        (git for-each-ref --format="%(refname:short)" refs/heads &&
 291        git for-each-ref --format="%(refname:short)" refs/tags) >actual &&
 292        test_cmp expected actual
 293'
 294
 295cat >expected <<EOF
 296origin/master
 297EOF
 298
 299test_expect_success 'Check short upstream format' '
 300        git for-each-ref --format="%(upstream:short)" refs/heads >actual &&
 301        test_cmp expected actual
 302'
 303
 304cat >expected <<EOF
 305$(git rev-parse --short HEAD)
 306EOF
 307
 308test_expect_success 'Check short objectname format' '
 309        git for-each-ref --format="%(objectname:short)" refs/heads >actual &&
 310        test_cmp expected actual
 311'
 312
 313test_expect_success 'Check for invalid refname format' '
 314        test_must_fail git for-each-ref --format="%(refname:INVALID)"
 315'
 316
 317cat >expected <<\EOF
 318heads/master
 319tags/master
 320EOF
 321
 322test_expect_success 'Check ambiguous head and tag refs (strict)' '
 323        git config --bool core.warnambiguousrefs true &&
 324        git checkout -b newtag &&
 325        echo "Using $datestamp" > one &&
 326        git add one &&
 327        git commit -m "Branch" &&
 328        setdate_and_increment &&
 329        git tag -m "Tagging at $datestamp" master &&
 330        git for-each-ref --format "%(refname:short)" refs/heads/master refs/tags/master >actual &&
 331        test_cmp expected actual
 332'
 333
 334cat >expected <<\EOF
 335heads/master
 336master
 337EOF
 338
 339test_expect_success 'Check ambiguous head and tag refs (loose)' '
 340        git config --bool core.warnambiguousrefs false &&
 341        git for-each-ref --format "%(refname:short)" refs/heads/master refs/tags/master >actual &&
 342        test_cmp expected actual
 343'
 344
 345cat >expected <<\EOF
 346heads/ambiguous
 347ambiguous
 348EOF
 349
 350test_expect_success 'Check ambiguous head and tag refs II (loose)' '
 351        git checkout master &&
 352        git tag ambiguous testtag^0 &&
 353        git branch ambiguous testtag^0 &&
 354        git for-each-ref --format "%(refname:short)" refs/heads/ambiguous refs/tags/ambiguous >actual &&
 355        test_cmp expected actual
 356'
 357
 358test_expect_success 'an unusual tag with an incomplete line' '
 359
 360        git tag -m "bogo" bogo &&
 361        bogo=$(git cat-file tag bogo) &&
 362        bogo=$(printf "%s" "$bogo" | git mktag) &&
 363        git tag -f bogo "$bogo" &&
 364        git for-each-ref --format "%(body)" refs/tags/bogo
 365
 366'
 367
 368test_expect_success 'create tag with subject and body content' '
 369        cat >>msg <<-\EOF &&
 370                the subject line
 371
 372                first body line
 373                second body line
 374        EOF
 375        git tag -F msg subject-body
 376'
 377test_atom refs/tags/subject-body subject 'the subject line'
 378test_atom refs/tags/subject-body body 'first body line
 379second body line
 380'
 381test_atom refs/tags/subject-body contents 'the subject line
 382
 383first body line
 384second body line
 385'
 386
 387test_expect_success 'create tag with multiline subject' '
 388        cat >msg <<-\EOF &&
 389                first subject line
 390                second subject line
 391
 392                first body line
 393                second body line
 394        EOF
 395        git tag -F msg multiline
 396'
 397test_atom refs/tags/multiline subject 'first subject line second subject line'
 398test_atom refs/tags/multiline contents:subject 'first subject line second subject line'
 399test_atom refs/tags/multiline body 'first body line
 400second body line
 401'
 402test_atom refs/tags/multiline contents:body 'first body line
 403second body line
 404'
 405test_atom refs/tags/multiline contents:signature ''
 406test_atom refs/tags/multiline contents 'first subject line
 407second subject line
 408
 409first body line
 410second body line
 411'
 412
 413test_expect_success GPG 'create signed tags' '
 414        git tag -s -m "" signed-empty &&
 415        git tag -s -m "subject line" signed-short &&
 416        cat >msg <<-\EOF &&
 417        subject line
 418
 419        body contents
 420        EOF
 421        git tag -s -F msg signed-long
 422'
 423
 424sig='-----BEGIN PGP SIGNATURE-----
 425-----END PGP SIGNATURE-----
 426'
 427
 428PREREQ=GPG
 429test_atom refs/tags/signed-empty subject ''
 430test_atom refs/tags/signed-empty contents:subject ''
 431test_atom refs/tags/signed-empty body "$sig"
 432test_atom refs/tags/signed-empty contents:body ''
 433test_atom refs/tags/signed-empty contents:signature "$sig"
 434test_atom refs/tags/signed-empty contents "$sig"
 435
 436test_atom refs/tags/signed-short subject 'subject line'
 437test_atom refs/tags/signed-short contents:subject 'subject line'
 438test_atom refs/tags/signed-short body "$sig"
 439test_atom refs/tags/signed-short contents:body ''
 440test_atom refs/tags/signed-short contents:signature "$sig"
 441test_atom refs/tags/signed-short contents "subject line
 442$sig"
 443
 444test_atom refs/tags/signed-long subject 'subject line'
 445test_atom refs/tags/signed-long contents:subject 'subject line'
 446test_atom refs/tags/signed-long body "body contents
 447$sig"
 448test_atom refs/tags/signed-long contents:body 'body contents
 449'
 450test_atom refs/tags/signed-long contents:signature "$sig"
 451test_atom refs/tags/signed-long contents "subject line
 452
 453body contents
 454$sig"
 455
 456cat >expected <<EOF
 457$(git rev-parse refs/tags/master) <committer@example.com> refs/tags/master
 458$(git rev-parse refs/tags/bogo) <committer@example.com> refs/tags/bogo
 459EOF
 460
 461test_expect_success 'Verify sort with multiple keys' '
 462        git for-each-ref --format="%(objectname) %(taggeremail) %(refname)" --sort=objectname --sort=taggeremail \
 463                refs/tags/bogo refs/tags/master > actual &&
 464        test_cmp expected actual
 465'
 466test_done