t / t7814-grep-recurse-submodules.shon commit Merge branch 'mh/release-commit-memory-fix' (21ce0b4)
   1#!/bin/sh
   2
   3test_description='Test grep recurse-submodules feature
   4
   5This test verifies the recurse-submodules feature correctly greps across
   6submodules.
   7'
   8
   9. ./test-lib.sh
  10
  11test_expect_success 'setup directory structure and submodule' '
  12        echo "(1|2)d(3|4)" >a &&
  13        mkdir b &&
  14        echo "(3|4)" >b/b &&
  15        git add a b &&
  16        git commit -m "add a and b" &&
  17        test_tick &&
  18        git init submodule &&
  19        echo "(1|2)d(3|4)" >submodule/a &&
  20        git -C submodule add a &&
  21        git -C submodule commit -m "add a" &&
  22        git submodule add ./submodule &&
  23        git commit -m "added submodule" &&
  24        test_tick
  25'
  26
  27test_expect_success 'grep correctly finds patterns in a submodule' '
  28        cat >expect <<-\EOF &&
  29        a:(1|2)d(3|4)
  30        b/b:(3|4)
  31        submodule/a:(1|2)d(3|4)
  32        EOF
  33
  34        git grep -e "(3|4)" --recurse-submodules >actual &&
  35        test_cmp expect actual
  36'
  37
  38test_expect_success 'grep finds patterns in a submodule via config' '
  39        test_config submodule.recurse true &&
  40        # expect from previous test
  41        git grep -e "(3|4)" >actual &&
  42        test_cmp expect actual
  43'
  44
  45test_expect_success 'grep --no-recurse-submodules overrides config' '
  46        test_config submodule.recurse true &&
  47        cat >expect <<-\EOF &&
  48        a:(1|2)d(3|4)
  49        b/b:(3|4)
  50        EOF
  51
  52        git grep -e "(3|4)" --no-recurse-submodules >actual &&
  53        test_cmp expect actual
  54'
  55
  56test_expect_success 'grep and basic pathspecs' '
  57        cat >expect <<-\EOF &&
  58        submodule/a:(1|2)d(3|4)
  59        EOF
  60
  61        git grep -e. --recurse-submodules -- submodule >actual &&
  62        test_cmp expect actual
  63'
  64
  65test_expect_success 'grep and nested submodules' '
  66        git init submodule/sub &&
  67        echo "(1|2)d(3|4)" >submodule/sub/a &&
  68        git -C submodule/sub add a &&
  69        git -C submodule/sub commit -m "add a" &&
  70        test_tick &&
  71        git -C submodule submodule add ./sub &&
  72        git -C submodule add sub &&
  73        git -C submodule commit -m "added sub" &&
  74        test_tick &&
  75        git add submodule &&
  76        git commit -m "updated submodule" &&
  77        test_tick &&
  78
  79        cat >expect <<-\EOF &&
  80        a:(1|2)d(3|4)
  81        b/b:(3|4)
  82        submodule/a:(1|2)d(3|4)
  83        submodule/sub/a:(1|2)d(3|4)
  84        EOF
  85
  86        git grep -e "(3|4)" --recurse-submodules >actual &&
  87        test_cmp expect actual
  88'
  89
  90test_expect_success 'grep and multiple patterns' '
  91        cat >expect <<-\EOF &&
  92        a:(1|2)d(3|4)
  93        submodule/a:(1|2)d(3|4)
  94        submodule/sub/a:(1|2)d(3|4)
  95        EOF
  96
  97        git grep -e "(3|4)" --and -e "(1|2)" --recurse-submodules >actual &&
  98        test_cmp expect actual
  99'
 100
 101test_expect_success 'grep and multiple patterns' '
 102        cat >expect <<-\EOF &&
 103        b/b:(3|4)
 104        EOF
 105
 106        git grep -e "(3|4)" --and --not -e "(1|2)" --recurse-submodules >actual &&
 107        test_cmp expect actual
 108'
 109
 110test_expect_success 'basic grep tree' '
 111        cat >expect <<-\EOF &&
 112        HEAD:a:(1|2)d(3|4)
 113        HEAD:b/b:(3|4)
 114        HEAD:submodule/a:(1|2)d(3|4)
 115        HEAD:submodule/sub/a:(1|2)d(3|4)
 116        EOF
 117
 118        git grep -e "(3|4)" --recurse-submodules HEAD >actual &&
 119        test_cmp expect actual
 120'
 121
 122test_expect_success 'grep tree HEAD^' '
 123        cat >expect <<-\EOF &&
 124        HEAD^:a:(1|2)d(3|4)
 125        HEAD^:b/b:(3|4)
 126        HEAD^:submodule/a:(1|2)d(3|4)
 127        EOF
 128
 129        git grep -e "(3|4)" --recurse-submodules HEAD^ >actual &&
 130        test_cmp expect actual
 131'
 132
 133test_expect_success 'grep tree HEAD^^' '
 134        cat >expect <<-\EOF &&
 135        HEAD^^:a:(1|2)d(3|4)
 136        HEAD^^:b/b:(3|4)
 137        EOF
 138
 139        git grep -e "(3|4)" --recurse-submodules HEAD^^ >actual &&
 140        test_cmp expect actual
 141'
 142
 143test_expect_success 'grep tree and pathspecs' '
 144        cat >expect <<-\EOF &&
 145        HEAD:submodule/a:(1|2)d(3|4)
 146        HEAD:submodule/sub/a:(1|2)d(3|4)
 147        EOF
 148
 149        git grep -e "(3|4)" --recurse-submodules HEAD -- submodule >actual &&
 150        test_cmp expect actual
 151'
 152
 153test_expect_success 'grep tree and pathspecs' '
 154        cat >expect <<-\EOF &&
 155        HEAD:submodule/a:(1|2)d(3|4)
 156        HEAD:submodule/sub/a:(1|2)d(3|4)
 157        EOF
 158
 159        git grep -e "(3|4)" --recurse-submodules HEAD -- "submodule*a" >actual &&
 160        test_cmp expect actual
 161'
 162
 163test_expect_success 'grep tree and more pathspecs' '
 164        cat >expect <<-\EOF &&
 165        HEAD:submodule/a:(1|2)d(3|4)
 166        EOF
 167
 168        git grep -e "(3|4)" --recurse-submodules HEAD -- "submodul?/a" >actual &&
 169        test_cmp expect actual
 170'
 171
 172test_expect_success 'grep tree and more pathspecs' '
 173        cat >expect <<-\EOF &&
 174        HEAD:submodule/sub/a:(1|2)d(3|4)
 175        EOF
 176
 177        git grep -e "(3|4)" --recurse-submodules HEAD -- "submodul*/sub/a" >actual &&
 178        test_cmp expect actual
 179'
 180
 181test_expect_success !MINGW 'grep recurse submodule colon in name' '
 182        git init parent &&
 183        test_when_finished "rm -rf parent" &&
 184        echo "(1|2)d(3|4)" >"parent/fi:le" &&
 185        git -C parent add "fi:le" &&
 186        git -C parent commit -m "add fi:le" &&
 187        test_tick &&
 188
 189        git init "su:b" &&
 190        test_when_finished "rm -rf su:b" &&
 191        echo "(1|2)d(3|4)" >"su:b/fi:le" &&
 192        git -C "su:b" add "fi:le" &&
 193        git -C "su:b" commit -m "add fi:le" &&
 194        test_tick &&
 195
 196        git -C parent submodule add "../su:b" "su:b" &&
 197        git -C parent commit -m "add submodule" &&
 198        test_tick &&
 199
 200        cat >expect <<-\EOF &&
 201        fi:le:(1|2)d(3|4)
 202        su:b/fi:le:(1|2)d(3|4)
 203        EOF
 204        git -C parent grep -e "(1|2)d(3|4)" --recurse-submodules >actual &&
 205        test_cmp expect actual &&
 206
 207        cat >expect <<-\EOF &&
 208        HEAD:fi:le:(1|2)d(3|4)
 209        HEAD:su:b/fi:le:(1|2)d(3|4)
 210        EOF
 211        git -C parent grep -e "(1|2)d(3|4)" --recurse-submodules HEAD >actual &&
 212        test_cmp expect actual
 213'
 214
 215test_expect_success 'grep history with moved submoules' '
 216        git init parent &&
 217        test_when_finished "rm -rf parent" &&
 218        echo "(1|2)d(3|4)" >parent/file &&
 219        git -C parent add file &&
 220        git -C parent commit -m "add file" &&
 221        test_tick &&
 222
 223        git init sub &&
 224        test_when_finished "rm -rf sub" &&
 225        echo "(1|2)d(3|4)" >sub/file &&
 226        git -C sub add file &&
 227        git -C sub commit -m "add file" &&
 228        test_tick &&
 229
 230        git -C parent submodule add ../sub dir/sub &&
 231        git -C parent commit -m "add submodule" &&
 232        test_tick &&
 233
 234        cat >expect <<-\EOF &&
 235        dir/sub/file:(1|2)d(3|4)
 236        file:(1|2)d(3|4)
 237        EOF
 238        git -C parent grep -e "(1|2)d(3|4)" --recurse-submodules >actual &&
 239        test_cmp expect actual &&
 240
 241        git -C parent mv dir/sub sub-moved &&
 242        git -C parent commit -m "moved submodule" &&
 243        test_tick &&
 244
 245        cat >expect <<-\EOF &&
 246        file:(1|2)d(3|4)
 247        sub-moved/file:(1|2)d(3|4)
 248        EOF
 249        git -C parent grep -e "(1|2)d(3|4)" --recurse-submodules >actual &&
 250        test_cmp expect actual &&
 251
 252        cat >expect <<-\EOF &&
 253        HEAD^:dir/sub/file:(1|2)d(3|4)
 254        HEAD^:file:(1|2)d(3|4)
 255        EOF
 256        git -C parent grep -e "(1|2)d(3|4)" --recurse-submodules HEAD^ >actual &&
 257        test_cmp expect actual
 258'
 259
 260test_expect_success 'grep using relative path' '
 261        test_when_finished "rm -rf parent sub" &&
 262        git init sub &&
 263        echo "(1|2)d(3|4)" >sub/file &&
 264        git -C sub add file &&
 265        git -C sub commit -m "add file" &&
 266        test_tick &&
 267
 268        git init parent &&
 269        echo "(1|2)d(3|4)" >parent/file &&
 270        git -C parent add file &&
 271        mkdir parent/src &&
 272        echo "(1|2)d(3|4)" >parent/src/file2 &&
 273        git -C parent add src/file2 &&
 274        git -C parent submodule add ../sub &&
 275        git -C parent commit -m "add files and submodule" &&
 276        test_tick &&
 277
 278        # From top works
 279        cat >expect <<-\EOF &&
 280        file:(1|2)d(3|4)
 281        src/file2:(1|2)d(3|4)
 282        sub/file:(1|2)d(3|4)
 283        EOF
 284        git -C parent grep --recurse-submodules -e "(1|2)d(3|4)" >actual &&
 285        test_cmp expect actual &&
 286
 287        # Relative path to top
 288        cat >expect <<-\EOF &&
 289        ../file:(1|2)d(3|4)
 290        file2:(1|2)d(3|4)
 291        ../sub/file:(1|2)d(3|4)
 292        EOF
 293        git -C parent/src grep --recurse-submodules -e "(1|2)d(3|4)" -- .. >actual &&
 294        test_cmp expect actual &&
 295
 296        # Relative path to submodule
 297        cat >expect <<-\EOF &&
 298        ../sub/file:(1|2)d(3|4)
 299        EOF
 300        git -C parent/src grep --recurse-submodules -e "(1|2)d(3|4)" -- ../sub >actual &&
 301        test_cmp expect actual
 302'
 303
 304test_expect_success 'grep from a subdir' '
 305        test_when_finished "rm -rf parent sub" &&
 306        git init sub &&
 307        echo "(1|2)d(3|4)" >sub/file &&
 308        git -C sub add file &&
 309        git -C sub commit -m "add file" &&
 310        test_tick &&
 311
 312        git init parent &&
 313        mkdir parent/src &&
 314        echo "(1|2)d(3|4)" >parent/src/file &&
 315        git -C parent add src/file &&
 316        git -C parent submodule add ../sub src/sub &&
 317        git -C parent submodule add ../sub sub &&
 318        git -C parent commit -m "add files and submodules" &&
 319        test_tick &&
 320
 321        # Verify grep from root works
 322        cat >expect <<-\EOF &&
 323        src/file:(1|2)d(3|4)
 324        src/sub/file:(1|2)d(3|4)
 325        sub/file:(1|2)d(3|4)
 326        EOF
 327        git -C parent grep --recurse-submodules -e "(1|2)d(3|4)" >actual &&
 328        test_cmp expect actual &&
 329
 330        # Verify grep from a subdir works
 331        cat >expect <<-\EOF &&
 332        file:(1|2)d(3|4)
 333        sub/file:(1|2)d(3|4)
 334        EOF
 335        git -C parent/src grep --recurse-submodules -e "(1|2)d(3|4)" >actual &&
 336        test_cmp expect actual
 337'
 338
 339test_incompatible_with_recurse_submodules ()
 340{
 341        test_expect_success "--recurse-submodules and $1 are incompatible" "
 342                test_must_fail git grep -e. --recurse-submodules $1 2>actual &&
 343                test_i18ngrep 'not supported with --recurse-submodules' actual
 344        "
 345}
 346
 347test_incompatible_with_recurse_submodules --untracked
 348test_incompatible_with_recurse_submodules --no-index
 349
 350test_expect_success 'grep --recurse-submodules should pass the pattern type along' '
 351        # Fixed
 352        test_must_fail git grep -F --recurse-submodules -e "(.|.)[\d]" &&
 353        test_must_fail git -c grep.patternType=fixed grep --recurse-submodules -e "(.|.)[\d]" &&
 354
 355        # Basic
 356        git grep -G --recurse-submodules -e "(.|.)[\d]" >actual &&
 357        cat >expect <<-\EOF &&
 358        a:(1|2)d(3|4)
 359        submodule/a:(1|2)d(3|4)
 360        submodule/sub/a:(1|2)d(3|4)
 361        EOF
 362        test_cmp expect actual &&
 363        git -c grep.patternType=basic grep --recurse-submodules -e "(.|.)[\d]" >actual &&
 364        test_cmp expect actual &&
 365
 366        # Extended
 367        git grep -E --recurse-submodules -e "(.|.)[\d]" >actual &&
 368        cat >expect <<-\EOF &&
 369        .gitmodules:[submodule "submodule"]
 370        .gitmodules:    path = submodule
 371        .gitmodules:    url = ./submodule
 372        a:(1|2)d(3|4)
 373        submodule/.gitmodules:[submodule "sub"]
 374        submodule/a:(1|2)d(3|4)
 375        submodule/sub/a:(1|2)d(3|4)
 376        EOF
 377        test_cmp expect actual &&
 378        git -c grep.patternType=extended grep --recurse-submodules -e "(.|.)[\d]" >actual &&
 379        test_cmp expect actual &&
 380        git -c grep.extendedRegexp=true grep --recurse-submodules -e "(.|.)[\d]" >actual &&
 381        test_cmp expect actual &&
 382
 383        # Perl
 384        if test_have_prereq PCRE
 385        then
 386                git grep -P --recurse-submodules -e "(.|.)[\d]" >actual &&
 387                cat >expect <<-\EOF &&
 388                a:(1|2)d(3|4)
 389                b/b:(3|4)
 390                submodule/a:(1|2)d(3|4)
 391                submodule/sub/a:(1|2)d(3|4)
 392                EOF
 393                test_cmp expect actual &&
 394                git -c grep.patternType=perl grep --recurse-submodules -e "(.|.)[\d]" >actual &&
 395                test_cmp expect actual
 396        fi
 397'
 398
 399test_expect_success 'grep --recurse-submodules with submodules without .gitmodules in the working tree' '
 400        test_when_finished "git -C submodule checkout .gitmodules" &&
 401        rm submodule/.gitmodules &&
 402        git grep --recurse-submodules -e "(.|.)[\d]" >actual &&
 403        cat >expect <<-\EOF &&
 404        a:(1|2)d(3|4)
 405        submodule/a:(1|2)d(3|4)
 406        submodule/sub/a:(1|2)d(3|4)
 407        EOF
 408        test_cmp expect actual
 409'
 410
 411reset_and_clean () {
 412        git reset --hard &&
 413        git clean -fd &&
 414        git submodule foreach --recursive 'git reset --hard' &&
 415        git submodule foreach --recursive 'git clean -fd'
 416}
 417
 418test_expect_success 'grep --recurse-submodules without --cached considers worktree modifications' '
 419        reset_and_clean &&
 420        echo "A modified line in submodule" >>submodule/a &&
 421        echo "submodule/a:A modified line in submodule" >expect &&
 422        git grep --recurse-submodules "A modified line in submodule" >actual &&
 423        test_cmp expect actual
 424'
 425
 426test_expect_success 'grep --recurse-submodules with --cached ignores worktree modifications' '
 427        reset_and_clean &&
 428        echo "A modified line in submodule" >>submodule/a &&
 429        test_must_fail git grep --recurse-submodules --cached "A modified line in submodule" >actual 2>&1 &&
 430        test_must_be_empty actual
 431'
 432test_done