t / t6302-for-each-ref-filter.shon commit Merge branch 'tb/banned-vsprintf-namefix' (37801f0)
   1#!/bin/sh
   2
   3test_description='test for-each-refs usage of ref-filter APIs'
   4
   5. ./test-lib.sh
   6. "$TEST_DIRECTORY"/lib-gpg.sh
   7
   8test_expect_success 'setup some history and refs' '
   9        test_commit one &&
  10        test_commit two &&
  11        test_commit three &&
  12        git checkout -b side &&
  13        test_commit four &&
  14        git tag -m "An annotated tag" annotated-tag &&
  15        git tag -m "Annonated doubly" doubly-annotated-tag annotated-tag &&
  16
  17        # Note that these "signed" tags might not actually be signed.
  18        # Tests which care about the distinction should be marked
  19        # with the GPG prereq.
  20        if test_have_prereq GPG
  21        then
  22                sign=-s
  23        else
  24                sign=
  25        fi &&
  26        git tag $sign -m "A signed tag" signed-tag &&
  27        git tag $sign -m "Signed doubly" doubly-signed-tag signed-tag &&
  28
  29        git checkout master &&
  30        git update-ref refs/odd/spot master
  31'
  32
  33test_expect_success 'filtering with --points-at' '
  34        cat >expect <<-\EOF &&
  35        refs/heads/master
  36        refs/odd/spot
  37        refs/tags/three
  38        EOF
  39        git for-each-ref --format="%(refname)" --points-at=master >actual &&
  40        test_cmp expect actual
  41'
  42
  43test_expect_success 'check signed tags with --points-at' '
  44        sed -e "s/Z$//" >expect <<-\EOF &&
  45        refs/heads/side Z
  46        refs/tags/annotated-tag four
  47        refs/tags/four Z
  48        refs/tags/signed-tag four
  49        EOF
  50        git for-each-ref --format="%(refname) %(*subject)" --points-at=side >actual &&
  51        test_cmp expect actual
  52'
  53
  54test_expect_success 'filtering with --merged' '
  55        cat >expect <<-\EOF &&
  56        refs/heads/master
  57        refs/odd/spot
  58        refs/tags/one
  59        refs/tags/three
  60        refs/tags/two
  61        EOF
  62        git for-each-ref --format="%(refname)" --merged=master >actual &&
  63        test_cmp expect actual
  64'
  65
  66test_expect_success 'filtering with --no-merged' '
  67        cat >expect <<-\EOF &&
  68        refs/heads/side
  69        refs/tags/annotated-tag
  70        refs/tags/doubly-annotated-tag
  71        refs/tags/doubly-signed-tag
  72        refs/tags/four
  73        refs/tags/signed-tag
  74        EOF
  75        git for-each-ref --format="%(refname)" --no-merged=master >actual &&
  76        test_cmp expect actual
  77'
  78
  79test_expect_success 'filtering with --contains' '
  80        cat >expect <<-\EOF &&
  81        refs/heads/master
  82        refs/heads/side
  83        refs/odd/spot
  84        refs/tags/annotated-tag
  85        refs/tags/doubly-annotated-tag
  86        refs/tags/doubly-signed-tag
  87        refs/tags/four
  88        refs/tags/signed-tag
  89        refs/tags/three
  90        refs/tags/two
  91        EOF
  92        git for-each-ref --format="%(refname)" --contains=two >actual &&
  93        test_cmp expect actual
  94'
  95
  96test_expect_success 'filtering with --no-contains' '
  97        cat >expect <<-\EOF &&
  98        refs/tags/one
  99        EOF
 100        git for-each-ref --format="%(refname)" --no-contains=two >actual &&
 101        test_cmp expect actual
 102'
 103
 104test_expect_success 'filtering with --contains and --no-contains' '
 105        cat >expect <<-\EOF &&
 106        refs/tags/two
 107        EOF
 108        git for-each-ref --format="%(refname)" --contains=two --no-contains=three >actual &&
 109        test_cmp expect actual
 110'
 111
 112test_expect_success '%(color) must fail' '
 113        test_must_fail git for-each-ref --format="%(color)%(refname)"
 114'
 115
 116test_expect_success 'left alignment is default' '
 117        cat >expect <<-\EOF &&
 118        refname is refs/heads/master  |refs/heads/master
 119        refname is refs/heads/side    |refs/heads/side
 120        refname is refs/odd/spot      |refs/odd/spot
 121        refname is refs/tags/annotated-tag|refs/tags/annotated-tag
 122        refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
 123        refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
 124        refname is refs/tags/four     |refs/tags/four
 125        refname is refs/tags/one      |refs/tags/one
 126        refname is refs/tags/signed-tag|refs/tags/signed-tag
 127        refname is refs/tags/three    |refs/tags/three
 128        refname is refs/tags/two      |refs/tags/two
 129        EOF
 130        git for-each-ref --format="%(align:30)refname is %(refname)%(end)|%(refname)" >actual &&
 131        test_cmp expect actual
 132'
 133
 134test_expect_success 'middle alignment' '
 135        cat >expect <<-\EOF &&
 136        | refname is refs/heads/master |refs/heads/master
 137        |  refname is refs/heads/side  |refs/heads/side
 138        |   refname is refs/odd/spot   |refs/odd/spot
 139        |refname is refs/tags/annotated-tag|refs/tags/annotated-tag
 140        |refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
 141        |refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
 142        |  refname is refs/tags/four   |refs/tags/four
 143        |   refname is refs/tags/one   |refs/tags/one
 144        |refname is refs/tags/signed-tag|refs/tags/signed-tag
 145        |  refname is refs/tags/three  |refs/tags/three
 146        |   refname is refs/tags/two   |refs/tags/two
 147        EOF
 148        git for-each-ref --format="|%(align:middle,30)refname is %(refname)%(end)|%(refname)" >actual &&
 149        test_cmp expect actual
 150'
 151
 152test_expect_success 'right alignment' '
 153        cat >expect <<-\EOF &&
 154        |  refname is refs/heads/master|refs/heads/master
 155        |    refname is refs/heads/side|refs/heads/side
 156        |      refname is refs/odd/spot|refs/odd/spot
 157        |refname is refs/tags/annotated-tag|refs/tags/annotated-tag
 158        |refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
 159        |refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
 160        |     refname is refs/tags/four|refs/tags/four
 161        |      refname is refs/tags/one|refs/tags/one
 162        |refname is refs/tags/signed-tag|refs/tags/signed-tag
 163        |    refname is refs/tags/three|refs/tags/three
 164        |      refname is refs/tags/two|refs/tags/two
 165        EOF
 166        git for-each-ref --format="|%(align:30,right)refname is %(refname)%(end)|%(refname)" >actual &&
 167        test_cmp expect actual
 168'
 169
 170cat >expect <<-\EOF
 171|       refname is refs/heads/master       |refs/heads/master
 172|        refname is refs/heads/side        |refs/heads/side
 173|         refname is refs/odd/spot         |refs/odd/spot
 174|    refname is refs/tags/annotated-tag    |refs/tags/annotated-tag
 175|refname is refs/tags/doubly-annotated-tag |refs/tags/doubly-annotated-tag
 176|  refname is refs/tags/doubly-signed-tag  |refs/tags/doubly-signed-tag
 177|        refname is refs/tags/four         |refs/tags/four
 178|         refname is refs/tags/one         |refs/tags/one
 179|     refname is refs/tags/signed-tag      |refs/tags/signed-tag
 180|        refname is refs/tags/three        |refs/tags/three
 181|         refname is refs/tags/two         |refs/tags/two
 182EOF
 183
 184test_align_permutations() {
 185        while read -r option
 186        do
 187                test_expect_success "align:$option" '
 188                        git for-each-ref --format="|%(align:$option)refname is %(refname)%(end)|%(refname)" >actual &&
 189                        test_cmp expect actual
 190                '
 191        done
 192}
 193
 194test_align_permutations <<-\EOF
 195        middle,42
 196        42,middle
 197        position=middle,42
 198        42,position=middle
 199        middle,width=42
 200        width=42,middle
 201        position=middle,width=42
 202        width=42,position=middle
 203EOF
 204
 205# Last one wins (silently) when multiple arguments of the same type are given
 206
 207test_align_permutations <<-\EOF
 208        32,width=42,middle
 209        width=30,42,middle
 210        width=42,position=right,middle
 211        42,right,position=middle
 212EOF
 213
 214# Individual atoms inside %(align:...) and %(end) must not be quoted.
 215
 216test_expect_success 'alignment with format quote' "
 217        cat >expect <<-\EOF &&
 218        |'      '\''master| A U Thor'\''      '|
 219        |'       '\''side| A U Thor'\''       '|
 220        |'     '\''odd/spot| A U Thor'\''     '|
 221        |'      '\''annotated-tag| '\''       '|
 222        |'   '\''doubly-annotated-tag| '\''   '|
 223        |'    '\''doubly-signed-tag| '\''     '|
 224        |'       '\''four| A U Thor'\''       '|
 225        |'       '\''one| A U Thor'\''        '|
 226        |'        '\''signed-tag| '\''        '|
 227        |'      '\''three| A U Thor'\''       '|
 228        |'       '\''two| A U Thor'\''        '|
 229        EOF
 230        git for-each-ref --shell --format=\"|%(align:30,middle)'%(refname:short)| %(authorname)'%(end)|\" >actual &&
 231        test_cmp expect actual
 232"
 233
 234test_expect_success 'nested alignment with quote formatting' "
 235        cat >expect <<-\EOF &&
 236        |'         master               '|
 237        |'           side               '|
 238        |'       odd/spot               '|
 239        |'  annotated-tag               '|
 240        |'doubly-annotated-tag          '|
 241        |'doubly-signed-tag             '|
 242        |'           four               '|
 243        |'            one               '|
 244        |'     signed-tag               '|
 245        |'          three               '|
 246        |'            two               '|
 247        EOF
 248        git for-each-ref --shell --format='|%(align:30,left)%(align:15,right)%(refname:short)%(end)%(end)|' >actual &&
 249        test_cmp expect actual
 250"
 251
 252test_expect_success 'check `%(contents:lines=1)`' '
 253        cat >expect <<-\EOF &&
 254        master |three
 255        side |four
 256        odd/spot |three
 257        annotated-tag |An annotated tag
 258        doubly-annotated-tag |Annonated doubly
 259        doubly-signed-tag |Signed doubly
 260        four |four
 261        one |one
 262        signed-tag |A signed tag
 263        three |three
 264        two |two
 265        EOF
 266        git for-each-ref --format="%(refname:short) |%(contents:lines=1)" >actual &&
 267        test_cmp expect actual
 268'
 269
 270test_expect_success 'check `%(contents:lines=0)`' '
 271        cat >expect <<-\EOF &&
 272        master |
 273        side |
 274        odd/spot |
 275        annotated-tag |
 276        doubly-annotated-tag |
 277        doubly-signed-tag |
 278        four |
 279        one |
 280        signed-tag |
 281        three |
 282        two |
 283        EOF
 284        git for-each-ref --format="%(refname:short) |%(contents:lines=0)" >actual &&
 285        test_cmp expect actual
 286'
 287
 288test_expect_success 'check `%(contents:lines=99999)`' '
 289        cat >expect <<-\EOF &&
 290        master |three
 291        side |four
 292        odd/spot |three
 293        annotated-tag |An annotated tag
 294        doubly-annotated-tag |Annonated doubly
 295        doubly-signed-tag |Signed doubly
 296        four |four
 297        one |one
 298        signed-tag |A signed tag
 299        three |three
 300        two |two
 301        EOF
 302        git for-each-ref --format="%(refname:short) |%(contents:lines=99999)" >actual &&
 303        test_cmp expect actual
 304'
 305
 306test_expect_success '`%(contents:lines=-1)` should fail' '
 307        test_must_fail git for-each-ref --format="%(refname:short) |%(contents:lines=-1)"
 308'
 309
 310test_expect_success 'setup for version sort' '
 311        test_commit foo1.3 &&
 312        test_commit foo1.6 &&
 313        test_commit foo1.10
 314'
 315
 316test_expect_success 'version sort' '
 317        git for-each-ref --sort=version:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
 318        cat >expect <<-\EOF &&
 319        foo1.3
 320        foo1.6
 321        foo1.10
 322        EOF
 323        test_cmp expect actual
 324'
 325
 326test_expect_success 'version sort (shortened)' '
 327        git for-each-ref --sort=v:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
 328        cat >expect <<-\EOF &&
 329        foo1.3
 330        foo1.6
 331        foo1.10
 332        EOF
 333        test_cmp expect actual
 334'
 335
 336test_expect_success 'reverse version sort' '
 337        git for-each-ref --sort=-version:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
 338        cat >expect <<-\EOF &&
 339        foo1.10
 340        foo1.6
 341        foo1.3
 342        EOF
 343        test_cmp expect actual
 344'
 345
 346test_expect_success 'improper usage of %(if), %(then), %(else) and %(end) atoms' '
 347        test_must_fail git for-each-ref --format="%(if)" &&
 348        test_must_fail git for-each-ref --format="%(then) %(end)" &&
 349        test_must_fail git for-each-ref --format="%(else) %(end)" &&
 350        test_must_fail git for-each-ref --format="%(if) %(else) %(end)" &&
 351        test_must_fail git for-each-ref --format="%(if) %(then) %(then) %(end)" &&
 352        test_must_fail git for-each-ref --format="%(then) %(else) %(end)" &&
 353        test_must_fail git for-each-ref --format="%(if) %(else) %(end)" &&
 354        test_must_fail git for-each-ref --format="%(if) %(then) %(else)" &&
 355        test_must_fail git for-each-ref --format="%(if) %(else) %(then) %(end)" &&
 356        test_must_fail git for-each-ref --format="%(if) %(then) %(else) %(else) %(end)" &&
 357        test_must_fail git for-each-ref --format="%(if) %(end)"
 358'
 359
 360test_expect_success 'check %(if)...%(then)...%(end) atoms' '
 361        git for-each-ref --format="%(refname)%(if)%(authorname)%(then) Author: %(authorname)%(end)" >actual &&
 362        cat >expect <<-\EOF &&
 363        refs/heads/master Author: A U Thor
 364        refs/heads/side Author: A U Thor
 365        refs/odd/spot Author: A U Thor
 366        refs/tags/annotated-tag
 367        refs/tags/doubly-annotated-tag
 368        refs/tags/doubly-signed-tag
 369        refs/tags/foo1.10 Author: A U Thor
 370        refs/tags/foo1.3 Author: A U Thor
 371        refs/tags/foo1.6 Author: A U Thor
 372        refs/tags/four Author: A U Thor
 373        refs/tags/one Author: A U Thor
 374        refs/tags/signed-tag
 375        refs/tags/three Author: A U Thor
 376        refs/tags/two Author: A U Thor
 377        EOF
 378        test_cmp expect actual
 379'
 380
 381test_expect_success 'check %(if)...%(then)...%(else)...%(end) atoms' '
 382        git for-each-ref --format="%(if)%(authorname)%(then)%(authorname)%(else)No author%(end): %(refname)" >actual &&
 383        cat >expect <<-\EOF &&
 384        A U Thor: refs/heads/master
 385        A U Thor: refs/heads/side
 386        A U Thor: refs/odd/spot
 387        No author: refs/tags/annotated-tag
 388        No author: refs/tags/doubly-annotated-tag
 389        No author: refs/tags/doubly-signed-tag
 390        A U Thor: refs/tags/foo1.10
 391        A U Thor: refs/tags/foo1.3
 392        A U Thor: refs/tags/foo1.6
 393        A U Thor: refs/tags/four
 394        A U Thor: refs/tags/one
 395        No author: refs/tags/signed-tag
 396        A U Thor: refs/tags/three
 397        A U Thor: refs/tags/two
 398        EOF
 399        test_cmp expect actual
 400'
 401test_expect_success 'ignore spaces in %(if) atom usage' '
 402        git for-each-ref --format="%(refname:short): %(if)%(HEAD)%(then)Head ref%(else)Not Head ref%(end)" >actual &&
 403        cat >expect <<-\EOF &&
 404        master: Head ref
 405        side: Not Head ref
 406        odd/spot: Not Head ref
 407        annotated-tag: Not Head ref
 408        doubly-annotated-tag: Not Head ref
 409        doubly-signed-tag: Not Head ref
 410        foo1.10: Not Head ref
 411        foo1.3: Not Head ref
 412        foo1.6: Not Head ref
 413        four: Not Head ref
 414        one: Not Head ref
 415        signed-tag: Not Head ref
 416        three: Not Head ref
 417        two: Not Head ref
 418        EOF
 419        test_cmp expect actual
 420'
 421
 422test_expect_success 'check %(if:equals=<string>)' '
 423        git for-each-ref --format="%(if:equals=master)%(refname:short)%(then)Found master%(else)Not master%(end)" refs/heads/ >actual &&
 424        cat >expect <<-\EOF &&
 425        Found master
 426        Not master
 427        EOF
 428        test_cmp expect actual
 429'
 430
 431test_expect_success 'check %(if:notequals=<string>)' '
 432        git for-each-ref --format="%(if:notequals=master)%(refname:short)%(then)Not master%(else)Found master%(end)" refs/heads/ >actual &&
 433        cat >expect <<-\EOF &&
 434        Found master
 435        Not master
 436        EOF
 437        test_cmp expect actual
 438'
 439
 440test_expect_success '--merged is incompatible with --no-merged' '
 441        test_must_fail git for-each-ref --merged HEAD --no-merged HEAD
 442'
 443
 444test_expect_success 'validate worktree atom' '
 445        cat >expect <<-EOF &&
 446        master: $(pwd)
 447        master_worktree: $(pwd)/worktree_dir
 448        side: not checked out
 449        EOF
 450        git worktree add -b master_worktree worktree_dir master &&
 451        git for-each-ref --format="%(refname:short): %(if)%(worktreepath)%(then)%(worktreepath)%(else)not checked out%(end)" refs/heads/ >actual &&
 452        rm -r worktree_dir &&
 453        git worktree prune &&
 454        test_cmp expect actual
 455'
 456
 457test_done