t / t0003-attributes.shon commit Merge branch 'mm/add-u-A-sans-pathspec' (27d46a7)
   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 CASE_INSENSITIVE_FS 'additional case insensitivity tests' '
 127        test_must_fail attr_check a/B/D/g "a/b/d/*" "-c core.ignorecase=0" &&
 128        test_must_fail attr_check A/B/D/NO "a/b/d/*" "-c core.ignorecase=0" &&
 129        attr_check A/b/h a/b/h "-c core.ignorecase=1" &&
 130        attr_check a/B/D/g "a/b/d/*" "-c core.ignorecase=1" &&
 131        attr_check A/B/D/NO "a/b/d/*" "-c core.ignorecase=1"
 132'
 133
 134test_expect_success 'unnormalized paths' '
 135        attr_check ./f f &&
 136        attr_check ./a/g a/g &&
 137        attr_check a/./g a/g &&
 138        attr_check a/c/../b/g a/b/g
 139'
 140
 141test_expect_success 'relative paths' '
 142        (cd a && attr_check ../f f) &&
 143        (cd a && attr_check f f) &&
 144        (cd a && attr_check i a/i) &&
 145        (cd a && attr_check g a/g) &&
 146        (cd a && attr_check b/g a/b/g) &&
 147        (cd b && attr_check ../a/f f) &&
 148        (cd b && attr_check ../a/g a/g) &&
 149        (cd b && attr_check ../a/b/g a/b/g)
 150'
 151
 152test_expect_success 'prefixes are not confused with leading directories' '
 153        attr_check a_plus/g unspecified &&
 154        cat >expect <<-\EOF &&
 155        a/g: test: a/g
 156        a_plus/g: test: unspecified
 157        EOF
 158        git check-attr test a/g a_plus/g >actual &&
 159        test_cmp expect actual
 160'
 161
 162test_expect_success 'core.attributesfile' '
 163        attr_check global unspecified &&
 164        git config core.attributesfile "$HOME/global-gitattributes" &&
 165        attr_check global global &&
 166        git config core.attributesfile "~/global-gitattributes" &&
 167        attr_check global global &&
 168        echo "global test=precedence" >>.gitattributes &&
 169        attr_check global precedence
 170'
 171
 172test_expect_success 'attribute test: read paths from stdin' '
 173        grep -v notest <expect-all >expect &&
 174        sed -e "s/:.*//" <expect | git check-attr --stdin test >actual &&
 175        test_cmp expect actual
 176'
 177
 178test_expect_success 'attribute test: --all option' '
 179        grep -v unspecified <expect-all | sort >specified-all &&
 180        sed -e "s/:.*//" <expect-all | uniq >stdin-all &&
 181        git check-attr --stdin --all <stdin-all | sort >actual &&
 182        test_cmp specified-all actual
 183'
 184
 185test_expect_success 'attribute test: --cached option' '
 186        : >empty &&
 187        git check-attr --cached --stdin --all <stdin-all | sort >actual &&
 188        test_cmp empty actual &&
 189        git add .gitattributes a/.gitattributes a/b/.gitattributes &&
 190        git check-attr --cached --stdin --all <stdin-all | sort >actual &&
 191        test_cmp specified-all actual
 192'
 193
 194test_expect_success 'root subdir attribute test' '
 195        attr_check a/i a/i &&
 196        attr_check subdir/a/i unspecified
 197'
 198
 199test_expect_success 'negative patterns' '
 200        echo "!f test=bar" >.gitattributes &&
 201        test_must_fail git check-attr test -- f
 202'
 203
 204test_expect_success 'patterns starting with exclamation' '
 205        echo "\!f test=foo" >.gitattributes &&
 206        attr_check "!f" foo
 207'
 208
 209test_expect_success '"**" test' '
 210        echo "**/f foo=bar" >.gitattributes &&
 211        cat <<\EOF >expect &&
 212f: foo: bar
 213a/f: foo: bar
 214a/b/f: foo: bar
 215a/b/c/f: foo: bar
 216EOF
 217        git check-attr foo -- "f" >actual 2>err &&
 218        git check-attr foo -- "a/f" >>actual 2>>err &&
 219        git check-attr foo -- "a/b/f" >>actual 2>>err &&
 220        git check-attr foo -- "a/b/c/f" >>actual 2>>err &&
 221        test_cmp expect actual &&
 222        test_line_count = 0 err
 223'
 224
 225test_expect_success '"**" with no slashes test' '
 226        echo "a**f foo=bar" >.gitattributes &&
 227        git check-attr foo -- "f" >actual &&
 228        cat <<\EOF >expect &&
 229f: foo: unspecified
 230af: foo: bar
 231axf: foo: bar
 232a/f: foo: unspecified
 233a/b/f: foo: unspecified
 234a/b/c/f: foo: unspecified
 235EOF
 236        git check-attr foo -- "f" >actual 2>err &&
 237        git check-attr foo -- "af" >>actual 2>err &&
 238        git check-attr foo -- "axf" >>actual 2>err &&
 239        git check-attr foo -- "a/f" >>actual 2>>err &&
 240        git check-attr foo -- "a/b/f" >>actual 2>>err &&
 241        git check-attr foo -- "a/b/c/f" >>actual 2>>err &&
 242        test_cmp expect actual &&
 243        test_line_count = 0 err
 244'
 245
 246test_expect_success 'setup bare' '
 247        git clone --bare . bare.git &&
 248        cd bare.git
 249'
 250
 251test_expect_success 'bare repository: check that .gitattribute is ignored' '
 252        (
 253                echo "f test=f"
 254                echo "a/i test=a/i"
 255        ) >.gitattributes &&
 256        attr_check f unspecified &&
 257        attr_check a/f unspecified &&
 258        attr_check a/c/f unspecified &&
 259        attr_check a/i unspecified &&
 260        attr_check subdir/a/i unspecified
 261'
 262
 263test_expect_success 'bare repository: check that --cached honors index' '
 264        GIT_INDEX_FILE=../.git/index \
 265        git check-attr --cached --stdin --all <../stdin-all |
 266        sort >actual &&
 267        test_cmp ../specified-all actual
 268'
 269
 270test_expect_success 'bare repository: test info/attributes' '
 271        (
 272                echo "f test=f"
 273                echo "a/i test=a/i"
 274        ) >info/attributes &&
 275        attr_check f f &&
 276        attr_check a/f f &&
 277        attr_check a/c/f f &&
 278        attr_check a/i a/i &&
 279        attr_check subdir/a/i unspecified
 280'
 281
 282test_done