1#!/bin/sh
2#
3# Copyright (c) 2012 Avery Pennaraum
4# Copyright (c) 2015 Alexey Shumkin
5#
6test_description='Basic porcelain support for subtrees
7
8This test verifies the basic operation of the add, pull, merge
9and split subcommands of git subtree.
10'
11
12TEST_DIRECTORY=$(pwd)/../../../t
13export TEST_DIRECTORY
14
15. ../../../t/test-lib.sh
16
17subtree_test_create_repo()
18{
19 test_create_repo "$1"
20 (
21 cd $1
22 git config log.date relative
23 )
24}
25
26create()
27{
28 echo "$1" >"$1"
29 git add "$1"
30}
31
32check_equal()
33{
34 test_debug 'echo'
35 test_debug "echo \"check a:\" \"{$1}\""
36 test_debug "echo \" b:\" \"{$2}\""
37 if [ "$1" = "$2" ]; then
38 return 0
39 else
40 return 1
41 fi
42}
43
44undo()
45{
46 git reset --hard HEAD~
47}
48
49# Make sure no patch changes more than one file.
50# The original set of commits changed only one file each.
51# A multi-file change would imply that we pruned commits
52# too aggressively.
53join_commits()
54{
55 commit=
56 all=
57 while read x y; do
58 if [ -z "$x" ]; then
59 continue
60 elif [ "$x" = "commit:" ]; then
61 if [ -n "$commit" ]; then
62 echo "$commit $all"
63 all=
64 fi
65 commit="$y"
66 else
67 all="$all $y"
68 fi
69 done
70 echo "$commit $all"
71}
72
73test_create_commit() (
74 repo=$1
75 commit=$2
76 cd "$repo"
77 mkdir -p $(dirname "$commit") \
78 || error "Could not create directory for commit"
79 echo "$commit" >"$commit"
80 git add "$commit" || error "Could not add commit"
81 git commit -m "$commit" || error "Could not commit"
82)
83
84last_commit_message()
85{
86 git log --pretty=format:%s -1
87}
88
89subtree_test_count=0
90next_test() {
91 subtree_test_count=$(($subtree_test_count+1))
92}
93
94#
95# Tests for 'git subtree add'
96#
97
98next_test
99test_expect_success 'no merge from non-existent subtree' '
100 subtree_test_create_repo "$subtree_test_count" &&
101 subtree_test_create_repo "$subtree_test_count/sub proj" &&
102 test_create_commit "$subtree_test_count" main1 &&
103 test_create_commit "$subtree_test_count/sub proj" sub1 &&
104 (
105 cd "$subtree_test_count" &&
106 git fetch ./"sub proj" master &&
107 test_must_fail git subtree merge --prefix="sub dir" FETCH_HEAD
108 )
109'
110
111next_test
112test_expect_success 'no pull from non-existent subtree' '
113 subtree_test_create_repo "$subtree_test_count" &&
114 subtree_test_create_repo "$subtree_test_count/sub proj" &&
115 test_create_commit "$subtree_test_count" main1 &&
116 test_create_commit "$subtree_test_count/sub proj" sub1 &&
117 (
118 cd "$subtree_test_count" &&
119 git fetch ./"sub proj" master &&
120 test_must_fail git subtree pull --prefix="sub dir" ./"sub proj" master
121 )'
122
123next_test
124test_expect_success 'add subproj as subtree into sub dir/ with --prefix' '
125 subtree_test_create_repo "$subtree_test_count" &&
126 subtree_test_create_repo "$subtree_test_count/sub proj" &&
127 test_create_commit "$subtree_test_count" main1 &&
128 test_create_commit "$subtree_test_count/sub proj" sub1 &&
129 (
130 cd "$subtree_test_count" &&
131 git fetch ./"sub proj" master &&
132 git subtree add --prefix="sub dir" FETCH_HEAD &&
133 check_equal "$(last_commit_message)" "Add '\''sub dir/'\'' from commit '\''$(git rev-parse FETCH_HEAD)'\''"
134 )
135'
136
137next_test
138test_expect_success 'add subproj as subtree into sub dir/ with --prefix and --message' '
139 subtree_test_create_repo "$subtree_test_count" &&
140 subtree_test_create_repo "$subtree_test_count/sub proj" &&
141 test_create_commit "$subtree_test_count" main1 &&
142 test_create_commit "$subtree_test_count/sub proj" sub1 &&
143 (
144 cd "$subtree_test_count" &&
145 git fetch ./"sub proj" master &&
146 git subtree add --prefix="sub dir" --message="Added subproject" FETCH_HEAD &&
147 check_equal "$(last_commit_message)" "Added subproject"
148 )
149'
150
151next_test
152test_expect_success 'add subproj as subtree into sub dir/ with --prefix as -P and --message as -m' '
153 subtree_test_create_repo "$subtree_test_count" &&
154 subtree_test_create_repo "$subtree_test_count/sub proj" &&
155 test_create_commit "$subtree_test_count" main1 &&
156 test_create_commit "$subtree_test_count/sub proj" sub1 &&
157 (
158 cd "$subtree_test_count" &&
159 git fetch ./"sub proj" master &&
160 git subtree add -P "sub dir" -m "Added subproject" FETCH_HEAD &&
161 check_equal "$(last_commit_message)" "Added subproject"
162 )
163'
164
165next_test
166test_expect_success 'add subproj as subtree into sub dir/ with --squash and --prefix and --message' '
167 subtree_test_create_repo "$subtree_test_count" &&
168 subtree_test_create_repo "$subtree_test_count/sub proj" &&
169 test_create_commit "$subtree_test_count" main1 &&
170 test_create_commit "$subtree_test_count/sub proj" sub1 &&
171 (
172 cd "$subtree_test_count" &&
173 git fetch ./"sub proj" master &&
174 git subtree add --prefix="sub dir" --message="Added subproject with squash" --squash FETCH_HEAD &&
175 check_equal "$(last_commit_message)" "Added subproject with squash"
176 )
177'
178
179#
180# Tests for 'git subtree merge'
181#
182
183next_test
184test_expect_success 'merge new subproj history into sub dir/ with --prefix' '
185 subtree_test_create_repo "$subtree_test_count" &&
186 subtree_test_create_repo "$subtree_test_count/sub proj" &&
187 test_create_commit "$subtree_test_count" main1 &&
188 test_create_commit "$subtree_test_count/sub proj" sub1 &&
189 (
190 cd "$subtree_test_count" &&
191 git fetch ./"sub proj" master &&
192 git subtree add --prefix="sub dir" FETCH_HEAD
193 ) &&
194 test_create_commit "$subtree_test_count/sub proj" sub2 &&
195 (
196 cd "$subtree_test_count" &&
197 git fetch ./"sub proj" master &&
198 git subtree merge --prefix="sub dir" FETCH_HEAD &&
199 check_equal "$(last_commit_message)" "Merge commit '\''$(git rev-parse FETCH_HEAD)'\''"
200 )
201'
202
203next_test
204test_expect_success 'merge new subproj history into sub dir/ with --prefix and --message' '
205 subtree_test_create_repo "$subtree_test_count" &&
206 subtree_test_create_repo "$subtree_test_count/sub proj" &&
207 test_create_commit "$subtree_test_count" main1 &&
208 test_create_commit "$subtree_test_count/sub proj" sub1 &&
209 (
210 cd "$subtree_test_count" &&
211 git fetch ./"sub proj" master &&
212 git subtree add --prefix="sub dir" FETCH_HEAD
213 ) &&
214 test_create_commit "$subtree_test_count/sub proj" sub2 &&
215 (
216 cd "$subtree_test_count" &&
217 git fetch ./"sub proj" master &&
218 git subtree merge --prefix="sub dir" --message="Merged changes from subproject" FETCH_HEAD &&
219 check_equal "$(last_commit_message)" "Merged changes from subproject"
220 )
221'
222
223next_test
224test_expect_success 'merge new subproj history into sub dir/ with --squash and --prefix and --message' '
225 subtree_test_create_repo "$subtree_test_count/sub proj" &&
226 subtree_test_create_repo "$subtree_test_count" &&
227 test_create_commit "$subtree_test_count" main1 &&
228 test_create_commit "$subtree_test_count/sub proj" sub1 &&
229 (
230 cd "$subtree_test_count" &&
231 git fetch ./"sub proj" master &&
232 git subtree add --prefix="sub dir" FETCH_HEAD
233 ) &&
234 test_create_commit "$subtree_test_count/sub proj" sub2 &&
235 (
236 cd "$subtree_test_count" &&
237 git fetch ./"sub proj" master &&
238 git subtree merge --prefix="sub dir" --message="Merged changes from subproject using squash" --squash FETCH_HEAD &&
239 check_equal "$(last_commit_message)" "Merged changes from subproject using squash"
240 )
241'
242
243next_test
244test_expect_success 'merge the added subproj again, should do nothing' '
245 subtree_test_create_repo "$subtree_test_count" &&
246 subtree_test_create_repo "$subtree_test_count/sub proj" &&
247 test_create_commit "$subtree_test_count" main1 &&
248 test_create_commit "$subtree_test_count/sub proj" sub1 &&
249 (
250 cd "$subtree_test_count" &&
251 git fetch ./"sub proj" master &&
252 git subtree add --prefix="sub dir" FETCH_HEAD &&
253 # this shouldn not actually do anything, since FETCH_HEAD
254 # is already a parent
255 result=$(git merge -s ours -m "merge -s -ours" FETCH_HEAD) &&
256 check_equal "${result}" "Already up-to-date."
257 )
258'
259
260next_test
261test_expect_success 'merge new subproj history into subdir/ with a slash appended to the argument of --prefix' '
262 test_create_repo "$test_count" &&
263 test_create_repo "$test_count/subproj" &&
264 test_create_commit "$test_count" main1 &&
265 test_create_commit "$test_count/subproj" sub1 &&
266 (
267 cd "$test_count" &&
268 git fetch ./subproj master &&
269 git subtree add --prefix=subdir/ FETCH_HEAD
270 ) &&
271 test_create_commit "$test_count/subproj" sub2 &&
272 (
273 cd "$test_count" &&
274 git fetch ./subproj master &&
275 git subtree merge --prefix=subdir/ FETCH_HEAD &&
276 check_equal "$(last_commit_message)" "Merge commit '\''$(git rev-parse FETCH_HEAD)'\''"
277 )
278'
279
280#
281# Tests for 'git subtree split'
282#
283
284next_test
285test_expect_success 'split requires option --prefix' '
286 subtree_test_create_repo "$subtree_test_count" &&
287 subtree_test_create_repo "$subtree_test_count/sub proj" &&
288 test_create_commit "$subtree_test_count" main1 &&
289 test_create_commit "$subtree_test_count/sub proj" sub1 &&
290 (
291 cd "$subtree_test_count" &&
292 git fetch ./"sub proj" master &&
293 git subtree add --prefix="sub dir" FETCH_HEAD &&
294 echo "You must provide the --prefix option." > expected &&
295 test_must_fail git subtree split > actual 2>&1 &&
296 test_debug "printf '"expected: "'" &&
297 test_debug "cat expected" &&
298 test_debug "printf '"actual: "'" &&
299 test_debug "cat actual" &&
300 test_cmp expected actual
301 )
302'
303
304next_test
305test_expect_success 'split requires path given by option --prefix must exist' '
306 subtree_test_create_repo "$subtree_test_count" &&
307 subtree_test_create_repo "$subtree_test_count/sub proj" &&
308 test_create_commit "$subtree_test_count" main1 &&
309 test_create_commit "$subtree_test_count/sub proj" sub1 &&
310 (
311 cd "$subtree_test_count" &&
312 git fetch ./"sub proj" master &&
313 git subtree add --prefix="sub dir" FETCH_HEAD &&
314 echo "'\''non-existent-directory'\'' does not exist; use '\''git subtree add'\''" > expected &&
315 test_must_fail git subtree split --prefix=non-existent-directory > actual 2>&1 &&
316 test_debug "printf '"expected: "'" &&
317 test_debug "cat expected" &&
318 test_debug "printf '"actual: "'" &&
319 test_debug "cat actual" &&
320 test_cmp expected actual
321 )
322'
323
324next_test
325test_expect_success 'split sub dir/ with --rejoin' '
326 subtree_test_create_repo "$subtree_test_count" &&
327 subtree_test_create_repo "$subtree_test_count/sub proj" &&
328 test_create_commit "$subtree_test_count" main1 &&
329 test_create_commit "$subtree_test_count/sub proj" sub1 &&
330 (
331 cd "$subtree_test_count" &&
332 git fetch ./"sub proj" master &&
333 git subtree add --prefix="sub dir" FETCH_HEAD
334 ) &&
335 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
336 test_create_commit "$subtree_test_count" main2 &&
337 test_create_commit "$subtree_test_count/sub proj" sub2 &&
338 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
339 (
340 cd "$subtree_test_count" &&
341 git fetch ./"sub proj" master &&
342 git subtree merge --prefix="sub dir" FETCH_HEAD &&
343 split_hash=$(git subtree split --prefix="sub dir" --annotate="*") &&
344 git subtree split --prefix="sub dir" --annotate="*" --rejoin &&
345 check_equal "$(last_commit_message)" "Split '\''sub dir/'\'' into commit '\''$split_hash'\''"
346 )
347 '
348
349next_test
350test_expect_success 'split sub dir/ with --rejoin and --message' '
351 subtree_test_create_repo "$subtree_test_count" &&
352 subtree_test_create_repo "$subtree_test_count/sub proj" &&
353 test_create_commit "$subtree_test_count" main1 &&
354 test_create_commit "$subtree_test_count/sub proj" sub1 &&
355 (
356 cd "$subtree_test_count" &&
357 git fetch ./"sub proj" master &&
358 git subtree add --prefix="sub dir" FETCH_HEAD
359 ) &&
360 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
361 test_create_commit "$subtree_test_count" main2 &&
362 test_create_commit "$subtree_test_count/sub proj" sub2 &&
363 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
364 (
365 cd "$subtree_test_count" &&
366 git fetch ./"sub proj" master &&
367 git subtree merge --prefix="sub dir" FETCH_HEAD &&
368 git subtree split --prefix="sub dir" --message="Split & rejoin" --annotate="*" --rejoin &&
369 check_equal "$(last_commit_message)" "Split & rejoin"
370 )
371'
372
373next_test
374test_expect_success 'split "sub dir"/ with --branch' '
375 subtree_test_create_repo "$subtree_test_count" &&
376 subtree_test_create_repo "$subtree_test_count/sub proj" &&
377 test_create_commit "$subtree_test_count" main1 &&
378 test_create_commit "$subtree_test_count/sub proj" sub1 &&
379 (
380 cd "$subtree_test_count" &&
381 git fetch ./"sub proj" master &&
382 git subtree add --prefix="sub dir" FETCH_HEAD
383 ) &&
384 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
385 test_create_commit "$subtree_test_count" main2 &&
386 test_create_commit "$subtree_test_count/sub proj" sub2 &&
387 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
388 (
389 cd "$subtree_test_count" &&
390 git fetch ./"sub proj" master &&
391 git subtree merge --prefix="sub dir" FETCH_HEAD &&
392 split_hash=$(git subtree split --prefix="sub dir" --annotate="*") &&
393 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br &&
394 check_equal "$(git rev-parse subproj-br)" "$split_hash"
395 )
396'
397
398next_test
399test_expect_success 'check hash of split' '
400 subtree_test_create_repo "$subtree_test_count" &&
401 subtree_test_create_repo "$subtree_test_count/sub proj" &&
402 test_create_commit "$subtree_test_count" main1 &&
403 test_create_commit "$subtree_test_count/sub proj" sub1 &&
404 (
405 cd "$subtree_test_count" &&
406 git fetch ./"sub proj" master &&
407 git subtree add --prefix="sub dir" FETCH_HEAD
408 ) &&
409 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
410 test_create_commit "$subtree_test_count" main2 &&
411 test_create_commit "$subtree_test_count/sub proj" sub2 &&
412 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
413 (
414 cd "$subtree_test_count" &&
415 git fetch ./"sub proj" master &&
416 git subtree merge --prefix="sub dir" FETCH_HEAD &&
417 split_hash=$(git subtree split --prefix="sub dir" --annotate="*") &&
418 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br &&
419 check_equal "$(git rev-parse subproj-br)" "$split_hash" &&
420 # Check hash of split
421 new_hash=$(git rev-parse subproj-br^2) &&
422 (
423 cd ./"sub proj" &&
424 subdir_hash=$(git rev-parse HEAD) &&
425 check_equal ''"$new_hash"'' "$subdir_hash"
426 )
427 )
428'
429
430next_test
431test_expect_success 'split "sub dir"/ with --branch for an existing branch' '
432 subtree_test_create_repo "$subtree_test_count" &&
433 subtree_test_create_repo "$subtree_test_count/sub proj" &&
434 test_create_commit "$subtree_test_count" main1 &&
435 test_create_commit "$subtree_test_count/sub proj" sub1 &&
436 (
437 cd "$subtree_test_count" &&
438 git fetch ./"sub proj" master &&
439 git branch subproj-br FETCH_HEAD &&
440 git subtree add --prefix="sub dir" FETCH_HEAD
441 ) &&
442 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
443 test_create_commit "$subtree_test_count" main2 &&
444 test_create_commit "$subtree_test_count/sub proj" sub2 &&
445 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
446 (
447 cd "$subtree_test_count" &&
448 git fetch ./"sub proj" master &&
449 git subtree merge --prefix="sub dir" FETCH_HEAD &&
450 split_hash=$(git subtree split --prefix="sub dir" --annotate="*") &&
451 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br &&
452 check_equal "$(git rev-parse subproj-br)" "$split_hash"
453 )
454'
455
456next_test
457test_expect_success 'split "sub dir"/ with --branch for an incompatible branch' '
458 subtree_test_create_repo "$subtree_test_count" &&
459 subtree_test_create_repo "$subtree_test_count/sub proj" &&
460 test_create_commit "$subtree_test_count" main1 &&
461 test_create_commit "$subtree_test_count/sub proj" sub1 &&
462 (
463 cd "$subtree_test_count" &&
464 git branch init HEAD &&
465 git fetch ./"sub proj" master &&
466 git subtree add --prefix="sub dir" FETCH_HEAD
467 ) &&
468 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
469 test_create_commit "$subtree_test_count" main2 &&
470 test_create_commit "$subtree_test_count/sub proj" sub2 &&
471 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
472 (
473 cd "$subtree_test_count" &&
474 git fetch ./"sub proj" master &&
475 git subtree merge --prefix="sub dir" FETCH_HEAD &&
476 test_must_fail git subtree split --prefix="sub dir" --branch init
477 )
478'
479
480#
481# Validity checking
482#
483
484next_test
485test_expect_success 'make sure exactly the right set of files ends up in the subproj' '
486 subtree_test_create_repo "$subtree_test_count" &&
487 subtree_test_create_repo "$subtree_test_count/sub proj" &&
488 test_create_commit "$subtree_test_count" main1 &&
489 test_create_commit "$subtree_test_count/sub proj" sub1 &&
490 (
491 cd "$subtree_test_count" &&
492 git fetch ./"sub proj" master &&
493 git subtree add --prefix="sub dir" FETCH_HEAD
494 ) &&
495 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
496 test_create_commit "$subtree_test_count" main2 &&
497 test_create_commit "$subtree_test_count/sub proj" sub2 &&
498 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
499 (
500 cd "$subtree_test_count" &&
501 git fetch ./"sub proj" master &&
502 git subtree merge --prefix="sub dir" FETCH_HEAD &&
503 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
504 ) &&
505 test_create_commit "$subtree_test_count/sub proj" sub3 &&
506 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
507 (
508 cd "$subtree_test_count/sub proj" &&
509 git fetch .. subproj-br &&
510 git merge FETCH_HEAD
511 ) &&
512 test_create_commit "$subtree_test_count/sub proj" sub4 &&
513 (
514 cd "$subtree_test_count" &&
515 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
516 ) &&
517 test_create_commit "$subtree_test_count" "sub dir"/main-sub4 &&
518 (
519 cd "$subtree_test_count" &&
520 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
521 ) &&
522 (
523 cd "$subtree_test_count/sub proj" &&
524 git fetch .. subproj-br &&
525 git merge FETCH_HEAD &&
526
527 chks="sub1
528sub2
529sub3
530sub4" &&
531 chks_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
532$chks
533TXT
534) &&
535 chkms="main-sub1
536main-sub2
537main-sub3
538main-sub4" &&
539 chkms_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
540$chkms
541TXT
542) &&
543
544 subfiles=$(git ls-files) &&
545 check_equal "$subfiles" "$chkms
546$chks"
547 )
548'
549
550next_test
551test_expect_success 'make sure the subproj *only* contains commits that affect the "sub dir"' '
552 subtree_test_create_repo "$subtree_test_count" &&
553 subtree_test_create_repo "$subtree_test_count/sub proj" &&
554 test_create_commit "$subtree_test_count" main1 &&
555 test_create_commit "$subtree_test_count/sub proj" sub1 &&
556 (
557 cd "$subtree_test_count" &&
558 git fetch ./"sub proj" master &&
559 git subtree add --prefix="sub dir" FETCH_HEAD
560 ) &&
561 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
562 test_create_commit "$subtree_test_count" main2 &&
563 test_create_commit "$subtree_test_count/sub proj" sub2 &&
564 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
565 (
566 cd "$subtree_test_count" &&
567 git fetch ./"sub proj" master &&
568 git subtree merge --prefix="sub dir" FETCH_HEAD &&
569 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
570 ) &&
571 test_create_commit "$subtree_test_count/sub proj" sub3 &&
572 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
573 (
574 cd "$subtree_test_count/sub proj" &&
575 git fetch .. subproj-br &&
576 git merge FETCH_HEAD
577 ) &&
578 test_create_commit "$subtree_test_count/sub proj" sub4 &&
579 (
580 cd "$subtree_test_count" &&
581 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
582 ) &&
583 test_create_commit "$subtree_test_count" "sub dir"/main-sub4 &&
584 (
585 cd "$subtree_test_count" &&
586 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
587 ) &&
588 (
589 cd "$subtree_test_count/sub proj" &&
590 git fetch .. subproj-br &&
591 git merge FETCH_HEAD &&
592
593 chks="sub1
594sub2
595sub3
596sub4" &&
597 chks_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
598$chks
599TXT
600) &&
601 chkms="main-sub1
602main-sub2
603main-sub3
604main-sub4" &&
605 chkms_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
606$chkms
607TXT
608) &&
609 allchanges=$(git log --name-only --pretty=format:"" | sort | sed "/^$/d") &&
610 check_equal "$allchanges" "$chkms
611$chks"
612 )
613'
614
615next_test
616test_expect_success 'make sure exactly the right set of files ends up in the mainline' '
617 subtree_test_create_repo "$subtree_test_count" &&
618 subtree_test_create_repo "$subtree_test_count/sub proj" &&
619 test_create_commit "$subtree_test_count" main1 &&
620 test_create_commit "$subtree_test_count/sub proj" sub1 &&
621 (
622 cd "$subtree_test_count" &&
623 git fetch ./"sub proj" master &&
624 git subtree add --prefix="sub dir" FETCH_HEAD
625 ) &&
626 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
627 test_create_commit "$subtree_test_count" main2 &&
628 test_create_commit "$subtree_test_count/sub proj" sub2 &&
629 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
630 (
631 cd "$subtree_test_count" &&
632 git fetch ./"sub proj" master &&
633 git subtree merge --prefix="sub dir" FETCH_HEAD &&
634 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
635 ) &&
636 test_create_commit "$subtree_test_count/sub proj" sub3 &&
637 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
638 (
639 cd "$subtree_test_count/sub proj" &&
640 git fetch .. subproj-br &&
641 git merge FETCH_HEAD
642 ) &&
643 test_create_commit "$subtree_test_count/sub proj" sub4 &&
644 (
645 cd "$subtree_test_count" &&
646 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
647 ) &&
648 test_create_commit "$subtree_test_count" "sub dir"/main-sub4 &&
649 (
650 cd "$subtree_test_count" &&
651 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
652 ) &&
653 (
654 cd "$subtree_test_count/sub proj" &&
655 git fetch .. subproj-br &&
656 git merge FETCH_HEAD
657 ) &&
658 (
659 cd "$subtree_test_count" &&
660 git subtree pull --prefix="sub dir" ./"sub proj" master &&
661
662 chkm="main1
663main2" &&
664 chks="sub1
665sub2
666sub3
667sub4" &&
668 chks_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
669$chks
670TXT
671) &&
672 chkms="main-sub1
673main-sub2
674main-sub3
675main-sub4" &&
676 chkms_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
677$chkms
678TXT
679) &&
680 mainfiles=$(git ls-files) &&
681 check_equal "$mainfiles" "$chkm
682$chkms_sub
683$chks_sub"
684)
685'
686
687next_test
688test_expect_success 'make sure each filename changed exactly once in the entire history' '
689 subtree_test_create_repo "$subtree_test_count" &&
690 subtree_test_create_repo "$subtree_test_count/sub proj" &&
691 test_create_commit "$subtree_test_count" main1 &&
692 test_create_commit "$subtree_test_count/sub proj" sub1 &&
693 (
694 cd "$subtree_test_count" &&
695 git config log.date relative
696 git fetch ./"sub proj" master &&
697 git subtree add --prefix="sub dir" FETCH_HEAD
698 ) &&
699 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
700 test_create_commit "$subtree_test_count" main2 &&
701 test_create_commit "$subtree_test_count/sub proj" sub2 &&
702 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
703 (
704 cd "$subtree_test_count" &&
705 git fetch ./"sub proj" master &&
706 git subtree merge --prefix="sub dir" FETCH_HEAD &&
707 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
708 ) &&
709 test_create_commit "$subtree_test_count/sub proj" sub3 &&
710 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
711 (
712 cd "$subtree_test_count/sub proj" &&
713 git fetch .. subproj-br &&
714 git merge FETCH_HEAD
715 ) &&
716 test_create_commit "$subtree_test_count/sub proj" sub4 &&
717 (
718 cd "$subtree_test_count" &&
719 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
720 ) &&
721 test_create_commit "$subtree_test_count" "sub dir"/main-sub4 &&
722 (
723 cd "$subtree_test_count" &&
724 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
725 ) &&
726 (
727 cd "$subtree_test_count/sub proj" &&
728 git fetch .. subproj-br &&
729 git merge FETCH_HEAD
730 ) &&
731 (
732 cd "$subtree_test_count" &&
733 git subtree pull --prefix="sub dir" ./"sub proj" master &&
734
735 chkm="main1
736main2" &&
737 chks="sub1
738sub2
739sub3
740sub4" &&
741 chks_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
742$chks
743TXT
744) &&
745 chkms="main-sub1
746main-sub2
747main-sub3
748main-sub4" &&
749 chkms_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
750$chkms
751TXT
752) &&
753
754 # main-sub?? and /"sub dir"/main-sub?? both change, because those are the
755 # changes that were split into their own history. And "sub dir"/sub?? never
756 # change, since they were *only* changed in the subtree branch.
757 allchanges=$(git log --name-only --pretty=format:"" | sort | sed "/^$/d") &&
758 expected=''"$(cat <<TXT | sort
759$chkms
760$chkm
761$chks
762$chkms_sub
763TXT
764)"'' &&
765 check_equal "$allchanges" "$expected"
766 )
767'
768
769next_test
770test_expect_success 'make sure the --rejoin commits never make it into subproj' '
771 subtree_test_create_repo "$subtree_test_count" &&
772 subtree_test_create_repo "$subtree_test_count/sub proj" &&
773 test_create_commit "$subtree_test_count" main1 &&
774 test_create_commit "$subtree_test_count/sub proj" sub1 &&
775 (
776 cd "$subtree_test_count" &&
777 git fetch ./"sub proj" master &&
778 git subtree add --prefix="sub dir" FETCH_HEAD
779 ) &&
780 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
781 test_create_commit "$subtree_test_count" main2 &&
782 test_create_commit "$subtree_test_count/sub proj" sub2 &&
783 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
784 (
785 cd "$subtree_test_count" &&
786 git fetch ./"sub proj" master &&
787 git subtree merge --prefix="sub dir" FETCH_HEAD &&
788 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
789 ) &&
790 test_create_commit "$subtree_test_count/sub proj" sub3 &&
791 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
792 (
793 cd "$subtree_test_count/sub proj" &&
794 git fetch .. subproj-br &&
795 git merge FETCH_HEAD
796 ) &&
797 test_create_commit "$subtree_test_count/sub proj" sub4 &&
798 (
799 cd "$subtree_test_count" &&
800 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
801 ) &&
802 test_create_commit "$subtree_test_count" "sub dir"/main-sub4 &&
803 (
804 cd "$subtree_test_count" &&
805 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
806 ) &&
807 (
808 cd "$subtree_test_count/sub proj" &&
809 git fetch .. subproj-br &&
810 git merge FETCH_HEAD
811 ) &&
812 (
813 cd "$subtree_test_count" &&
814 git subtree pull --prefix="sub dir" ./"sub proj" master &&
815 check_equal "$(git log --pretty=format:"%s" HEAD^2 | grep -i split)" ""
816 )
817'
818
819next_test
820test_expect_success 'make sure no "git subtree" tagged commits make it into subproj' '
821 subtree_test_create_repo "$subtree_test_count" &&
822 subtree_test_create_repo "$subtree_test_count/sub proj" &&
823 test_create_commit "$subtree_test_count" main1 &&
824 test_create_commit "$subtree_test_count/sub proj" sub1 &&
825 (
826 cd "$subtree_test_count" &&
827 git fetch ./"sub proj" master &&
828 git subtree add --prefix="sub dir" FETCH_HEAD
829 ) &&
830 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
831 test_create_commit "$subtree_test_count" main2 &&
832 test_create_commit "$subtree_test_count/sub proj" sub2 &&
833 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
834 (
835 cd "$subtree_test_count" &&
836 git fetch ./"sub proj" master &&
837 git subtree merge --prefix="sub dir" FETCH_HEAD &&
838 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
839 ) &&
840 test_create_commit "$subtree_test_count/sub proj" sub3 &&
841 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
842 (
843 cd "$subtree_test_count/sub proj" &&
844 git fetch .. subproj-br &&
845 git merge FETCH_HEAD
846 ) &&
847 test_create_commit "$subtree_test_count/sub proj" sub4 &&
848 (
849 cd "$subtree_test_count" &&
850 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
851 ) &&
852 test_create_commit "$subtree_test_count" "sub dir"/main-sub4 &&
853 (
854 cd "$subtree_test_count" &&
855 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
856 ) &&
857 (
858 cd "$subtree_test_count/sub proj" &&
859 git fetch .. subproj-br &&
860 git merge FETCH_HEAD
861 ) &&
862 (
863 cd "$subtree_test_count" &&
864 git subtree pull --prefix="sub dir" ./"sub proj" master &&
865
866 # They are meaningless to subproj since one side of the merge refers to the mainline
867 check_equal "$(git log --pretty=format:"%s%n%b" HEAD^2 | grep "git-subtree.*:")" ""
868 )
869'
870
871#
872# A new set of tests
873#
874
875next_test
876test_expect_success 'make sure "git subtree split" find the correct parent' '
877 subtree_test_create_repo "$subtree_test_count" &&
878 subtree_test_create_repo "$subtree_test_count/sub proj" &&
879 test_create_commit "$subtree_test_count" main1 &&
880 test_create_commit "$subtree_test_count/sub proj" sub1 &&
881 (
882 cd "$subtree_test_count" &&
883 git fetch ./"sub proj" master &&
884 git subtree add --prefix="sub dir" FETCH_HEAD
885 ) &&
886 test_create_commit "$subtree_test_count/sub proj" sub2 &&
887 (
888 cd "$subtree_test_count" &&
889 git fetch ./"sub proj" master &&
890 git branch subproj-ref FETCH_HEAD &&
891 git subtree merge --prefix="sub dir" FETCH_HEAD
892 ) &&
893 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
894 (
895 cd "$subtree_test_count" &&
896 git subtree split --prefix="sub dir" --branch subproj-br &&
897
898 # at this point, the new commit parent should be subproj-ref, if it is
899 # not, something went wrong (the "newparent" of "master~" commit should
900 # have been sub2, but it was not, because its cache was not set to
901 # itself)
902 check_equal "$(git log --pretty=format:%P -1 subproj-br)" "$(git rev-parse subproj-ref)"
903 )
904'
905
906next_test
907test_expect_success 'split a new subtree without --onto option' '
908 subtree_test_create_repo "$subtree_test_count" &&
909 subtree_test_create_repo "$subtree_test_count/sub proj" &&
910 test_create_commit "$subtree_test_count" main1 &&
911 test_create_commit "$subtree_test_count/sub proj" sub1 &&
912 (
913 cd "$subtree_test_count" &&
914 git fetch ./"sub proj" master &&
915 git subtree add --prefix="sub dir" FETCH_HEAD
916 ) &&
917 test_create_commit "$subtree_test_count/sub proj" sub2 &&
918 (
919 cd "$subtree_test_count" &&
920 git fetch ./"sub proj" master &&
921 git subtree merge --prefix="sub dir" FETCH_HEAD
922 ) &&
923 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
924 (
925 cd "$subtree_test_count" &&
926 git subtree split --prefix="sub dir" --branch subproj-br
927 ) &&
928 mkdir "$subtree_test_count"/"sub dir2" &&
929 test_create_commit "$subtree_test_count" "sub dir2"/main-sub2 &&
930 (
931 cd "$subtree_test_count" &&
932
933 # also test that we still can split out an entirely new subtree
934 # if the parent of the first commit in the tree is not empty,
935 # then the new subtree has accidently been attached to something
936 git subtree split --prefix="sub dir2" --branch subproj2-br &&
937 check_equal "$(git log --pretty=format:%P -1 subproj2-br)" ""
938 )
939'
940
941next_test
942test_expect_success 'verify one file change per commit' '
943 subtree_test_create_repo "$subtree_test_count" &&
944 subtree_test_create_repo "$subtree_test_count/sub proj" &&
945 test_create_commit "$subtree_test_count" main1 &&
946 test_create_commit "$subtree_test_count/sub proj" sub1 &&
947 (
948 cd "$subtree_test_count" &&
949 git fetch ./"sub proj" master &&
950 git branch sub1 FETCH_HEAD &&
951 git subtree add --prefix="sub dir" sub1
952 ) &&
953 test_create_commit "$subtree_test_count/sub proj" sub2 &&
954 (
955 cd "$subtree_test_count" &&
956 git fetch ./"sub proj" master &&
957 git subtree merge --prefix="sub dir" FETCH_HEAD
958 ) &&
959 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
960 (
961 cd "$subtree_test_count" &&
962 git subtree split --prefix="sub dir" --branch subproj-br
963 ) &&
964 mkdir "$subtree_test_count"/"sub dir2" &&
965 test_create_commit "$subtree_test_count" "sub dir2"/main-sub2 &&
966 (
967 cd "$subtree_test_count" &&
968 git subtree split --prefix="sub dir2" --branch subproj2-br &&
969
970 x= &&
971 git log --pretty=format:"commit: %H" | join_commits |
972 (
973 while read commit a b; do
974 test_debug "echo Verifying commit $commit"
975 test_debug "echo a: $a"
976 test_debug "echo b: $b"
977 check_equal "$b" ""
978 x=1
979 done
980 check_equal "$x" 1
981 )
982 )
983'
984
985next_test
986test_expect_success 'push split to subproj' '
987 subtree_test_create_repo "$subtree_test_count" &&
988 subtree_test_create_repo "$subtree_test_count/sub proj" &&
989 test_create_commit "$subtree_test_count" main1 &&
990 test_create_commit "$subtree_test_count/sub proj" sub1 &&
991 (
992 cd "$subtree_test_count" &&
993 git fetch ./"sub proj" master &&
994 git subtree add --prefix="sub dir" FETCH_HEAD
995 ) &&
996 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
997 test_create_commit "$subtree_test_count" main2 &&
998 test_create_commit "$subtree_test_count/sub proj" sub2 &&
999 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
1000 (
1001 cd $subtree_test_count/"sub proj" &&
1002 git branch sub-branch-1 &&
1003 cd .. &&
1004 git fetch ./"sub proj" master &&
1005 git subtree merge --prefix="sub dir" FETCH_HEAD
1006 ) &&
1007 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
1008 (
1009 cd "$subtree_test_count" &&
1010 git subtree push ./"sub proj" --prefix "sub dir" sub-branch-1 &&
1011 cd ./"sub proj" &&
1012 git checkout sub-branch-1 &&
1013 check_equal "$(last_commit_message)" "sub dir/main-sub3"
1014 )
1015'
1016
1017#
1018# This test covers 2 cases in subtree split copy_or_skip code
1019# 1) Merges where one parent is a superset of the changes of the other
1020# parent regarding changes to the subtree, in this case the merge
1021# commit should be copied
1022# 2) Merges where only one parent operate on the subtree, and the merge
1023# commit should be skipped
1024#
1025# (1) is checked by ensuring subtree_tip is a descendent of subtree_branch
1026# (2) should have a check added (not_a_subtree_change shouldn't be present
1027# on the produced subtree)
1028#
1029# Other related cases which are not tested (or currently handled correctly)
1030# - Case (1) where there are more than 2 parents, it will sometimes correctly copy
1031# the merge, and sometimes not
1032# - Merge commit where both parents have same tree as the merge, currently
1033# will always be skipped, even if they reached that state via different
1034# set of commits.
1035#
1036
1037next_test
1038test_expect_success 'subtree descendant check' '
1039 subtree_test_create_repo "$subtree_test_count" &&
1040 test_create_commit "$subtree_test_count" folder_subtree/a &&
1041 (
1042 cd "$subtree_test_count" &&
1043 git branch branch
1044 ) &&
1045 test_create_commit "$subtree_test_count" folder_subtree/0 &&
1046 test_create_commit "$subtree_test_count" folder_subtree/b &&
1047 cherry=$(cd "$subtree_test_count"; git rev-parse HEAD) &&
1048 (
1049 cd "$subtree_test_count" &&
1050 git checkout branch
1051 ) &&
1052 test_create_commit "$subtree_test_count" commit_on_branch &&
1053 (
1054 cd "$subtree_test_count" &&
1055 git cherry-pick $cherry &&
1056 git checkout master &&
1057 git merge -m "merge should be kept on subtree" branch &&
1058 git branch no_subtree_work_branch
1059 ) &&
1060 test_create_commit "$subtree_test_count" folder_subtree/d &&
1061 (
1062 cd "$subtree_test_count" &&
1063 git checkout no_subtree_work_branch
1064 ) &&
1065 test_create_commit "$subtree_test_count" not_a_subtree_change &&
1066 (
1067 cd "$subtree_test_count" &&
1068 git checkout master &&
1069 git merge -m "merge should be skipped on subtree" no_subtree_work_branch &&
1070
1071 git subtree split --prefix folder_subtree/ --branch subtree_tip master &&
1072 git subtree split --prefix folder_subtree/ --branch subtree_branch branch &&
1073 check_equal $(git rev-list --count subtree_tip..subtree_branch) 0
1074 )
1075'
1076
1077test_done