t / t0003-attributes.shon commit Support "**" wildcard in .gitignore and .gitattributes (237ec6e)
   1#!/bin/sh
   2
   3test_description=gitattributes
   4
   5. ./test-lib.sh
   6
   7attr_check () {
   8        path="$1" expect="$2"
   9
  10        git $3 check-attr test -- "$path" >actual 2>err &&
  11        echo "$path: test: $2" >expect &&
  12        test_cmp expect actual &&
  13        test_line_count = 0 err
  14}
  15
  16
  17test_expect_success 'setup' '
  18        mkdir -p a/b/d a/c b &&
  19        (
  20                echo "[attr]notest !test"
  21                echo "f test=f"
  22                echo "a/i test=a/i"
  23                echo "onoff test -test"
  24                echo "offon -test test"
  25                echo "no notest"
  26                echo "A/e/F test=A/e/F"
  27        ) >.gitattributes &&
  28        (
  29                echo "g test=a/g" &&
  30                echo "b/g test=a/b/g"
  31        ) >a/.gitattributes &&
  32        (
  33                echo "h test=a/b/h" &&
  34                echo "d/* test=a/b/d/*"
  35                echo "d/yes notest"
  36        ) >a/b/.gitattributes &&
  37        (
  38                echo "global test=global"
  39        ) >"$HOME"/global-gitattributes &&
  40        cat <<-EOF >expect-all
  41        f: test: f
  42        a/f: test: f
  43        a/c/f: test: f
  44        a/g: test: a/g
  45        a/b/g: test: a/b/g
  46        b/g: test: unspecified
  47        a/b/h: test: a/b/h
  48        a/b/d/g: test: a/b/d/*
  49        onoff: test: unset
  50        offon: test: set
  51        no: notest: set
  52        no: test: unspecified
  53        a/b/d/no: notest: set
  54        a/b/d/no: test: a/b/d/*
  55        a/b/d/yes: notest: set
  56        a/b/d/yes: test: unspecified
  57        EOF
  58'
  59
  60test_expect_success 'command line checks' '
  61        test_must_fail git check-attr &&
  62        test_must_fail git check-attr -- &&
  63        test_must_fail git check-attr test &&
  64        test_must_fail git check-attr test -- &&
  65        test_must_fail git check-attr -- f &&
  66        echo "f" | test_must_fail git check-attr --stdin &&
  67        echo "f" | test_must_fail git check-attr --stdin -- f &&
  68        echo "f" | test_must_fail git check-attr --stdin test -- f &&
  69        test_must_fail git check-attr "" -- f
  70'
  71
  72test_expect_success 'attribute test' '
  73        attr_check f f &&
  74        attr_check a/f f &&
  75        attr_check a/c/f f &&
  76        attr_check a/g a/g &&
  77        attr_check a/b/g a/b/g &&
  78        attr_check b/g unspecified &&
  79        attr_check a/b/h a/b/h &&
  80        attr_check a/b/d/g "a/b/d/*" &&
  81        attr_check onoff unset &&
  82        attr_check offon set &&
  83        attr_check no unspecified &&
  84        attr_check a/b/d/no "a/b/d/*" &&
  85        attr_check a/b/d/yes unspecified
  86'
  87
  88test_expect_success 'attribute matching is case sensitive when core.ignorecase=0' '
  89
  90        test_must_fail attr_check F f "-c core.ignorecase=0" &&
  91        test_must_fail attr_check a/F f "-c core.ignorecase=0" &&
  92        test_must_fail attr_check a/c/F f "-c core.ignorecase=0" &&
  93        test_must_fail attr_check a/G a/g "-c core.ignorecase=0" &&
  94        test_must_fail attr_check a/B/g a/b/g "-c core.ignorecase=0" &&
  95        test_must_fail attr_check a/b/G a/b/g "-c core.ignorecase=0" &&
  96        test_must_fail attr_check a/b/H a/b/h "-c core.ignorecase=0" &&
  97        test_must_fail attr_check a/b/D/g "a/b/d/*" "-c core.ignorecase=0" &&
  98        test_must_fail attr_check oNoFf unset "-c core.ignorecase=0" &&
  99        test_must_fail attr_check oFfOn set "-c core.ignorecase=0" &&
 100        attr_check NO unspecified "-c core.ignorecase=0" &&
 101        test_must_fail attr_check a/b/D/NO "a/b/d/*" "-c core.ignorecase=0" &&
 102        attr_check a/b/d/YES a/b/d/* "-c core.ignorecase=0" &&
 103        test_must_fail attr_check a/E/f "A/e/F" "-c core.ignorecase=0"
 104
 105'
 106
 107test_expect_success 'attribute matching is case insensitive when core.ignorecase=1' '
 108
 109        attr_check F f "-c core.ignorecase=1" &&
 110        attr_check a/F f "-c core.ignorecase=1" &&
 111        attr_check a/c/F f "-c core.ignorecase=1" &&
 112        attr_check a/G a/g "-c core.ignorecase=1" &&
 113        attr_check a/B/g a/b/g "-c core.ignorecase=1" &&
 114        attr_check a/b/G a/b/g "-c core.ignorecase=1" &&
 115        attr_check a/b/H a/b/h "-c core.ignorecase=1" &&
 116        attr_check a/b/D/g "a/b/d/*" "-c core.ignorecase=1" &&
 117        attr_check oNoFf unset "-c core.ignorecase=1" &&
 118        attr_check oFfOn set "-c core.ignorecase=1" &&
 119        attr_check NO unspecified "-c core.ignorecase=1" &&
 120        attr_check a/b/D/NO "a/b/d/*" "-c core.ignorecase=1" &&
 121        attr_check a/b/d/YES unspecified "-c core.ignorecase=1" &&
 122        attr_check a/E/f "A/e/F" "-c core.ignorecase=1"
 123
 124'
 125
 126test_expect_success 'check whether FS is case-insensitive' '
 127        mkdir junk &&
 128        echo good >junk/CamelCase &&
 129        echo bad >junk/camelcase &&
 130        if test "$(cat junk/CamelCase)" != good
 131        then
 132                test_set_prereq CASE_INSENSITIVE_FS
 133        fi
 134'
 135
 136test_expect_success CASE_INSENSITIVE_FS 'additional case insensitivity tests' '
 137        test_must_fail attr_check a/B/D/g "a/b/d/*" "-c core.ignorecase=0" &&
 138        test_must_fail attr_check A/B/D/NO "a/b/d/*" "-c core.ignorecase=0" &&
 139        attr_check A/b/h a/b/h "-c core.ignorecase=1" &&
 140        attr_check a/B/D/g "a/b/d/*" "-c core.ignorecase=1" &&
 141        attr_check A/B/D/NO "a/b/d/*" "-c core.ignorecase=1"
 142'
 143
 144test_expect_success 'unnormalized paths' '
 145        attr_check ./f f &&
 146        attr_check ./a/g a/g &&
 147        attr_check a/./g a/g &&
 148        attr_check a/c/../b/g a/b/g
 149'
 150
 151test_expect_success 'relative paths' '
 152        (cd a && attr_check ../f f) &&
 153        (cd a && attr_check f f) &&
 154        (cd a && attr_check i a/i) &&
 155        (cd a && attr_check g a/g) &&
 156        (cd a && attr_check b/g a/b/g) &&
 157        (cd b && attr_check ../a/f f) &&
 158        (cd b && attr_check ../a/g a/g) &&
 159        (cd b && attr_check ../a/b/g a/b/g)
 160'
 161
 162test_expect_success 'prefixes are not confused with leading directories' '
 163        attr_check a_plus/g unspecified &&
 164        cat >expect <<-\EOF &&
 165        a/g: test: a/g
 166        a_plus/g: test: unspecified
 167        EOF
 168        git check-attr test a/g a_plus/g >actual &&
 169        test_cmp expect actual
 170'
 171
 172test_expect_success 'core.attributesfile' '
 173        attr_check global unspecified &&
 174        git config core.attributesfile "$HOME/global-gitattributes" &&
 175        attr_check global global &&
 176        git config core.attributesfile "~/global-gitattributes" &&
 177        attr_check global global &&
 178        echo "global test=precedence" >>.gitattributes &&
 179        attr_check global precedence
 180'
 181
 182test_expect_success 'attribute test: read paths from stdin' '
 183        grep -v notest <expect-all >expect &&
 184        sed -e "s/:.*//" <expect | git check-attr --stdin test >actual &&
 185        test_cmp expect actual
 186'
 187
 188test_expect_success 'attribute test: --all option' '
 189        grep -v unspecified <expect-all | sort >specified-all &&
 190        sed -e "s/:.*//" <expect-all | uniq >stdin-all &&
 191        git check-attr --stdin --all <stdin-all | sort >actual &&
 192        test_cmp specified-all actual
 193'
 194
 195test_expect_success 'attribute test: --cached option' '
 196        : >empty &&
 197        git check-attr --cached --stdin --all <stdin-all | sort >actual &&
 198        test_cmp empty actual &&
 199        git add .gitattributes a/.gitattributes a/b/.gitattributes &&
 200        git check-attr --cached --stdin --all <stdin-all | sort >actual &&
 201        test_cmp specified-all actual
 202'
 203
 204test_expect_success 'root subdir attribute test' '
 205        attr_check a/i a/i &&
 206        attr_check subdir/a/i unspecified
 207'
 208
 209test_expect_success 'negative patterns' '
 210        echo "!f test=bar" >.gitattributes &&
 211        test_must_fail git check-attr test -- f
 212'
 213
 214test_expect_success 'patterns starting with exclamation' '
 215        echo "\!f test=foo" >.gitattributes &&
 216        attr_check "!f" foo
 217'
 218
 219test_expect_success '"**" test' '
 220        echo "**/f foo=bar" >.gitattributes &&
 221        cat <<\EOF >expect &&
 222f: foo: bar
 223a/f: foo: bar
 224a/b/f: foo: bar
 225a/b/c/f: foo: bar
 226EOF
 227        git check-attr foo -- "f" >actual 2>err &&
 228        git check-attr foo -- "a/f" >>actual 2>>err &&
 229        git check-attr foo -- "a/b/f" >>actual 2>>err &&
 230        git check-attr foo -- "a/b/c/f" >>actual 2>>err &&
 231        test_cmp expect actual &&
 232        test_line_count = 0 err
 233'
 234
 235test_expect_success '"**" with no slashes test' '
 236        echo "a**f foo=bar" >.gitattributes &&
 237        git check-attr foo -- "f" >actual &&
 238        cat <<\EOF >expect &&
 239f: foo: unspecified
 240af: foo: bar
 241axf: foo: bar
 242a/f: foo: unspecified
 243a/b/f: foo: unspecified
 244a/b/c/f: foo: unspecified
 245EOF
 246        git check-attr foo -- "f" >actual 2>err &&
 247        git check-attr foo -- "af" >>actual 2>err &&
 248        git check-attr foo -- "axf" >>actual 2>err &&
 249        git check-attr foo -- "a/f" >>actual 2>>err &&
 250        git check-attr foo -- "a/b/f" >>actual 2>>err &&
 251        git check-attr foo -- "a/b/c/f" >>actual 2>>err &&
 252        test_cmp expect actual &&
 253        test_line_count = 0 err
 254'
 255
 256test_expect_success 'setup bare' '
 257        git clone --bare . bare.git &&
 258        cd bare.git
 259'
 260
 261test_expect_success 'bare repository: check that .gitattribute is ignored' '
 262        (
 263                echo "f test=f"
 264                echo "a/i test=a/i"
 265        ) >.gitattributes &&
 266        attr_check f unspecified &&
 267        attr_check a/f unspecified &&
 268        attr_check a/c/f unspecified &&
 269        attr_check a/i unspecified &&
 270        attr_check subdir/a/i unspecified
 271'
 272
 273test_expect_success 'bare repository: check that --cached honors index' '
 274        GIT_INDEX_FILE=../.git/index \
 275        git check-attr --cached --stdin --all <../stdin-all |
 276        sort >actual &&
 277        test_cmp ../specified-all actual
 278'
 279
 280test_expect_success 'bare repository: test info/attributes' '
 281        (
 282                echo "f test=f"
 283                echo "a/i test=a/i"
 284        ) >info/attributes &&
 285        attr_check f f &&
 286        attr_check a/f f &&
 287        attr_check a/c/f f &&
 288        attr_check a/i a/i &&
 289        attr_check subdir/a/i unspecified
 290'
 291
 292test_done