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 test_write_lines main-sub1 main-sub2 main-sub3 main-sub4 \
544 sub1 sub2 sub3 sub4 >expect &&
545 git ls-files >actual &&
546 test_cmp expect actual
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 test_write_lines main-sub1 main-sub2 main-sub3 main-sub4 \
594 sub1 sub2 sub3 sub4 >expect &&
595 git log --name-only --pretty=format:"" >log &&
596 sort <log | sed "/^\$/ d" >actual &&
597 test_cmp expect actual
598 )
599'
600
601next_test
602test_expect_success 'make sure exactly the right set of files ends up in the mainline' '
603 subtree_test_create_repo "$subtree_test_count" &&
604 subtree_test_create_repo "$subtree_test_count/sub proj" &&
605 test_create_commit "$subtree_test_count" main1 &&
606 test_create_commit "$subtree_test_count/sub proj" sub1 &&
607 (
608 cd "$subtree_test_count" &&
609 git fetch ./"sub proj" master &&
610 git subtree add --prefix="sub dir" FETCH_HEAD
611 ) &&
612 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
613 test_create_commit "$subtree_test_count" main2 &&
614 test_create_commit "$subtree_test_count/sub proj" sub2 &&
615 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
616 (
617 cd "$subtree_test_count" &&
618 git fetch ./"sub proj" master &&
619 git subtree merge --prefix="sub dir" FETCH_HEAD &&
620 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
621 ) &&
622 test_create_commit "$subtree_test_count/sub proj" sub3 &&
623 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
624 (
625 cd "$subtree_test_count/sub proj" &&
626 git fetch .. subproj-br &&
627 git merge FETCH_HEAD
628 ) &&
629 test_create_commit "$subtree_test_count/sub proj" sub4 &&
630 (
631 cd "$subtree_test_count" &&
632 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
633 ) &&
634 test_create_commit "$subtree_test_count" "sub dir"/main-sub4 &&
635 (
636 cd "$subtree_test_count" &&
637 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
638 ) &&
639 (
640 cd "$subtree_test_count/sub proj" &&
641 git fetch .. subproj-br &&
642 git merge FETCH_HEAD
643 ) &&
644 (
645 cd "$subtree_test_count" &&
646 git subtree pull --prefix="sub dir" ./"sub proj" master &&
647
648 test_write_lines main1 main2 >chkm &&
649 test_write_lines main-sub1 main-sub2 main-sub3 main-sub4 >chkms &&
650 sed "s,^,sub dir/," chkms >chkms_sub &&
651 test_write_lines sub1 sub2 sub3 sub4 >chks &&
652 sed "s,^,sub dir/," chks >chks_sub &&
653
654 cat chkm chkms_sub chks_sub >expect &&
655 git ls-files >actual &&
656 test_cmp expect actual
657 )
658'
659
660next_test
661test_expect_success 'make sure each filename changed exactly once in the entire history' '
662 subtree_test_create_repo "$subtree_test_count" &&
663 subtree_test_create_repo "$subtree_test_count/sub proj" &&
664 test_create_commit "$subtree_test_count" main1 &&
665 test_create_commit "$subtree_test_count/sub proj" sub1 &&
666 (
667 cd "$subtree_test_count" &&
668 git config log.date relative &&
669 git fetch ./"sub proj" master &&
670 git subtree add --prefix="sub dir" FETCH_HEAD
671 ) &&
672 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
673 test_create_commit "$subtree_test_count" main2 &&
674 test_create_commit "$subtree_test_count/sub proj" sub2 &&
675 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
676 (
677 cd "$subtree_test_count" &&
678 git fetch ./"sub proj" master &&
679 git subtree merge --prefix="sub dir" FETCH_HEAD &&
680 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
681 ) &&
682 test_create_commit "$subtree_test_count/sub proj" sub3 &&
683 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
684 (
685 cd "$subtree_test_count/sub proj" &&
686 git fetch .. subproj-br &&
687 git merge FETCH_HEAD
688 ) &&
689 test_create_commit "$subtree_test_count/sub proj" sub4 &&
690 (
691 cd "$subtree_test_count" &&
692 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
693 ) &&
694 test_create_commit "$subtree_test_count" "sub dir"/main-sub4 &&
695 (
696 cd "$subtree_test_count" &&
697 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
698 ) &&
699 (
700 cd "$subtree_test_count/sub proj" &&
701 git fetch .. subproj-br &&
702 git merge FETCH_HEAD
703 ) &&
704 (
705 cd "$subtree_test_count" &&
706 git subtree pull --prefix="sub dir" ./"sub proj" master &&
707
708 test_write_lines main1 main2 >chkm &&
709 test_write_lines sub1 sub2 sub3 sub4 >chks &&
710 test_write_lines main-sub1 main-sub2 main-sub3 main-sub4 >chkms &&
711 sed "s,^,sub dir/," chkms >chkms_sub &&
712
713 # main-sub?? and /"sub dir"/main-sub?? both change, because those are the
714 # changes that were split into their own history. And "sub dir"/sub?? never
715 # change, since they were *only* changed in the subtree branch.
716 git log --name-only --pretty=format:"" >log &&
717 sort <log >sorted-log &&
718 sed "/^$/ d" sorted-log >actual &&
719
720 cat chkms chkm chks chkms_sub >expect-unsorted &&
721 sort expect-unsorted >expect &&
722 test_cmp expect actual
723 )
724'
725
726next_test
727test_expect_success 'make sure the --rejoin commits never make it into subproj' '
728 subtree_test_create_repo "$subtree_test_count" &&
729 subtree_test_create_repo "$subtree_test_count/sub proj" &&
730 test_create_commit "$subtree_test_count" main1 &&
731 test_create_commit "$subtree_test_count/sub proj" sub1 &&
732 (
733 cd "$subtree_test_count" &&
734 git fetch ./"sub proj" master &&
735 git subtree add --prefix="sub dir" FETCH_HEAD
736 ) &&
737 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
738 test_create_commit "$subtree_test_count" main2 &&
739 test_create_commit "$subtree_test_count/sub proj" sub2 &&
740 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
741 (
742 cd "$subtree_test_count" &&
743 git fetch ./"sub proj" master &&
744 git subtree merge --prefix="sub dir" FETCH_HEAD &&
745 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
746 ) &&
747 test_create_commit "$subtree_test_count/sub proj" sub3 &&
748 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
749 (
750 cd "$subtree_test_count/sub proj" &&
751 git fetch .. subproj-br &&
752 git merge FETCH_HEAD
753 ) &&
754 test_create_commit "$subtree_test_count/sub proj" sub4 &&
755 (
756 cd "$subtree_test_count" &&
757 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
758 ) &&
759 test_create_commit "$subtree_test_count" "sub dir"/main-sub4 &&
760 (
761 cd "$subtree_test_count" &&
762 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
763 ) &&
764 (
765 cd "$subtree_test_count/sub proj" &&
766 git fetch .. subproj-br &&
767 git merge FETCH_HEAD
768 ) &&
769 (
770 cd "$subtree_test_count" &&
771 git subtree pull --prefix="sub dir" ./"sub proj" master &&
772 check_equal "$(git log --pretty=format:"%s" HEAD^2 | grep -i split)" ""
773 )
774'
775
776next_test
777test_expect_success 'make sure no "git subtree" tagged commits make it into subproj' '
778 subtree_test_create_repo "$subtree_test_count" &&
779 subtree_test_create_repo "$subtree_test_count/sub proj" &&
780 test_create_commit "$subtree_test_count" main1 &&
781 test_create_commit "$subtree_test_count/sub proj" sub1 &&
782 (
783 cd "$subtree_test_count" &&
784 git fetch ./"sub proj" master &&
785 git subtree add --prefix="sub dir" FETCH_HEAD
786 ) &&
787 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
788 test_create_commit "$subtree_test_count" main2 &&
789 test_create_commit "$subtree_test_count/sub proj" sub2 &&
790 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
791 (
792 cd "$subtree_test_count" &&
793 git fetch ./"sub proj" master &&
794 git subtree merge --prefix="sub dir" FETCH_HEAD &&
795 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
796 ) &&
797 test_create_commit "$subtree_test_count/sub proj" sub3 &&
798 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
799 (
800 cd "$subtree_test_count/sub proj" &&
801 git fetch .. subproj-br &&
802 git merge FETCH_HEAD
803 ) &&
804 test_create_commit "$subtree_test_count/sub proj" sub4 &&
805 (
806 cd "$subtree_test_count" &&
807 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
808 ) &&
809 test_create_commit "$subtree_test_count" "sub dir"/main-sub4 &&
810 (
811 cd "$subtree_test_count" &&
812 git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
813 ) &&
814 (
815 cd "$subtree_test_count/sub proj" &&
816 git fetch .. subproj-br &&
817 git merge FETCH_HEAD
818 ) &&
819 (
820 cd "$subtree_test_count" &&
821 git subtree pull --prefix="sub dir" ./"sub proj" master &&
822
823 # They are meaningless to subproj since one side of the merge refers to the mainline
824 check_equal "$(git log --pretty=format:"%s%n%b" HEAD^2 | grep "git-subtree.*:")" ""
825 )
826'
827
828#
829# A new set of tests
830#
831
832next_test
833test_expect_success 'make sure "git subtree split" find the correct parent' '
834 subtree_test_create_repo "$subtree_test_count" &&
835 subtree_test_create_repo "$subtree_test_count/sub proj" &&
836 test_create_commit "$subtree_test_count" main1 &&
837 test_create_commit "$subtree_test_count/sub proj" sub1 &&
838 (
839 cd "$subtree_test_count" &&
840 git fetch ./"sub proj" master &&
841 git subtree add --prefix="sub dir" FETCH_HEAD
842 ) &&
843 test_create_commit "$subtree_test_count/sub proj" sub2 &&
844 (
845 cd "$subtree_test_count" &&
846 git fetch ./"sub proj" master &&
847 git branch subproj-ref FETCH_HEAD &&
848 git subtree merge --prefix="sub dir" FETCH_HEAD
849 ) &&
850 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
851 (
852 cd "$subtree_test_count" &&
853 git subtree split --prefix="sub dir" --branch subproj-br &&
854
855 # at this point, the new commit parent should be subproj-ref, if it is
856 # not, something went wrong (the "newparent" of "master~" commit should
857 # have been sub2, but it was not, because its cache was not set to
858 # itself)
859 check_equal "$(git log --pretty=format:%P -1 subproj-br)" "$(git rev-parse subproj-ref)"
860 )
861'
862
863next_test
864test_expect_success 'split a new subtree without --onto option' '
865 subtree_test_create_repo "$subtree_test_count" &&
866 subtree_test_create_repo "$subtree_test_count/sub proj" &&
867 test_create_commit "$subtree_test_count" main1 &&
868 test_create_commit "$subtree_test_count/sub proj" sub1 &&
869 (
870 cd "$subtree_test_count" &&
871 git fetch ./"sub proj" master &&
872 git subtree add --prefix="sub dir" FETCH_HEAD
873 ) &&
874 test_create_commit "$subtree_test_count/sub proj" sub2 &&
875 (
876 cd "$subtree_test_count" &&
877 git fetch ./"sub proj" master &&
878 git subtree merge --prefix="sub dir" FETCH_HEAD
879 ) &&
880 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
881 (
882 cd "$subtree_test_count" &&
883 git subtree split --prefix="sub dir" --branch subproj-br
884 ) &&
885 mkdir "$subtree_test_count"/"sub dir2" &&
886 test_create_commit "$subtree_test_count" "sub dir2"/main-sub2 &&
887 (
888 cd "$subtree_test_count" &&
889
890 # also test that we still can split out an entirely new subtree
891 # if the parent of the first commit in the tree is not empty,
892 # then the new subtree has accidentally been attached to something
893 git subtree split --prefix="sub dir2" --branch subproj2-br &&
894 check_equal "$(git log --pretty=format:%P -1 subproj2-br)" ""
895 )
896'
897
898next_test
899test_expect_success 'verify one file change per commit' '
900 subtree_test_create_repo "$subtree_test_count" &&
901 subtree_test_create_repo "$subtree_test_count/sub proj" &&
902 test_create_commit "$subtree_test_count" main1 &&
903 test_create_commit "$subtree_test_count/sub proj" sub1 &&
904 (
905 cd "$subtree_test_count" &&
906 git fetch ./"sub proj" master &&
907 git branch sub1 FETCH_HEAD &&
908 git subtree add --prefix="sub dir" sub1
909 ) &&
910 test_create_commit "$subtree_test_count/sub proj" sub2 &&
911 (
912 cd "$subtree_test_count" &&
913 git fetch ./"sub proj" master &&
914 git subtree merge --prefix="sub dir" FETCH_HEAD
915 ) &&
916 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
917 (
918 cd "$subtree_test_count" &&
919 git subtree split --prefix="sub dir" --branch subproj-br
920 ) &&
921 mkdir "$subtree_test_count"/"sub dir2" &&
922 test_create_commit "$subtree_test_count" "sub dir2"/main-sub2 &&
923 (
924 cd "$subtree_test_count" &&
925 git subtree split --prefix="sub dir2" --branch subproj2-br &&
926
927 x= &&
928 git log --pretty=format:"commit: %H" | join_commits |
929 (
930 while read commit a b; do
931 test_debug "echo Verifying commit $commit"
932 test_debug "echo a: $a"
933 test_debug "echo b: $b"
934 check_equal "$b" ""
935 x=1
936 done
937 check_equal "$x" 1
938 )
939 )
940'
941
942next_test
943test_expect_success 'push split to subproj' '
944 subtree_test_create_repo "$subtree_test_count" &&
945 subtree_test_create_repo "$subtree_test_count/sub proj" &&
946 test_create_commit "$subtree_test_count" main1 &&
947 test_create_commit "$subtree_test_count/sub proj" sub1 &&
948 (
949 cd "$subtree_test_count" &&
950 git fetch ./"sub proj" master &&
951 git subtree add --prefix="sub dir" FETCH_HEAD
952 ) &&
953 test_create_commit "$subtree_test_count" "sub dir"/main-sub1 &&
954 test_create_commit "$subtree_test_count" main2 &&
955 test_create_commit "$subtree_test_count/sub proj" sub2 &&
956 test_create_commit "$subtree_test_count" "sub dir"/main-sub2 &&
957 (
958 cd $subtree_test_count/"sub proj" &&
959 git branch sub-branch-1 &&
960 cd .. &&
961 git fetch ./"sub proj" master &&
962 git subtree merge --prefix="sub dir" FETCH_HEAD
963 ) &&
964 test_create_commit "$subtree_test_count" "sub dir"/main-sub3 &&
965 (
966 cd "$subtree_test_count" &&
967 git subtree push ./"sub proj" --prefix "sub dir" sub-branch-1 &&
968 cd ./"sub proj" &&
969 git checkout sub-branch-1 &&
970 check_equal "$(last_commit_message)" "sub dir/main-sub3"
971 )
972'
973
974#
975# This test covers 2 cases in subtree split copy_or_skip code
976# 1) Merges where one parent is a superset of the changes of the other
977# parent regarding changes to the subtree, in this case the merge
978# commit should be copied
979# 2) Merges where only one parent operate on the subtree, and the merge
980# commit should be skipped
981#
982# (1) is checked by ensuring subtree_tip is a descendent of subtree_branch
983# (2) should have a check added (not_a_subtree_change shouldn't be present
984# on the produced subtree)
985#
986# Other related cases which are not tested (or currently handled correctly)
987# - Case (1) where there are more than 2 parents, it will sometimes correctly copy
988# the merge, and sometimes not
989# - Merge commit where both parents have same tree as the merge, currently
990# will always be skipped, even if they reached that state via different
991# set of commits.
992#
993
994next_test
995test_expect_success 'subtree descendant check' '
996 subtree_test_create_repo "$subtree_test_count" &&
997 test_create_commit "$subtree_test_count" folder_subtree/a &&
998 (
999 cd "$subtree_test_count" &&
1000 git branch branch
1001 ) &&
1002 test_create_commit "$subtree_test_count" folder_subtree/0 &&
1003 test_create_commit "$subtree_test_count" folder_subtree/b &&
1004 cherry=$(cd "$subtree_test_count"; git rev-parse HEAD) &&
1005 (
1006 cd "$subtree_test_count" &&
1007 git checkout branch
1008 ) &&
1009 test_create_commit "$subtree_test_count" commit_on_branch &&
1010 (
1011 cd "$subtree_test_count" &&
1012 git cherry-pick $cherry &&
1013 git checkout master &&
1014 git merge -m "merge should be kept on subtree" branch &&
1015 git branch no_subtree_work_branch
1016 ) &&
1017 test_create_commit "$subtree_test_count" folder_subtree/d &&
1018 (
1019 cd "$subtree_test_count" &&
1020 git checkout no_subtree_work_branch
1021 ) &&
1022 test_create_commit "$subtree_test_count" not_a_subtree_change &&
1023 (
1024 cd "$subtree_test_count" &&
1025 git checkout master &&
1026 git merge -m "merge should be skipped on subtree" no_subtree_work_branch &&
1027
1028 git subtree split --prefix folder_subtree/ --branch subtree_tip master &&
1029 git subtree split --prefix folder_subtree/ --branch subtree_branch branch &&
1030 check_equal $(git rev-list --count subtree_tip..subtree_branch) 0
1031 )
1032'
1033
1034test_done