3 test_description='Test grep recurse-submodules feature
5 This test verifies the recurse-submodules feature correctly greps across
11 test_expect_success 'setup directory structure and submodule' '
12 echo "(1|2)d(3|4)" >a &&
16 git commit -m "add a and b" &&
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" &&
27 test_expect_success 'grep correctly finds patterns in a submodule' '
28 cat >expect <<-\EOF &&
31 submodule/a:(1|2)d(3|4)
34 git grep -e "(3|4)" --recurse-submodules >actual &&
35 test_cmp expect actual
38 test_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
45 test_expect_success 'grep --no-recurse-submodules overrides config' '
46 test_config submodule.recurse true &&
47 cat >expect <<-\EOF &&
52 git grep -e "(3|4)" --no-recurse-submodules >actual &&
53 test_cmp expect actual
56 test_expect_success 'grep and basic pathspecs' '
57 cat >expect <<-\EOF &&
58 submodule/a:(1|2)d(3|4)
61 git grep -e. --recurse-submodules -- submodule >actual &&
62 test_cmp expect actual
65 test_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" &&
71 git -C submodule submodule add ./sub &&
72 git -C submodule add sub &&
73 git -C submodule commit -m "added sub" &&
76 git commit -m "updated submodule" &&
79 cat >expect <<-\EOF &&
82 submodule/a:(1|2)d(3|4)
83 submodule/sub/a:(1|2)d(3|4)
86 git grep -e "(3|4)" --recurse-submodules >actual &&
87 test_cmp expect actual
90 test_expect_success 'grep and multiple patterns' '
91 cat >expect <<-\EOF &&
93 submodule/a:(1|2)d(3|4)
94 submodule/sub/a:(1|2)d(3|4)
97 git grep -e "(3|4)" --and -e "(1|2)" --recurse-submodules >actual &&
98 test_cmp expect actual
101 test_expect_success 'grep and multiple patterns' '
102 cat >expect <<-\EOF &&
106 git grep -e "(3|4)" --and --not -e "(1|2)" --recurse-submodules >actual &&
107 test_cmp expect actual
110 test_expect_success 'basic grep tree' '
111 cat >expect <<-\EOF &&
114 HEAD:submodule/a:(1|2)d(3|4)
115 HEAD:submodule/sub/a:(1|2)d(3|4)
118 git grep -e "(3|4)" --recurse-submodules HEAD >actual &&
119 test_cmp expect actual
122 test_expect_success 'grep tree HEAD^' '
123 cat >expect <<-\EOF &&
126 HEAD^:submodule/a:(1|2)d(3|4)
129 git grep -e "(3|4)" --recurse-submodules HEAD^ >actual &&
130 test_cmp expect actual
133 test_expect_success 'grep tree HEAD^^' '
134 cat >expect <<-\EOF &&
139 git grep -e "(3|4)" --recurse-submodules HEAD^^ >actual &&
140 test_cmp expect actual
143 test_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)
149 git grep -e "(3|4)" --recurse-submodules HEAD -- submodule >actual &&
150 test_cmp expect actual
153 test_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)
159 git grep -e "(3|4)" --recurse-submodules HEAD -- "submodule*a" >actual &&
160 test_cmp expect actual
163 test_expect_success 'grep tree and more pathspecs' '
164 cat >expect <<-\EOF &&
165 HEAD:submodule/a:(1|2)d(3|4)
168 git grep -e "(3|4)" --recurse-submodules HEAD -- "submodul?/a" >actual &&
169 test_cmp expect actual
172 test_expect_success 'grep tree and more pathspecs' '
173 cat >expect <<-\EOF &&
174 HEAD:submodule/sub/a:(1|2)d(3|4)
177 git grep -e "(3|4)" --recurse-submodules HEAD -- "submodul*/sub/a" >actual &&
178 test_cmp expect actual
181 test_expect_success !MINGW 'grep recurse submodule colon in name' '
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" &&
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" &&
196 git -C parent submodule add "../su:b" "su:b" &&
197 git -C parent commit -m "add submodule" &&
200 cat >expect <<-\EOF &&
202 su:b/fi:le:(1|2)d(3|4)
204 git -C parent grep -e "(1|2)d(3|4)" --recurse-submodules >actual &&
205 test_cmp expect actual &&
207 cat >expect <<-\EOF &&
208 HEAD:fi:le:(1|2)d(3|4)
209 HEAD:su:b/fi:le:(1|2)d(3|4)
211 git -C parent grep -e "(1|2)d(3|4)" --recurse-submodules HEAD >actual &&
212 test_cmp expect actual
215 test_expect_success 'grep history with moved submoules' '
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" &&
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" &&
230 git -C parent submodule add ../sub dir/sub &&
231 git -C parent commit -m "add submodule" &&
234 cat >expect <<-\EOF &&
235 dir/sub/file:(1|2)d(3|4)
238 git -C parent grep -e "(1|2)d(3|4)" --recurse-submodules >actual &&
239 test_cmp expect actual &&
241 git -C parent mv dir/sub sub-moved &&
242 git -C parent commit -m "moved submodule" &&
245 cat >expect <<-\EOF &&
247 sub-moved/file:(1|2)d(3|4)
249 git -C parent grep -e "(1|2)d(3|4)" --recurse-submodules >actual &&
250 test_cmp expect actual &&
252 cat >expect <<-\EOF &&
253 HEAD^:dir/sub/file:(1|2)d(3|4)
254 HEAD^:file:(1|2)d(3|4)
256 git -C parent grep -e "(1|2)d(3|4)" --recurse-submodules HEAD^ >actual &&
257 test_cmp expect actual
260 test_expect_success 'grep using relative path' '
261 test_when_finished "rm -rf parent sub" &&
263 echo "(1|2)d(3|4)" >sub/file &&
264 git -C sub add file &&
265 git -C sub commit -m "add file" &&
269 echo "(1|2)d(3|4)" >parent/file &&
270 git -C parent add file &&
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" &&
279 cat >expect <<-\EOF &&
281 src/file2:(1|2)d(3|4)
284 git -C parent grep --recurse-submodules -e "(1|2)d(3|4)" >actual &&
285 test_cmp expect actual &&
287 # Relative path to top
288 cat >expect <<-\EOF &&
291 ../sub/file:(1|2)d(3|4)
293 git -C parent/src grep --recurse-submodules -e "(1|2)d(3|4)" -- .. >actual &&
294 test_cmp expect actual &&
296 # Relative path to submodule
297 cat >expect <<-\EOF &&
298 ../sub/file:(1|2)d(3|4)
300 git -C parent/src grep --recurse-submodules -e "(1|2)d(3|4)" -- ../sub >actual &&
301 test_cmp expect actual
304 test_expect_success 'grep from a subdir' '
305 test_when_finished "rm -rf parent sub" &&
307 echo "(1|2)d(3|4)" >sub/file &&
308 git -C sub add file &&
309 git -C sub commit -m "add file" &&
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" &&
321 # Verify grep from root works
322 cat >expect <<-\EOF &&
324 src/sub/file:(1|2)d(3|4)
327 git -C parent grep --recurse-submodules -e "(1|2)d(3|4)" >actual &&
328 test_cmp expect actual &&
330 # Verify grep from a subdir works
331 cat >expect <<-\EOF &&
335 git -C parent/src grep --recurse-submodules -e "(1|2)d(3|4)" >actual &&
336 test_cmp expect actual
339 test_incompatible_with_recurse_submodules ()
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
347 test_incompatible_with_recurse_submodules --untracked
348 test_incompatible_with_recurse_submodules --no-index
350 test_expect_success 'grep --recurse-submodules should pass the pattern type along' '
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]" &&
356 git grep -G --recurse-submodules -e "(.|.)[\d]" >actual &&
357 cat >expect <<-\EOF &&
359 submodule/a:(1|2)d(3|4)
360 submodule/sub/a:(1|2)d(3|4)
362 test_cmp expect actual &&
363 git -c grep.patternType=basic grep --recurse-submodules -e "(.|.)[\d]" >actual &&
364 test_cmp expect actual &&
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
373 submodule/.gitmodules:[submodule "sub"]
374 submodule/a:(1|2)d(3|4)
375 submodule/sub/a:(1|2)d(3|4)
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 &&
384 if test_have_prereq PCRE
386 git grep -P --recurse-submodules -e "(.|.)[\d]" >actual &&
387 cat >expect <<-\EOF &&
390 submodule/a:(1|2)d(3|4)
391 submodule/sub/a:(1|2)d(3|4)
393 test_cmp expect actual &&
394 git -c grep.patternType=perl grep --recurse-submodules -e "(.|.)[\d]" >actual &&
395 test_cmp expect actual
399 test_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 &&
405 submodule/a:(1|2)d(3|4)
406 submodule/sub/a:(1|2)d(3|4)
408 test_cmp expect actual
414 git submodule foreach --recursive 'git reset --hard' &&
415 git submodule foreach --recursive 'git clean -fd'
418 test_expect_success 'grep --recurse-submodules without --cached considers worktree modifications' '
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
426 test_expect_success 'grep --recurse-submodules with --cached ignores worktree modifications' '
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