Merge branch 'km/stash-error-message-fix'
[git] / t / t7814-grep-recurse-submodules.sh
1 #!/bin/sh
2
3 test_description='Test grep recurse-submodules feature
4
5 This test verifies the recurse-submodules feature correctly greps across
6 submodules.
7 '
8
9 . ./test-lib.sh
10
11 test_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
27 test_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
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
43 '
44
45 test_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
56 test_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
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" &&
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
90 test_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
101 test_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
110 test_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
122 test_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
133 test_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
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)
147         EOF
148
149         git grep -e "(3|4)" --recurse-submodules HEAD -- submodule >actual &&
150         test_cmp expect actual
151 '
152
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)
157         EOF
158
159         git grep -e "(3|4)" --recurse-submodules HEAD -- "submodule*a" >actual &&
160         test_cmp expect actual
161 '
162
163 test_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
172 test_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
181 test_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
215 test_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
260 test_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
304 test_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
339 test_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
347 test_incompatible_with_recurse_submodules --untracked
348
349 test_expect_success 'grep --recurse-submodules --no-index ignores --recurse-submodules' '
350         git grep --recurse-submodules --no-index -e "^(.|.)[\d]" >actual &&
351         cat >expect <<-\EOF &&
352         a:(1|2)d(3|4)
353         submodule/a:(1|2)d(3|4)
354         submodule/sub/a:(1|2)d(3|4)
355         EOF
356         test_cmp expect actual
357 '
358
359 test_expect_success 'grep --recurse-submodules should pass the pattern type along' '
360         # Fixed
361         test_must_fail git grep -F --recurse-submodules -e "(.|.)[\d]" &&
362         test_must_fail git -c grep.patternType=fixed grep --recurse-submodules -e "(.|.)[\d]" &&
363
364         # Basic
365         git grep -G --recurse-submodules -e "(.|.)[\d]" >actual &&
366         cat >expect <<-\EOF &&
367         a:(1|2)d(3|4)
368         submodule/a:(1|2)d(3|4)
369         submodule/sub/a:(1|2)d(3|4)
370         EOF
371         test_cmp expect actual &&
372         git -c grep.patternType=basic grep --recurse-submodules -e "(.|.)[\d]" >actual &&
373         test_cmp expect actual &&
374
375         # Extended
376         git grep -E --recurse-submodules -e "(.|.)[\d]" >actual &&
377         cat >expect <<-\EOF &&
378         .gitmodules:[submodule "submodule"]
379         .gitmodules:    path = submodule
380         .gitmodules:    url = ./submodule
381         a:(1|2)d(3|4)
382         submodule/.gitmodules:[submodule "sub"]
383         submodule/a:(1|2)d(3|4)
384         submodule/sub/a:(1|2)d(3|4)
385         EOF
386         test_cmp expect actual &&
387         git -c grep.patternType=extended grep --recurse-submodules -e "(.|.)[\d]" >actual &&
388         test_cmp expect actual &&
389         git -c grep.extendedRegexp=true grep --recurse-submodules -e "(.|.)[\d]" >actual &&
390         test_cmp expect actual &&
391
392         # Perl
393         if test_have_prereq PCRE
394         then
395                 git grep -P --recurse-submodules -e "(.|.)[\d]" >actual &&
396                 cat >expect <<-\EOF &&
397                 a:(1|2)d(3|4)
398                 b/b:(3|4)
399                 submodule/a:(1|2)d(3|4)
400                 submodule/sub/a:(1|2)d(3|4)
401                 EOF
402                 test_cmp expect actual &&
403                 git -c grep.patternType=perl grep --recurse-submodules -e "(.|.)[\d]" >actual &&
404                 test_cmp expect actual
405         fi
406 '
407
408 test_expect_success 'grep --recurse-submodules with submodules without .gitmodules in the working tree' '
409         test_when_finished "git -C submodule checkout .gitmodules" &&
410         rm submodule/.gitmodules &&
411         git grep --recurse-submodules -e "(.|.)[\d]" >actual &&
412         cat >expect <<-\EOF &&
413         a:(1|2)d(3|4)
414         submodule/a:(1|2)d(3|4)
415         submodule/sub/a:(1|2)d(3|4)
416         EOF
417         test_cmp expect actual
418 '
419
420 reset_and_clean () {
421         git reset --hard &&
422         git clean -fd &&
423         git submodule foreach --recursive 'git reset --hard' &&
424         git submodule foreach --recursive 'git clean -fd'
425 }
426
427 test_expect_success 'grep --recurse-submodules without --cached considers worktree modifications' '
428         reset_and_clean &&
429         echo "A modified line in submodule" >>submodule/a &&
430         echo "submodule/a:A modified line in submodule" >expect &&
431         git grep --recurse-submodules "A modified line in submodule" >actual &&
432         test_cmp expect actual
433 '
434
435 test_expect_success 'grep --recurse-submodules with --cached ignores worktree modifications' '
436         reset_and_clean &&
437         echo "A modified line in submodule" >>submodule/a &&
438         test_must_fail git grep --recurse-submodules --cached "A modified line in submodule" >actual 2>&1 &&
439         test_must_be_empty actual
440 '
441 test_done