Merge branch 'rs/apply-avoid-over-reading' into maint
[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 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
365 next_test
366 test_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
389 next_test
390 test_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
414 next_test
415 test_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
446 next_test
447 test_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
472 next_test
473 test_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
500 next_test
501 test_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
544 sub2
545 sub3
546 sub4" &&
547                 chks_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
548 $chks
549 TXT
550 ) &&
551                 chkms="main-sub1
552 main-sub2
553 main-sub3
554 main-sub4" &&
555                 chkms_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
556 $chkms
557 TXT
558 ) &&
559
560                 subfiles=$(git ls-files) &&
561                 check_equal "$subfiles" "$chkms
562 $chks"
563         )
564 '
565
566 next_test
567 test_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
610 sub2
611 sub3
612 sub4" &&
613                 chks_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
614 $chks
615 TXT
616 ) &&
617                 chkms="main-sub1
618 main-sub2
619 main-sub3
620 main-sub4" &&
621                 chkms_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
622 $chkms
623 TXT
624 ) &&
625                 allchanges=$(git log --name-only --pretty=format:"" | sort | sed "/^$/d") &&
626                 check_equal "$allchanges" "$chkms
627 $chks"
628         )
629 '
630
631 next_test
632 test_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
679 main2" &&
680                 chks="sub1
681 sub2
682 sub3
683 sub4" &&
684                 chks_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
685 $chks
686 TXT
687 ) &&
688                 chkms="main-sub1
689 main-sub2
690 main-sub3
691 main-sub4" &&
692                 chkms_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
693 $chkms
694 TXT
695 ) &&
696                 mainfiles=$(git ls-files) &&
697                 check_equal "$mainfiles" "$chkm
698 $chkms_sub
699 $chks_sub"
700 )
701 '
702
703 next_test
704 test_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
752 main2" &&
753                 chks="sub1
754 sub2
755 sub3
756 sub4" &&
757                 chks_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
758 $chks
759 TXT
760 ) &&
761                 chkms="main-sub1
762 main-sub2
763 main-sub3
764 main-sub4" &&
765                 chkms_sub=$(cat <<TXT | sed '\''s,^,sub dir/,'\''
766 $chkms
767 TXT
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
779 TXT
780 )"'' &&
781                 check_equal "$allchanges" "$expected"
782         )
783 '
784
785 next_test
786 test_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
835 next_test
836 test_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
891 next_test
892 test_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
922 next_test
923 test_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 accidentally 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
957 next_test
958 test_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
1001 next_test
1002 test_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
1053 next_test
1054 test_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
1093 test_done