Merge branch 'nd/remote-plural-ours-plus-theirs'
[git] / contrib / subtree / t / t7900-subtree.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2012 Avery Pennaraum
4 # Copyright (c) 2015 Alexey Shumkin
5 #
6 test_description='Basic porcelain support for subtrees
7
8 This test verifies the basic operation of the add, pull, merge
9 and split subcommands of git subtree.
10 '
11
12 TEST_DIRECTORY=$(pwd)/../../../t
13 export TEST_DIRECTORY
14
15 . ../../../t/test-lib.sh
16
17 subtree_test_create_repo()
18 {
19         test_create_repo "$1"
20         (
21                 cd $1
22                 git config log.date relative
23         )
24 }
25
26 create()
27 {
28         echo "$1" >"$1"
29         git add "$1"
30 }
31
32 check_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
44 undo()
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.
53 join_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
73 test_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
84 last_commit_message()
85 {
86         git log --pretty=format:%s -1
87 }
88
89 subtree_test_count=0
90 next_test() {
91         subtree_test_count=$(($subtree_test_count+1))
92 }
93
94 #
95 # Tests for 'git subtree add'
96 #
97
98 next_test
99 test_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
111 next_test
112 test_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
123 next_test
124 test_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
137 next_test
138 test_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
151 next_test
152 test_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
165 next_test
166 test_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
183 next_test
184 test_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
203 next_test
204 test_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
223 next_test
224 test_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
243 next_test
244 test_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
260 next_test
261 test_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
284 next_test
285 test_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
304 next_test
305 test_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
324 next_test
325 test_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
349 next_test
350 test_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
373 next_test
374 test_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
398 next_test
399 test_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
430 next_test
431 test_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
456 next_test
457 test_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
484 next_test
485 test_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
528 sub2
529 sub3
530 sub4" &&
531                 chks_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
532 $chks
533 TXT
534 ) &&
535                 chkms="main-sub1
536 main-sub2
537 main-sub3
538 main-sub4" &&
539                 chkms_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
540 $chkms
541 TXT
542 ) &&
543
544                 subfiles=$(git ls-files) &&
545                 check_equal "$subfiles" "$chkms
546 $chks"
547         )
548 '
549
550 next_test
551 test_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
594 sub2
595 sub3
596 sub4" &&
597                 chks_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
598 $chks
599 TXT
600 ) &&
601                 chkms="main-sub1
602 main-sub2
603 main-sub3
604 main-sub4" &&
605                 chkms_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
606 $chkms
607 TXT
608 ) &&
609                 allchanges=$(git log --name-only --pretty=format:"" | sort | sed "/^$/d") &&
610                 check_equal "$allchanges" "$chkms
611 $chks"
612         )
613 '
614
615 next_test
616 test_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
663 main2" &&
664                 chks="sub1
665 sub2
666 sub3
667 sub4" &&
668                 chks_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
669 $chks
670 TXT
671 ) &&
672                 chkms="main-sub1
673 main-sub2
674 main-sub3
675 main-sub4" &&
676                 chkms_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
677 $chkms
678 TXT
679 ) &&
680                 mainfiles=$(git ls-files) &&
681                 check_equal "$mainfiles" "$chkm
682 $chkms_sub
683 $chks_sub"
684 )
685 '
686
687 next_test
688 test_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
736 main2" &&
737                 chks="sub1
738 sub2
739 sub3
740 sub4" &&
741                 chks_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
742 $chks
743 TXT
744 ) &&
745                 chkms="main-sub1
746 main-sub2
747 main-sub3
748 main-sub4" &&
749                 chkms_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
750 $chkms
751 TXT
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
763 TXT
764 )"'' &&
765                 check_equal "$allchanges" "$expected"
766         )
767 '
768
769 next_test
770 test_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
819 next_test
820 test_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
875 next_test
876 test_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
906 next_test
907 test_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
941 next_test
942 test_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
985 next_test
986 test_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
1037 next_test
1038 test_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
1077 test_done