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