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 from scratch' '
351 subtree_test_create_repo "$subtree_test_count" &&
352 test_create_commit "$subtree_test_count" main1 &&
353 (
354 cd "$subtree_test_count" &&
355 mkdir "sub dir" &&
356 echo file >"sub dir"/file &&
357 git add "sub dir/file" &&
358 git commit -m"sub dir file" &&
359 split_hash=$(git subtree split --prefix="sub dir" --rejoin) &&
360 git subtree split --prefix="sub dir" --rejoin &&
361 check_equal "$(last_commit_message)" "Split '\''sub dir/'\'' into commit '\''$split_hash'\''"
362 )
363 '
364
365next_test
366test_expect_success 'split sub dir/ with --rejoin and --message' '
367 subtree_test_create_repo "$subtree_test_count" &&
368 subtree_test_create_repo "$subtree_test_count/sub proj" &&
369 test_create_commit "$subtree_test_count" main1 &&
370 test_create_commit "$subtree_test_count/sub proj" sub1 &&
371 (
372 cd "$subtree_test_count" &&
373 git fetch ./"sub proj" master &&
374 git subtree add --prefix="sub dir" FETCH_HEAD
375 ) &&
376 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
377 test_create_commit "$subtree_test_count" main2 &&
378 test_create_commit "$subtree_test_count/sub proj" sub2 &&
379 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
380 (
381 cd "$subtree_test_count" &&
382 git fetch ./"sub proj" master &&
383 git subtree merge --prefix="sub dir" FETCH_HEAD &&
384 git subtree split --prefix="sub dir" --message="Split & rejoin" --annotate="*" --rejoin &&
385 check_equal "$(last_commit_message)" "Split & rejoin"
386 )
387'
388
389next_test
390test_expect_success 'split "sub dir"/ with --branch' '
391 subtree_test_create_repo "$subtree_test_count" &&
392 subtree_test_create_repo "$subtree_test_count/sub proj" &&
393 test_create_commit "$subtree_test_count" main1 &&
394 test_create_commit "$subtree_test_count/sub proj" sub1 &&
395 (
396 cd "$subtree_test_count" &&
397 git fetch ./"sub proj" master &&
398 git subtree add --prefix="sub dir" FETCH_HEAD
399 ) &&
400 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
401 test_create_commit "$subtree_test_count" main2 &&
402 test_create_commit "$subtree_test_count/sub proj" sub2 &&
403 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
404 (
405 cd "$subtree_test_count" &&
406 git fetch ./"sub proj" master &&
407 git subtree merge --prefix="sub dir" FETCH_HEAD &&
408 split_hash=$(git subtree split --prefix="sub dir" --annotate="*") &&
409 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br &&
410 check_equal "$(git rev-parse subproj-br)" "$split_hash"
411 )
412'
413
414next_test
415test_expect_success 'check hash of split' '
416 subtree_test_create_repo "$subtree_test_count" &&
417 subtree_test_create_repo "$subtree_test_count/sub proj" &&
418 test_create_commit "$subtree_test_count" main1 &&
419 test_create_commit "$subtree_test_count/sub proj" sub1 &&
420 (
421 cd "$subtree_test_count" &&
422 git fetch ./"sub proj" master &&
423 git subtree add --prefix="sub dir" FETCH_HEAD
424 ) &&
425 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
426 test_create_commit "$subtree_test_count" main2 &&
427 test_create_commit "$subtree_test_count/sub proj" sub2 &&
428 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
429 (
430 cd "$subtree_test_count" &&
431 git fetch ./"sub proj" master &&
432 git subtree merge --prefix="sub dir" FETCH_HEAD &&
433 split_hash=$(git subtree split --prefix="sub dir" --annotate="*") &&
434 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br &&
435 check_equal "$(git rev-parse subproj-br)" "$split_hash" &&
436 # Check hash of split
437 new_hash=$(git rev-parse subproj-br^2) &&
438 (
439 cd ./"sub proj" &&
440 subdir_hash=$(git rev-parse HEAD) &&
441 check_equal ''"$new_hash"'' "$subdir_hash"
442 )
443 )
444'
445
446next_test
447test_expect_success 'split "sub dir"/ with --branch for an existing branch' '
448 subtree_test_create_repo "$subtree_test_count" &&
449 subtree_test_create_repo "$subtree_test_count/sub proj" &&
450 test_create_commit "$subtree_test_count" main1 &&
451 test_create_commit "$subtree_test_count/sub proj" sub1 &&
452 (
453 cd "$subtree_test_count" &&
454 git fetch ./"sub proj" master &&
455 git branch subproj-br FETCH_HEAD &&
456 git subtree add --prefix="sub dir" FETCH_HEAD
457 ) &&
458 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
459 test_create_commit "$subtree_test_count" main2 &&
460 test_create_commit "$subtree_test_count/sub proj" sub2 &&
461 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
462 (
463 cd "$subtree_test_count" &&
464 git fetch ./"sub proj" master &&
465 git subtree merge --prefix="sub dir" FETCH_HEAD &&
466 split_hash=$(git subtree split --prefix="sub dir" --annotate="*") &&
467 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br &&
468 check_equal "$(git rev-parse subproj-br)" "$split_hash"
469 )
470'
471
472next_test
473test_expect_success 'split "sub dir"/ with --branch for an incompatible branch' '
474 subtree_test_create_repo "$subtree_test_count" &&
475 subtree_test_create_repo "$subtree_test_count/sub proj" &&
476 test_create_commit "$subtree_test_count" main1 &&
477 test_create_commit "$subtree_test_count/sub proj" sub1 &&
478 (
479 cd "$subtree_test_count" &&
480 git branch init HEAD &&
481 git fetch ./"sub proj" master &&
482 git subtree add --prefix="sub dir" FETCH_HEAD
483 ) &&
484 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
485 test_create_commit "$subtree_test_count" main2 &&
486 test_create_commit "$subtree_test_count/sub proj" sub2 &&
487 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
488 (
489 cd "$subtree_test_count" &&
490 git fetch ./"sub proj" master &&
491 git subtree merge --prefix="sub dir" FETCH_HEAD &&
492 test_must_fail git subtree split --prefix="sub dir" --branch init
493 )
494'
495
496#
497# Validity checking
498#
499
500next_test
501test_expect_success 'make sure exactly the right set of files ends up in the subproj' '
502 subtree_test_create_repo "$subtree_test_count" &&
503 subtree_test_create_repo "$subtree_test_count/sub proj" &&
504 test_create_commit "$subtree_test_count" main1 &&
505 test_create_commit "$subtree_test_count/sub proj" sub1 &&
506 (
507 cd "$subtree_test_count" &&
508 git fetch ./"sub proj" master &&
509 git subtree add --prefix="sub dir" FETCH_HEAD
510 ) &&
511 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
512 test_create_commit "$subtree_test_count" main2 &&
513 test_create_commit "$subtree_test_count/sub proj" sub2 &&
514 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
515 (
516 cd "$subtree_test_count" &&
517 git fetch ./"sub proj" master &&
518 git subtree merge --prefix="sub dir" FETCH_HEAD &&
519 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
520 ) &&
521 test_create_commit "$subtree_test_count/sub proj" sub3 &&
522 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
523 (
524 cd "$subtree_test_count/sub proj" &&
525 git fetch .. subproj-br &&
526 git merge FETCH_HEAD
527 ) &&
528 test_create_commit "$subtree_test_count/sub proj" sub4 &&
529 (
530 cd "$subtree_test_count" &&
531 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
532 ) &&
533 test_create_commit "$subtree_test_count" "sub dir"/main-sub4 &&
534 (
535 cd "$subtree_test_count" &&
536 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
537 ) &&
538 (
539 cd "$subtree_test_count/sub proj" &&
540 git fetch .. subproj-br &&
541 git merge FETCH_HEAD &&
542
543 chks="sub1
544sub2
545sub3
546sub4" &&
547 chks_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
548$chks
549TXT
550) &&
551 chkms="main-sub1
552main-sub2
553main-sub3
554main-sub4" &&
555 chkms_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
556$chkms
557TXT
558) &&
559
560 subfiles=$(git ls-files) &&
561 check_equal "$subfiles" "$chkms
562$chks"
563 )
564'
565
566next_test
567test_expect_success 'make sure the subproj *only* contains commits that affect the "sub dir"' '
568 subtree_test_create_repo "$subtree_test_count" &&
569 subtree_test_create_repo "$subtree_test_count/sub proj" &&
570 test_create_commit "$subtree_test_count" main1 &&
571 test_create_commit "$subtree_test_count/sub proj" sub1 &&
572 (
573 cd "$subtree_test_count" &&
574 git fetch ./"sub proj" master &&
575 git subtree add --prefix="sub dir" FETCH_HEAD
576 ) &&
577 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
578 test_create_commit "$subtree_test_count" main2 &&
579 test_create_commit "$subtree_test_count/sub proj" sub2 &&
580 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
581 (
582 cd "$subtree_test_count" &&
583 git fetch ./"sub proj" master &&
584 git subtree merge --prefix="sub dir" FETCH_HEAD &&
585 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
586 ) &&
587 test_create_commit "$subtree_test_count/sub proj" sub3 &&
588 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
589 (
590 cd "$subtree_test_count/sub proj" &&
591 git fetch .. subproj-br &&
592 git merge FETCH_HEAD
593 ) &&
594 test_create_commit "$subtree_test_count/sub proj" sub4 &&
595 (
596 cd "$subtree_test_count" &&
597 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
598 ) &&
599 test_create_commit "$subtree_test_count" "sub dir"/main-sub4 &&
600 (
601 cd "$subtree_test_count" &&
602 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
603 ) &&
604 (
605 cd "$subtree_test_count/sub proj" &&
606 git fetch .. subproj-br &&
607 git merge FETCH_HEAD &&
608
609 chks="sub1
610sub2
611sub3
612sub4" &&
613 chks_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
614$chks
615TXT
616) &&
617 chkms="main-sub1
618main-sub2
619main-sub3
620main-sub4" &&
621 chkms_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
622$chkms
623TXT
624) &&
625 allchanges=$(git log --name-only --pretty=format:"" | sort | sed "/^$/d") &&
626 check_equal "$allchanges" "$chkms
627$chks"
628 )
629'
630
631next_test
632test_expect_success 'make sure exactly the right set of files ends up in the mainline' '
633 subtree_test_create_repo "$subtree_test_count" &&
634 subtree_test_create_repo "$subtree_test_count/sub proj" &&
635 test_create_commit "$subtree_test_count" main1 &&
636 test_create_commit "$subtree_test_count/sub proj" sub1 &&
637 (
638 cd "$subtree_test_count" &&
639 git fetch ./"sub proj" master &&
640 git subtree add --prefix="sub dir" FETCH_HEAD
641 ) &&
642 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
643 test_create_commit "$subtree_test_count" main2 &&
644 test_create_commit "$subtree_test_count/sub proj" sub2 &&
645 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
646 (
647 cd "$subtree_test_count" &&
648 git fetch ./"sub proj" master &&
649 git subtree merge --prefix="sub dir" FETCH_HEAD &&
650 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
651 ) &&
652 test_create_commit "$subtree_test_count/sub proj" sub3 &&
653 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
654 (
655 cd "$subtree_test_count/sub proj" &&
656 git fetch .. subproj-br &&
657 git merge FETCH_HEAD
658 ) &&
659 test_create_commit "$subtree_test_count/sub proj" sub4 &&
660 (
661 cd "$subtree_test_count" &&
662 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
663 ) &&
664 test_create_commit "$subtree_test_count" "sub dir"/main-sub4 &&
665 (
666 cd "$subtree_test_count" &&
667 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
668 ) &&
669 (
670 cd "$subtree_test_count/sub proj" &&
671 git fetch .. subproj-br &&
672 git merge FETCH_HEAD
673 ) &&
674 (
675 cd "$subtree_test_count" &&
676 git subtree pull --prefix="sub dir" ./"sub proj" master &&
677
678 chkm="main1
679main2" &&
680 chks="sub1
681sub2
682sub3
683sub4" &&
684 chks_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
685$chks
686TXT
687) &&
688 chkms="main-sub1
689main-sub2
690main-sub3
691main-sub4" &&
692 chkms_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
693$chkms
694TXT
695) &&
696 mainfiles=$(git ls-files) &&
697 check_equal "$mainfiles" "$chkm
698$chkms_sub
699$chks_sub"
700)
701'
702
703next_test
704test_expect_success 'make sure each filename changed exactly once in the entire history' '
705 subtree_test_create_repo "$subtree_test_count" &&
706 subtree_test_create_repo "$subtree_test_count/sub proj" &&
707 test_create_commit "$subtree_test_count" main1 &&
708 test_create_commit "$subtree_test_count/sub proj" sub1 &&
709 (
710 cd "$subtree_test_count" &&
711 git config log.date relative
712 git fetch ./"sub proj" master &&
713 git subtree add --prefix="sub dir" FETCH_HEAD
714 ) &&
715 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
716 test_create_commit "$subtree_test_count" main2 &&
717 test_create_commit "$subtree_test_count/sub proj" sub2 &&
718 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
719 (
720 cd "$subtree_test_count" &&
721 git fetch ./"sub proj" master &&
722 git subtree merge --prefix="sub dir" FETCH_HEAD &&
723 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
724 ) &&
725 test_create_commit "$subtree_test_count/sub proj" sub3 &&
726 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
727 (
728 cd "$subtree_test_count/sub proj" &&
729 git fetch .. subproj-br &&
730 git merge FETCH_HEAD
731 ) &&
732 test_create_commit "$subtree_test_count/sub proj" sub4 &&
733 (
734 cd "$subtree_test_count" &&
735 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
736 ) &&
737 test_create_commit "$subtree_test_count" "sub dir"/main-sub4 &&
738 (
739 cd "$subtree_test_count" &&
740 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
741 ) &&
742 (
743 cd "$subtree_test_count/sub proj" &&
744 git fetch .. subproj-br &&
745 git merge FETCH_HEAD
746 ) &&
747 (
748 cd "$subtree_test_count" &&
749 git subtree pull --prefix="sub dir" ./"sub proj" master &&
750
751 chkm="main1
752main2" &&
753 chks="sub1
754sub2
755sub3
756sub4" &&
757 chks_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
758$chks
759TXT
760) &&
761 chkms="main-sub1
762main-sub2
763main-sub3
764main-sub4" &&
765 chkms_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
766$chkms
767TXT
768) &&
769
770 # main-sub?? and /"sub dir"/main-sub?? both change, because those are the
771 # changes that were split into their own history. And "sub dir"/sub?? never
772 # change, since they were *only* changed in the subtree branch.
773 allchanges=$(git log --name-only --pretty=format:"" | sort | sed "/^$/d") &&
774 expected=''"$(cat <<TXT | sort
775$chkms
776$chkm
777$chks
778$chkms_sub
779TXT
780)"'' &&
781 check_equal "$allchanges" "$expected"
782 )
783'
784
785next_test
786test_expect_success 'make sure the --rejoin commits never make it into subproj' '
787 subtree_test_create_repo "$subtree_test_count" &&
788 subtree_test_create_repo "$subtree_test_count/sub proj" &&
789 test_create_commit "$subtree_test_count" main1 &&
790 test_create_commit "$subtree_test_count/sub proj" sub1 &&
791 (
792 cd "$subtree_test_count" &&
793 git fetch ./"sub proj" master &&
794 git subtree add --prefix="sub dir" FETCH_HEAD
795 ) &&
796 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
797 test_create_commit "$subtree_test_count" main2 &&
798 test_create_commit "$subtree_test_count/sub proj" sub2 &&
799 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
800 (
801 cd "$subtree_test_count" &&
802 git fetch ./"sub proj" master &&
803 git subtree merge --prefix="sub dir" FETCH_HEAD &&
804 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
805 ) &&
806 test_create_commit "$subtree_test_count/sub proj" sub3 &&
807 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
808 (
809 cd "$subtree_test_count/sub proj" &&
810 git fetch .. subproj-br &&
811 git merge FETCH_HEAD
812 ) &&
813 test_create_commit "$subtree_test_count/sub proj" sub4 &&
814 (
815 cd "$subtree_test_count" &&
816 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
817 ) &&
818 test_create_commit "$subtree_test_count" "sub dir"/main-sub4 &&
819 (
820 cd "$subtree_test_count" &&
821 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
822 ) &&
823 (
824 cd "$subtree_test_count/sub proj" &&
825 git fetch .. subproj-br &&
826 git merge FETCH_HEAD
827 ) &&
828 (
829 cd "$subtree_test_count" &&
830 git subtree pull --prefix="sub dir" ./"sub proj" master &&
831 check_equal "$(git log --pretty=format:"%s" HEAD^2 | grep -i split)" ""
832 )
833'
834
835next_test
836test_expect_success 'make sure no "git subtree" tagged commits make it into subproj' '
837 subtree_test_create_repo "$subtree_test_count" &&
838 subtree_test_create_repo "$subtree_test_count/sub proj" &&
839 test_create_commit "$subtree_test_count" main1 &&
840 test_create_commit "$subtree_test_count/sub proj" sub1 &&
841 (
842 cd "$subtree_test_count" &&
843 git fetch ./"sub proj" master &&
844 git subtree add --prefix="sub dir" FETCH_HEAD
845 ) &&
846 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
847 test_create_commit "$subtree_test_count" main2 &&
848 test_create_commit "$subtree_test_count/sub proj" sub2 &&
849 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
850 (
851 cd "$subtree_test_count" &&
852 git fetch ./"sub proj" master &&
853 git subtree merge --prefix="sub dir" FETCH_HEAD &&
854 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
855 ) &&
856 test_create_commit "$subtree_test_count/sub proj" sub3 &&
857 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
858 (
859 cd "$subtree_test_count/sub proj" &&
860 git fetch .. subproj-br &&
861 git merge FETCH_HEAD
862 ) &&
863 test_create_commit "$subtree_test_count/sub proj" sub4 &&
864 (
865 cd "$subtree_test_count" &&
866 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
867 ) &&
868 test_create_commit "$subtree_test_count" "sub dir"/main-sub4 &&
869 (
870 cd "$subtree_test_count" &&
871 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
872 ) &&
873 (
874 cd "$subtree_test_count/sub proj" &&
875 git fetch .. subproj-br &&
876 git merge FETCH_HEAD
877 ) &&
878 (
879 cd "$subtree_test_count" &&
880 git subtree pull --prefix="sub dir" ./"sub proj" master &&
881
882 # They are meaningless to subproj since one side of the merge refers to the mainline
883 check_equal "$(git log --pretty=format:"%s%n%b" HEAD^2 | grep "git-subtree.*:")" ""
884 )
885'
886
887#
888# A new set of tests
889#
890
891next_test
892test_expect_success 'make sure "git subtree split" find the correct parent' '
893 subtree_test_create_repo "$subtree_test_count" &&
894 subtree_test_create_repo "$subtree_test_count/sub proj" &&
895 test_create_commit "$subtree_test_count" main1 &&
896 test_create_commit "$subtree_test_count/sub proj" sub1 &&
897 (
898 cd "$subtree_test_count" &&
899 git fetch ./"sub proj" master &&
900 git subtree add --prefix="sub dir" FETCH_HEAD
901 ) &&
902 test_create_commit "$subtree_test_count/sub proj" sub2 &&
903 (
904 cd "$subtree_test_count" &&
905 git fetch ./"sub proj" master &&
906 git branch subproj-ref FETCH_HEAD &&
907 git subtree merge --prefix="sub dir" FETCH_HEAD
908 ) &&
909 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
910 (
911 cd "$subtree_test_count" &&
912 git subtree split --prefix="sub dir" --branch subproj-br &&
913
914 # at this point, the new commit parent should be subproj-ref, if it is
915 # not, something went wrong (the "newparent" of "master~" commit should
916 # have been sub2, but it was not, because its cache was not set to
917 # itself)
918 check_equal "$(git log --pretty=format:%P -1 subproj-br)" "$(git rev-parse subproj-ref)"
919 )
920'
921
922next_test
923test_expect_success 'split a new subtree without --onto option' '
924 subtree_test_create_repo "$subtree_test_count" &&
925 subtree_test_create_repo "$subtree_test_count/sub proj" &&
926 test_create_commit "$subtree_test_count" main1 &&
927 test_create_commit "$subtree_test_count/sub proj" sub1 &&
928 (
929 cd "$subtree_test_count" &&
930 git fetch ./"sub proj" master &&
931 git subtree add --prefix="sub dir" FETCH_HEAD
932 ) &&
933 test_create_commit "$subtree_test_count/sub proj" sub2 &&
934 (
935 cd "$subtree_test_count" &&
936 git fetch ./"sub proj" master &&
937 git subtree merge --prefix="sub dir" FETCH_HEAD
938 ) &&
939 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
940 (
941 cd "$subtree_test_count" &&
942 git subtree split --prefix="sub dir" --branch subproj-br
943 ) &&
944 mkdir "$subtree_test_count"/"sub dir2" &&
945 test_create_commit "$subtree_test_count" "sub dir2"/main-sub2 &&
946 (
947 cd "$subtree_test_count" &&
948
949 # also test that we still can split out an entirely new subtree
950 # if the parent of the first commit in the tree is not empty,
951 # then the new subtree has accidently been attached to something
952 git subtree split --prefix="sub dir2" --branch subproj2-br &&
953 check_equal "$(git log --pretty=format:%P -1 subproj2-br)" ""
954 )
955'
956
957next_test
958test_expect_success 'verify one file change per commit' '
959 subtree_test_create_repo "$subtree_test_count" &&
960 subtree_test_create_repo "$subtree_test_count/sub proj" &&
961 test_create_commit "$subtree_test_count" main1 &&
962 test_create_commit "$subtree_test_count/sub proj" sub1 &&
963 (
964 cd "$subtree_test_count" &&
965 git fetch ./"sub proj" master &&
966 git branch sub1 FETCH_HEAD &&
967 git subtree add --prefix="sub dir" sub1
968 ) &&
969 test_create_commit "$subtree_test_count/sub proj" sub2 &&
970 (
971 cd "$subtree_test_count" &&
972 git fetch ./"sub proj" master &&
973 git subtree merge --prefix="sub dir" FETCH_HEAD
974 ) &&
975 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
976 (
977 cd "$subtree_test_count" &&
978 git subtree split --prefix="sub dir" --branch subproj-br
979 ) &&
980 mkdir "$subtree_test_count"/"sub dir2" &&
981 test_create_commit "$subtree_test_count" "sub dir2"/main-sub2 &&
982 (
983 cd "$subtree_test_count" &&
984 git subtree split --prefix="sub dir2" --branch subproj2-br &&
985
986 x= &&
987 git log --pretty=format:"commit: %H" | join_commits |
988 (
989 while read commit a b; do
990 test_debug "echo Verifying commit $commit"
991 test_debug "echo a: $a"
992 test_debug "echo b: $b"
993 check_equal "$b" ""
994 x=1
995 done
996 check_equal "$x" 1
997 )
998 )
999'
1000
1001next_test
1002test_expect_success 'push split to subproj' '
1003 subtree_test_create_repo "$subtree_test_count" &&
1004 subtree_test_create_repo "$subtree_test_count/sub proj" &&
1005 test_create_commit "$subtree_test_count" main1 &&
1006 test_create_commit "$subtree_test_count/sub proj" sub1 &&
1007 (
1008 cd "$subtree_test_count" &&
1009 git fetch ./"sub proj" master &&
1010 git subtree add --prefix="sub dir" FETCH_HEAD
1011 ) &&
1012 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
1013 test_create_commit "$subtree_test_count" main2 &&
1014 test_create_commit "$subtree_test_count/sub proj" sub2 &&
1015 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
1016 (
1017 cd $subtree_test_count/"sub proj" &&
1018 git branch sub-branch-1 &&
1019 cd .. &&
1020 git fetch ./"sub proj" master &&
1021 git subtree merge --prefix="sub dir" FETCH_HEAD
1022 ) &&
1023 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
1024 (
1025 cd "$subtree_test_count" &&
1026 git subtree push ./"sub proj" --prefix "sub dir" sub-branch-1 &&
1027 cd ./"sub proj" &&
1028 git checkout sub-branch-1 &&
1029 check_equal "$(last_commit_message)" "sub dir/main-sub3"
1030 )
1031'
1032
1033#
1034# This test covers 2 cases in subtree split copy_or_skip code
1035# 1) Merges where one parent is a superset of the changes of the other
1036# parent regarding changes to the subtree, in this case the merge
1037# commit should be copied
1038# 2) Merges where only one parent operate on the subtree, and the merge
1039# commit should be skipped
1040#
1041# (1) is checked by ensuring subtree_tip is a descendent of subtree_branch
1042# (2) should have a check added (not_a_subtree_change shouldn't be present
1043# on the produced subtree)
1044#
1045# Other related cases which are not tested (or currently handled correctly)
1046# - Case (1) where there are more than 2 parents, it will sometimes correctly copy
1047# the merge, and sometimes not
1048# - Merge commit where both parents have same tree as the merge, currently
1049# will always be skipped, even if they reached that state via different
1050# set of commits.
1051#
1052
1053next_test
1054test_expect_success 'subtree descendant check' '
1055 subtree_test_create_repo "$subtree_test_count" &&
1056 test_create_commit "$subtree_test_count" folder_subtree/a &&
1057 (
1058 cd "$subtree_test_count" &&
1059 git branch branch
1060 ) &&
1061 test_create_commit "$subtree_test_count" folder_subtree/0 &&
1062 test_create_commit "$subtree_test_count" folder_subtree/b &&
1063 cherry=$(cd "$subtree_test_count"; git rev-parse HEAD) &&
1064 (
1065 cd "$subtree_test_count" &&
1066 git checkout branch
1067 ) &&
1068 test_create_commit "$subtree_test_count" commit_on_branch &&
1069 (
1070 cd "$subtree_test_count" &&
1071 git cherry-pick $cherry &&
1072 git checkout master &&
1073 git merge -m "merge should be kept on subtree" branch &&
1074 git branch no_subtree_work_branch
1075 ) &&
1076 test_create_commit "$subtree_test_count" folder_subtree/d &&
1077 (
1078 cd "$subtree_test_count" &&
1079 git checkout no_subtree_work_branch
1080 ) &&
1081 test_create_commit "$subtree_test_count" not_a_subtree_change &&
1082 (
1083 cd "$subtree_test_count" &&
1084 git checkout master &&
1085 git merge -m "merge should be skipped on subtree" no_subtree_work_branch &&
1086
1087 git subtree split --prefix folder_subtree/ --branch subtree_tip master &&
1088 git subtree split --prefix folder_subtree/ --branch subtree_branch branch &&
1089 check_equal $(git rev-list --count subtree_tip..subtree_branch) 0
1090 )
1091'
1092
1093test_done