]>
Commit | Line | Data |
---|---|---|
88961ef2 LH |
1 | #!/bin/sh |
2 | # | |
3 | # Copyright (c) 2007 Lars Hjemli | |
4 | # | |
5 | ||
6 | test_description='Basic porcelain support for submodules | |
7 | ||
8 | This test tries to verify basic sanity of the init, update and status | |
47a528ad | 9 | subcommands of git submodule. |
88961ef2 LH |
10 | ' |
11 | ||
12 | . ./test-lib.sh | |
13 | ||
fe454b13 JN |
14 | test_expect_success 'setup - initial commit' ' |
15 | >t && | |
47a528ad NS |
16 | git add t && |
17 | git commit -m "initial commit" && | |
fe454b13 JN |
18 | git branch initial |
19 | ' | |
20 | ||
21 | test_expect_success 'setup - repository in init subdirectory' ' | |
a2d93aea | 22 | mkdir init && |
fe454b13 JN |
23 | ( |
24 | cd init && | |
25 | git init && | |
26 | echo a >a && | |
27 | git add a && | |
28 | git commit -m "submodule commit 1" && | |
29 | git tag -a -m "rev-1" rev-1 | |
30 | ) | |
fe454b13 JN |
31 | ' |
32 | ||
33 | test_expect_success 'setup - commit with gitlink' ' | |
88961ef2 LH |
34 | echo a >a && |
35 | echo z >z && | |
a2d93aea | 36 | git add a init z && |
fe454b13 JN |
37 | git commit -m "super commit 1" |
38 | ' | |
39 | ||
40 | test_expect_success 'setup - hide init subdirectory' ' | |
41 | mv init .subrepo | |
42 | ' | |
43 | ||
a76c944b | 44 | test_expect_success 'setup - repository to add submodules to' ' |
31991b02 ÆAB |
45 | git init addtest && |
46 | git init addtest-ignore | |
a76c944b JN |
47 | ' |
48 | ||
49 | # The 'submodule add' tests need some repository to add as a submodule. | |
50 | # The trash directory is a good one as any. | |
51 | submodurl=$TRASH_DIRECTORY | |
52 | ||
53 | listbranches() { | |
54 | git for-each-ref --format='%(refname)' 'refs/heads/*' | |
55 | } | |
56 | ||
57 | inspect() { | |
58 | dir=$1 && | |
59 | dotdot="${2:-..}" && | |
60 | ||
ac8463d2 | 61 | ( |
a76c944b JN |
62 | cd "$dir" && |
63 | listbranches >"$dotdot/heads" && | |
64 | { git symbolic-ref HEAD || :; } >"$dotdot/head" && | |
ce8b54d6 | 65 | git rev-parse HEAD >"$dotdot/head-sha1" && |
a76c944b JN |
66 | git update-index --refresh && |
67 | git diff-files --exit-code && | |
68 | git clean -n -d -x >"$dotdot/untracked" | |
ac8463d2 | 69 | ) |
a76c944b | 70 | } |
ac8463d2 MG |
71 | |
72 | test_expect_success 'submodule add' ' | |
a76c944b JN |
73 | echo "refs/heads/master" >expect && |
74 | >empty && | |
75 | ||
ac8463d2 MG |
76 | ( |
77 | cd addtest && | |
78 | git submodule add "$submodurl" submod && | |
79 | git submodule init | |
a76c944b JN |
80 | ) && |
81 | ||
82 | rm -f heads head untracked && | |
83 | inspect addtest/submod ../.. && | |
84 | test_cmp expect heads && | |
85 | test_cmp expect head && | |
86 | test_cmp empty untracked | |
ac8463d2 MG |
87 | ' |
88 | ||
d27b876b | 89 | test_expect_success 'submodule add to .gitignored path fails' ' |
31991b02 ÆAB |
90 | ( |
91 | cd addtest-ignore && | |
d27b876b JL |
92 | cat <<-\EOF >expect && |
93 | The following path is ignored by one of your .gitignore files: | |
94 | submod | |
95 | Use -f if you really want to add it. | |
96 | EOF | |
31991b02 ÆAB |
97 | # Does not use test_commit due to the ignore |
98 | echo "*" > .gitignore && | |
99 | git add --force .gitignore && | |
100 | git commit -m"Ignore everything" && | |
d27b876b JL |
101 | ! git submodule add "$submodurl" submod >actual 2>&1 && |
102 | test_cmp expect actual | |
103 | ) | |
104 | ' | |
31991b02 | 105 | |
d27b876b JL |
106 | test_expect_success 'submodule add to .gitignored path with --force' ' |
107 | ( | |
108 | cd addtest-ignore && | |
109 | git submodule add --force "$submodurl" submod | |
110 | ) | |
31991b02 ÆAB |
111 | ' |
112 | ||
ea10b60c | 113 | test_expect_success 'submodule add --branch' ' |
a76c944b JN |
114 | echo "refs/heads/initial" >expect-head && |
115 | cat <<-\EOF >expect-heads && | |
116 | refs/heads/initial | |
117 | refs/heads/master | |
118 | EOF | |
119 | >empty && | |
120 | ||
ea10b60c BJ |
121 | ( |
122 | cd addtest && | |
123 | git submodule add -b initial "$submodurl" submod-branch && | |
a76c944b JN |
124 | git submodule init |
125 | ) && | |
126 | ||
127 | rm -f heads head untracked && | |
128 | inspect addtest/submod-branch ../.. && | |
129 | test_cmp expect-heads heads && | |
130 | test_cmp expect-head head && | |
131 | test_cmp empty untracked | |
ea10b60c BJ |
132 | ' |
133 | ||
db75ada5 | 134 | test_expect_success 'submodule add with ./ in path' ' |
a76c944b JN |
135 | echo "refs/heads/master" >expect && |
136 | >empty && | |
137 | ||
ac8463d2 MG |
138 | ( |
139 | cd addtest && | |
140 | git submodule add "$submodurl" ././dotsubmod/./frotz/./ && | |
141 | git submodule init | |
a76c944b JN |
142 | ) && |
143 | ||
144 | rm -f heads head untracked && | |
145 | inspect addtest/dotsubmod/frotz ../../.. && | |
146 | test_cmp expect heads && | |
147 | test_cmp expect head && | |
148 | test_cmp empty untracked | |
ac8463d2 MG |
149 | ' |
150 | ||
db75ada5 | 151 | test_expect_success 'submodule add with // in path' ' |
a76c944b JN |
152 | echo "refs/heads/master" >expect && |
153 | >empty && | |
154 | ||
ac8463d2 MG |
155 | ( |
156 | cd addtest && | |
157 | git submodule add "$submodurl" slashslashsubmod///frotz// && | |
158 | git submodule init | |
a76c944b JN |
159 | ) && |
160 | ||
161 | rm -f heads head untracked && | |
162 | inspect addtest/slashslashsubmod/frotz ../../.. && | |
163 | test_cmp expect heads && | |
164 | test_cmp expect head && | |
165 | test_cmp empty untracked | |
ac8463d2 MG |
166 | ' |
167 | ||
db75ada5 | 168 | test_expect_success 'submodule add with /.. in path' ' |
a76c944b JN |
169 | echo "refs/heads/master" >expect && |
170 | >empty && | |
171 | ||
ac8463d2 MG |
172 | ( |
173 | cd addtest && | |
174 | git submodule add "$submodurl" dotdotsubmod/../realsubmod/frotz/.. && | |
175 | git submodule init | |
a76c944b JN |
176 | ) && |
177 | ||
178 | rm -f heads head untracked && | |
179 | inspect addtest/realsubmod ../.. && | |
180 | test_cmp expect heads && | |
181 | test_cmp expect head && | |
182 | test_cmp empty untracked | |
ac8463d2 MG |
183 | ' |
184 | ||
db75ada5 | 185 | test_expect_success 'submodule add with ./, /.. and // in path' ' |
a76c944b JN |
186 | echo "refs/heads/master" >expect && |
187 | >empty && | |
188 | ||
ac8463d2 MG |
189 | ( |
190 | cd addtest && | |
191 | git submodule add "$submodurl" dot/dotslashsubmod/./../..////realsubmod2/a/b/c/d/../../../../frotz//.. && | |
192 | git submodule init | |
a76c944b JN |
193 | ) && |
194 | ||
195 | rm -f heads head untracked && | |
196 | inspect addtest/realsubmod2 ../.. && | |
197 | test_cmp expect heads && | |
198 | test_cmp expect head && | |
199 | test_cmp empty untracked | |
ac8463d2 MG |
200 | ' |
201 | ||
ce8b54d6 JN |
202 | test_expect_success 'setup - add an example entry to .gitmodules' ' |
203 | GIT_CONFIG=.gitmodules \ | |
204 | git config submodule.example.url git://example.com/init.git | |
205 | ' | |
206 | ||
941987a5 | 207 | test_expect_success 'status should fail for unmapped paths' ' |
ce8b54d6 JN |
208 | test_must_fail git submodule status |
209 | ' | |
210 | ||
211 | test_expect_success 'setup - map path in .gitmodules' ' | |
212 | cat <<\EOF >expect && | |
213 | [submodule "example"] | |
214 | url = git://example.com/init.git | |
215 | path = init | |
216 | EOF | |
217 | ||
218 | GIT_CONFIG=.gitmodules git config submodule.example.path init && | |
219 | ||
220 | test_cmp expect .gitmodules | |
88961ef2 LH |
221 | ' |
222 | ||
223 | test_expect_success 'status should only print one line' ' | |
ce8b54d6 JN |
224 | git submodule status >lines && |
225 | test $(wc -l <lines) = 1 | |
226 | ' | |
227 | ||
228 | test_expect_success 'setup - fetch commit name from submodule' ' | |
229 | rev1=$(cd .subrepo && git rev-parse HEAD) && | |
230 | printf "rev1: %s\n" "$rev1" && | |
231 | test -n "$rev1" | |
88961ef2 LH |
232 | ' |
233 | ||
234 | test_expect_success 'status should initially be "missing"' ' | |
ce8b54d6 JN |
235 | git submodule status >lines && |
236 | grep "^-$rev1" lines | |
88961ef2 LH |
237 | ' |
238 | ||
211b7f19 | 239 | test_expect_success 'init should register submodule url in .git/config' ' |
ce8b54d6 JN |
240 | echo git://example.com/init.git >expect && |
241 | ||
47a528ad | 242 | git submodule init && |
ce8b54d6 JN |
243 | git config submodule.example.url >url && |
244 | git config submodule.example.url ./.subrepo && | |
245 | ||
246 | test_cmp expect url | |
211b7f19 LH |
247 | ' |
248 | ||
249 | test_expect_success 'update should fail when path is used by a file' ' | |
ce8b54d6 JN |
250 | echo hello >expect && |
251 | ||
a2d93aea | 252 | echo "hello" >init && |
ce8b54d6 JN |
253 | test_must_fail git submodule update && |
254 | ||
255 | test_cmp expect init | |
88961ef2 LH |
256 | ' |
257 | ||
211b7f19 | 258 | test_expect_success 'update should fail when path is used by a nonempty directory' ' |
ce8b54d6 JN |
259 | echo hello >expect && |
260 | ||
261 | rm -fr init && | |
a2d93aea JH |
262 | mkdir init && |
263 | echo "hello" >init/a && | |
ce8b54d6 JN |
264 | |
265 | test_must_fail git submodule update && | |
266 | ||
267 | test_cmp expect init/a | |
88961ef2 LH |
268 | ' |
269 | ||
211b7f19 | 270 | test_expect_success 'update should work when path is an empty dir' ' |
ce8b54d6 JN |
271 | rm -fr init && |
272 | rm -f head-sha1 && | |
273 | echo "$rev1" >expect && | |
274 | ||
a2d93aea | 275 | mkdir init && |
47a528ad | 276 | git submodule update && |
ce8b54d6 JN |
277 | |
278 | inspect init && | |
279 | test_cmp expect head-sha1 | |
88961ef2 LH |
280 | ' |
281 | ||
211b7f19 | 282 | test_expect_success 'status should be "up-to-date" after update' ' |
ce8b54d6 JN |
283 | git submodule status >list && |
284 | grep "^ $rev1" list | |
88961ef2 LH |
285 | ' |
286 | ||
287 | test_expect_success 'status should be "modified" after submodule commit' ' | |
ce8b54d6 JN |
288 | ( |
289 | cd init && | |
290 | echo b >b && | |
291 | git add b && | |
292 | git commit -m "submodule commit 2" | |
293 | ) && | |
294 | ||
295 | rev2=$(cd init && git rev-parse HEAD) && | |
296 | test -n "$rev2" && | |
297 | git submodule status >list && | |
298 | ||
299 | grep "^+$rev2" list | |
88961ef2 LH |
300 | ' |
301 | ||
302 | test_expect_success 'the --cached sha1 should be rev1' ' | |
ce8b54d6 JN |
303 | git submodule --cached status >list && |
304 | grep "^+$rev1" list | |
88961ef2 LH |
305 | ' |
306 | ||
5701115a | 307 | test_expect_success 'git diff should report the SHA1 of the new submodule commit' ' |
ce8b54d6 JN |
308 | git diff >diff && |
309 | grep "^+Subproject commit $rev2" diff | |
5701115a SV |
310 | ' |
311 | ||
88961ef2 | 312 | test_expect_success 'update should checkout rev1' ' |
ce8b54d6 JN |
313 | rm -f head-sha1 && |
314 | echo "$rev1" >expect && | |
315 | ||
47a528ad | 316 | git submodule update init && |
ce8b54d6 JN |
317 | inspect init && |
318 | ||
319 | test_cmp expect head-sha1 | |
88961ef2 LH |
320 | ' |
321 | ||
322 | test_expect_success 'status should be "up-to-date" after update' ' | |
ce8b54d6 JN |
323 | git submodule status >list && |
324 | grep "^ $rev1" list | |
88961ef2 LH |
325 | ' |
326 | ||
0cf73755 | 327 | test_expect_success 'checkout superproject with subproject already present' ' |
47a528ad NS |
328 | git checkout initial && |
329 | git checkout master | |
0cf73755 SV |
330 | ' |
331 | ||
e06c5a6c | 332 | test_expect_success 'apply submodule diff' ' |
ce8b54d6 JN |
333 | >empty && |
334 | ||
e06c5a6c SV |
335 | git branch second && |
336 | ( | |
a2d93aea | 337 | cd init && |
e06c5a6c SV |
338 | echo s >s && |
339 | git add s && | |
340 | git commit -m "change subproject" | |
341 | ) && | |
a2d93aea | 342 | git update-index --add init && |
47a528ad NS |
343 | git commit -m "change init" && |
344 | git format-patch -1 --stdout >P.diff && | |
e06c5a6c SV |
345 | git checkout second && |
346 | git apply --index P.diff && | |
ce8b54d6 JN |
347 | |
348 | git diff --cached master >staged && | |
349 | test_cmp empty staged | |
e06c5a6c SV |
350 | ' |
351 | ||
be4d2c83 | 352 | test_expect_success 'update --init' ' |
be4d2c83 JS |
353 | mv init init2 && |
354 | git config -f .gitmodules submodule.example.url "$(pwd)/init2" && | |
ce8b54d6 JN |
355 | git config --remove-section submodule.example && |
356 | test_must_fail git config submodule.example.url && | |
357 | ||
be4d2c83 | 358 | git submodule update init > update.out && |
ce8b54d6 | 359 | cat update.out && |
be4d2c83 | 360 | grep "not initialized" update.out && |
ce8b54d6 JN |
361 | ! test -d init/.git && |
362 | ||
be4d2c83 JS |
363 | git submodule update --init init && |
364 | test -d init/.git | |
be4d2c83 JS |
365 | ' |
366 | ||
2ce53f9b JS |
367 | test_expect_success 'do not add files from a submodule' ' |
368 | ||
369 | git reset --hard && | |
370 | test_must_fail git add init/a | |
371 | ||
372 | ' | |
373 | ||
374 | test_expect_success 'gracefully add submodule with a trailing slash' ' | |
375 | ||
376 | git reset --hard && | |
377 | git commit -m "commit subproject" init && | |
378 | (cd init && | |
379 | echo b > a) && | |
380 | git add init/ && | |
381 | git diff --exit-code --cached init && | |
382 | commit=$(cd init && | |
383 | git commit -m update a >/dev/null && | |
384 | git rev-parse HEAD) && | |
385 | git add init/ && | |
386 | test_must_fail git diff --exit-code --cached init && | |
387 | test $commit = $(git ls-files --stage | | |
388 | sed -n "s/^160000 \([^ ]*\).*/\1/p") | |
389 | ||
390 | ' | |
391 | ||
f3670a57 JS |
392 | test_expect_success 'ls-files gracefully handles trailing slash' ' |
393 | ||
394 | test "init" = "$(git ls-files init/)" | |
395 | ||
396 | ' | |
397 | ||
c5e558a8 PC |
398 | test_expect_success 'moving to a commit without submodule does not leave empty dir' ' |
399 | rm -rf init && | |
400 | mkdir init && | |
401 | git reset --hard && | |
402 | git checkout initial && | |
403 | test ! -d init && | |
404 | git checkout second | |
405 | ' | |
406 | ||
496917b7 JS |
407 | test_expect_success 'submodule <invalid-path> warns' ' |
408 | ||
409 | git submodule no-such-submodule 2> output.err && | |
410 | grep "^error: .*no-such-submodule" output.err | |
411 | ||
412 | ' | |
413 | ||
1414e578 JL |
414 | test_expect_success 'add submodules without specifying an explicit path' ' |
415 | mkdir repo && | |
18a82692 JN |
416 | ( |
417 | cd repo && | |
418 | git init && | |
419 | echo r >r && | |
420 | git add r && | |
421 | git commit -m "repo commit 1" | |
fd4ec4f2 | 422 | ) && |
1414e578 | 423 | git clone --bare repo/ bare.git && |
69e7236c JL |
424 | ( |
425 | cd addtest && | |
426 | git submodule add "$submodurl/repo" && | |
427 | git config -f .gitmodules submodule.repo.path repo && | |
428 | git submodule add "$submodurl/bare.git" && | |
429 | git config -f .gitmodules submodule.bare.path bare | |
430 | ) | |
431 | ' | |
432 | ||
433 | test_expect_success 'add should fail when path is used by a file' ' | |
434 | ( | |
435 | cd addtest && | |
436 | touch file && | |
437 | test_must_fail git submodule add "$submodurl/repo" file | |
438 | ) | |
439 | ' | |
440 | ||
441 | test_expect_success 'add should fail when path is used by an existing directory' ' | |
442 | ( | |
443 | cd addtest && | |
444 | mkdir empty-dir && | |
445 | test_must_fail git submodule add "$submodurl/repo" empty-dir | |
446 | ) | |
1414e578 JL |
447 | ' |
448 | ||
8537f0ef JL |
449 | test_expect_success 'add should fail when path is relative but no url is set in the superproject' ' |
450 | ( | |
451 | cd addtest && | |
452 | test_must_fail git submodule add ../repo relative | |
453 | ) | |
454 | ' | |
455 | ||
ea640cc6 TR |
456 | test_expect_success 'set up for relative path tests' ' |
457 | mkdir reltest && | |
458 | ( | |
459 | cd reltest && | |
460 | git init && | |
461 | mkdir sub && | |
462 | ( | |
463 | cd sub && | |
464 | git init && | |
465 | test_commit foo | |
466 | ) && | |
467 | git add sub && | |
468 | git config -f .gitmodules submodule.sub.path sub && | |
469 | git config -f .gitmodules submodule.sub.url ../subrepo && | |
470 | cp .git/config pristine-.git-config | |
471 | ) | |
472 | ' | |
473 | ||
474 | test_expect_success 'relative path works with URL' ' | |
475 | ( | |
476 | cd reltest && | |
477 | cp pristine-.git-config .git/config && | |
478 | git config remote.origin.url ssh://hostname/repo && | |
479 | git submodule init && | |
480 | test "$(git config submodule.sub.url)" = ssh://hostname/subrepo | |
481 | ) | |
482 | ' | |
483 | ||
484 | test_expect_success 'relative path works with user@host:path' ' | |
485 | ( | |
486 | cd reltest && | |
487 | cp pristine-.git-config .git/config && | |
488 | git config remote.origin.url user@host:repo && | |
489 | git submodule init && | |
490 | test "$(git config submodule.sub.url)" = user@host:subrepo | |
491 | ) | |
492 | ' | |
493 | ||
88961ef2 | 494 | test_done |