t / t0003-attributes.shon commit t0027: do not use an empty string as a pathspec element (229a95a)
   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
  16test_expect_success 'setup' '
  17        mkdir -p a/b/d a/c b &&
  18        (
  19                echo "[attr]notest !test"
  20                echo "f test=f"
  21                echo "a/i test=a/i"
  22                echo "onoff test -test"
  23                echo "offon -test test"
  24                echo "no notest"
  25                echo "A/e/F test=A/e/F"
  26        ) >.gitattributes &&
  27        (
  28                echo "g test=a/g" &&
  29                echo "b/g test=a/b/g"
  30        ) >a/.gitattributes &&
  31        (
  32                echo "h test=a/b/h" &&
  33                echo "d/* test=a/b/d/*"
  34                echo "d/yes notest"
  35        ) >a/b/.gitattributes &&
  36        (
  37                echo "global test=global"
  38        ) >"$HOME"/global-gitattributes &&
  39        cat <<-EOF >expect-all
  40        f: test: f
  41        a/f: test: f
  42        a/c/f: test: f
  43        a/g: test: a/g
  44        a/b/g: test: a/b/g
  45        b/g: test: unspecified
  46        a/b/h: test: a/b/h
  47        a/b/d/g: test: a/b/d/*
  48        onoff: test: unset
  49        offon: test: set
  50        no: notest: set
  51        no: test: unspecified
  52        a/b/d/no: notest: set
  53        a/b/d/no: test: a/b/d/*
  54        a/b/d/yes: notest: set
  55        a/b/d/yes: test: unspecified
  56        EOF
  57'
  58
  59test_expect_success 'command line checks' '
  60        test_must_fail git check-attr &&
  61        test_must_fail git check-attr -- &&
  62        test_must_fail git check-attr test &&
  63        test_must_fail git check-attr test -- &&
  64        test_must_fail git check-attr -- f &&
  65        echo "f" | test_must_fail git check-attr --stdin &&
  66        echo "f" | test_must_fail git check-attr --stdin -- f &&
  67        echo "f" | test_must_fail git check-attr --stdin test -- f &&
  68        test_must_fail git check-attr "" -- f
  69'
  70
  71test_expect_success 'attribute test' '
  72        attr_check f f &&
  73        attr_check a/f f &&
  74        attr_check a/c/f f &&
  75        attr_check a/g a/g &&
  76        attr_check a/b/g a/b/g &&
  77        attr_check b/g unspecified &&
  78        attr_check a/b/h a/b/h &&
  79        attr_check a/b/d/g "a/b/d/*" &&
  80        attr_check onoff unset &&
  81        attr_check offon set &&
  82        attr_check no unspecified &&
  83        attr_check a/b/d/no "a/b/d/*" &&
  84        attr_check a/b/d/yes unspecified
  85'
  86
  87test_expect_success 'attribute matching is case sensitive when core.ignorecase=0' '
  88
  89        test_must_fail attr_check F f "-c core.ignorecase=0" &&
  90        test_must_fail attr_check a/F f "-c core.ignorecase=0" &&
  91        test_must_fail attr_check a/c/F f "-c core.ignorecase=0" &&
  92        test_must_fail attr_check a/G a/g "-c core.ignorecase=0" &&
  93        test_must_fail attr_check a/B/g a/b/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/H a/b/h "-c core.ignorecase=0" &&
  96        test_must_fail attr_check a/b/D/g "a/b/d/*" "-c core.ignorecase=0" &&
  97        test_must_fail attr_check oNoFf unset "-c core.ignorecase=0" &&
  98        test_must_fail attr_check oFfOn set "-c core.ignorecase=0" &&
  99        attr_check NO unspecified "-c core.ignorecase=0" &&
 100        test_must_fail attr_check a/b/D/NO "a/b/d/*" "-c core.ignorecase=0" &&
 101        attr_check a/b/d/YES a/b/d/* "-c core.ignorecase=0" &&
 102        test_must_fail attr_check a/E/f "A/e/F" "-c core.ignorecase=0"
 103
 104'
 105
 106test_expect_success 'attribute matching is case insensitive when core.ignorecase=1' '
 107
 108        attr_check F f "-c core.ignorecase=1" &&
 109        attr_check a/F f "-c core.ignorecase=1" &&
 110        attr_check a/c/F f "-c core.ignorecase=1" &&
 111        attr_check a/G a/g "-c core.ignorecase=1" &&
 112        attr_check a/B/g a/b/g "-c core.ignorecase=1" &&
 113        attr_check a/b/G a/b/g "-c core.ignorecase=1" &&
 114        attr_check a/b/H a/b/h "-c core.ignorecase=1" &&
 115        attr_check a/b/D/g "a/b/d/*" "-c core.ignorecase=1" &&
 116        attr_check oNoFf unset "-c core.ignorecase=1" &&
 117        attr_check oFfOn set "-c core.ignorecase=1" &&
 118        attr_check NO unspecified "-c core.ignorecase=1" &&
 119        attr_check a/b/D/NO "a/b/d/*" "-c core.ignorecase=1" &&
 120        attr_check a/b/d/YES unspecified "-c core.ignorecase=1" &&
 121        attr_check a/E/f "A/e/F" "-c core.ignorecase=1"
 122
 123'
 124
 125test_expect_success CASE_INSENSITIVE_FS 'additional case insensitivity tests' '
 126        test_must_fail attr_check a/B/D/g "a/b/d/*" "-c core.ignorecase=0" &&
 127        test_must_fail attr_check A/B/D/NO "a/b/d/*" "-c core.ignorecase=0" &&
 128        attr_check A/b/h a/b/h "-c core.ignorecase=1" &&
 129        attr_check a/B/D/g "a/b/d/*" "-c core.ignorecase=1" &&
 130        attr_check A/B/D/NO "a/b/d/*" "-c core.ignorecase=1"
 131'
 132
 133test_expect_success 'unnormalized paths' '
 134        attr_check ./f f &&
 135        attr_check ./a/g a/g &&
 136        attr_check a/./g a/g &&
 137        attr_check a/c/../b/g a/b/g
 138'
 139
 140test_expect_success 'relative paths' '
 141        (cd a && attr_check ../f f) &&
 142        (cd a && attr_check f f) &&
 143        (cd a && attr_check i a/i) &&
 144        (cd a && attr_check g a/g) &&
 145        (cd a && attr_check b/g a/b/g) &&
 146        (cd b && attr_check ../a/f f) &&
 147        (cd b && attr_check ../a/g a/g) &&
 148        (cd b && attr_check ../a/b/g a/b/g)
 149'
 150
 151test_expect_success 'prefixes are not confused with leading directories' '
 152        attr_check a_plus/g unspecified &&
 153        cat >expect <<-\EOF &&
 154        a/g: test: a/g
 155        a_plus/g: test: unspecified
 156        EOF
 157        git check-attr test a/g a_plus/g >actual &&
 158        test_cmp expect actual
 159'
 160
 161test_expect_success 'core.attributesfile' '
 162        attr_check global unspecified &&
 163        git config core.attributesfile "$HOME/global-gitattributes" &&
 164        attr_check global global &&
 165        git config core.attributesfile "~/global-gitattributes" &&
 166        attr_check global global &&
 167        echo "global test=precedence" >>.gitattributes &&
 168        attr_check global precedence
 169'
 170
 171test_expect_success 'attribute test: read paths from stdin' '
 172        grep -v notest <expect-all >expect &&
 173        sed -e "s/:.*//" <expect | git check-attr --stdin test >actual &&
 174        test_cmp expect actual
 175'
 176
 177test_expect_success 'attribute test: --all option' '
 178        grep -v unspecified <expect-all | sort >specified-all &&
 179        sed -e "s/:.*//" <expect-all | uniq >stdin-all &&
 180        git check-attr --stdin --all <stdin-all | sort >actual &&
 181        test_cmp specified-all actual
 182'
 183
 184test_expect_success 'attribute test: --cached option' '
 185        : >empty &&
 186        git check-attr --cached --stdin --all <stdin-all | sort >actual &&
 187        test_cmp empty actual &&
 188        git add .gitattributes a/.gitattributes a/b/.gitattributes &&
 189        git check-attr --cached --stdin --all <stdin-all | sort >actual &&
 190        test_cmp specified-all actual
 191'
 192
 193test_expect_success 'root subdir attribute test' '
 194        attr_check a/i a/i &&
 195        attr_check subdir/a/i unspecified
 196'
 197
 198test_expect_success 'negative patterns' '
 199        echo "!f test=bar" >.gitattributes &&
 200        git check-attr test -- '"'"'!f'"'"' 2>errors &&
 201        test_i18ngrep "Negative patterns are ignored" errors
 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 'using --git-dir and --work-tree' '
 247        mkdir unreal real &&
 248        git init real &&
 249        echo "file test=in-real" >real/.gitattributes &&
 250        (
 251                cd unreal &&
 252                attr_check file in-real "--git-dir ../real/.git --work-tree ../real"
 253        )
 254'
 255
 256test_expect_success 'setup bare' '
 257        git clone --bare . bare.git
 258'
 259
 260test_expect_success 'bare repository: check that .gitattribute is ignored' '
 261        (
 262                cd bare.git &&
 263                (
 264                        echo "f test=f"
 265                        echo "a/i test=a/i"
 266                ) >.gitattributes &&
 267                attr_check f unspecified &&
 268                attr_check a/f unspecified &&
 269                attr_check a/c/f unspecified &&
 270                attr_check a/i unspecified &&
 271                attr_check subdir/a/i unspecified
 272        )
 273'
 274
 275test_expect_success 'bare repository: check that --cached honors index' '
 276        (
 277                cd bare.git &&
 278                GIT_INDEX_FILE=../.git/index \
 279                git check-attr --cached --stdin --all <../stdin-all |
 280                sort >actual &&
 281                test_cmp ../specified-all actual
 282        )
 283'
 284
 285test_expect_success 'bare repository: test info/attributes' '
 286        (
 287                cd bare.git &&
 288                (
 289                        echo "f test=f"
 290                        echo "a/i test=a/i"
 291                ) >info/attributes &&
 292                attr_check f f &&
 293                attr_check a/f f &&
 294                attr_check a/c/f f &&
 295                attr_check a/i a/i &&
 296                attr_check subdir/a/i unspecified
 297        )
 298'
 299
 300test_done