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