#!/bin/sh # # Copyright (c) 2012 Avery Pennaraum # Copyright (c) 2015 Alexey Shumkin # global test_description := ''Basic porcelain support for subtrees This test verifies the basic operation of the add, pull, merge and split subcommands of git subtree. '' global TEST_DIRECTORY := "$[pwd]/../../../t" export TEST_DIRECTORY source ../../../t/test-lib.sh proc subtree_test_create_repo { test_create_repo $1 && shell { cd $1 && git config log.date relative } } proc create { echo $1 >$1 && git add $1 } proc check_equal { test_debug 'echo' test_debug "echo \"check a:\" \"{$1}\"" test_debug "echo \" b:\" \"{$2}\"" if test $1 = $2 { return 0 } else { return 1 } } proc undo { git reset --hard HEAD~ } # Make sure no patch changes more than one file. # The original set of commits changed only one file each. # A multi-file change would imply that we pruned commits # too aggressively. proc join_commits { global commit := '' global all := '' while read x y { if test -z $x { continue } elif test $x = "commit:" { if test -n $commit { echo "$commit $all" global all := '' } global commit := $y } else { global all := ""$all $y"" } } echo "$commit $all" } proc test_create_commit ( repo=$1 && commit=$2 && cd "$repo" && mkdir -p "$(dirname "$commit")" \ || error "Could not create directory for commit" echo "$commit" >"$commit" && git add "$commit" || error "Could not add commit" git commit -m "$commit" || error "Could not commit" ) proc last_commit_message { git log --pretty=format:%s -1 } global subtree_test_count := '0' proc next_test { global subtree_test_count := $($subtree_test_count+1) } # # Tests for 'git subtree add' # next_test test_expect_success 'no merge from non-existent subtree' ' subtree_test_create_repo "$subtree_test_count" && subtree_test_create_repo "$subtree_test_count/sub proj" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && test_must_fail git subtree merge --prefix="sub dir" FETCH_HEAD ) ' next_test test_expect_success 'no pull from non-existent subtree' ' subtree_test_create_repo "$subtree_test_count" && subtree_test_create_repo "$subtree_test_count/sub proj" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && test_must_fail git subtree pull --prefix="sub dir" ./"sub proj" master )' next_test test_expect_success 'add subproj as subtree into sub dir/ with --prefix' ' subtree_test_create_repo "$subtree_test_count" && subtree_test_create_repo "$subtree_test_count/sub proj" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree add --prefix="sub dir" FETCH_HEAD && check_equal "$(last_commit_message)" "Add '''''sub dir/''''' from commit '''''$(git rev-parse FETCH_HEAD)'''''" ) ' next_test test_expect_success 'add subproj as subtree into sub dir/ with --prefix and --message' ' subtree_test_create_repo "$subtree_test_count" && subtree_test_create_repo "$subtree_test_count/sub proj" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree add --prefix="sub dir" --message="Added subproject" FETCH_HEAD && check_equal "$(last_commit_message)" "Added subproject" ) ' next_test test_expect_success 'add subproj as subtree into sub dir/ with --prefix as -P and --message as -m' ' subtree_test_create_repo "$subtree_test_count" && subtree_test_create_repo "$subtree_test_count/sub proj" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree add -P "sub dir" -m "Added subproject" FETCH_HEAD && check_equal "$(last_commit_message)" "Added subproject" ) ' next_test test_expect_success 'add subproj as subtree into sub dir/ with --squash and --prefix and --message' ' subtree_test_create_repo "$subtree_test_count" && subtree_test_create_repo "$subtree_test_count/sub proj" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree add --prefix="sub dir" --message="Added subproject with squash" --squash FETCH_HEAD && check_equal "$(last_commit_message)" "Added subproject with squash" ) ' # # Tests for 'git subtree merge' # next_test test_expect_success 'merge new subproj history into sub dir/ with --prefix' ' subtree_test_create_repo "$subtree_test_count" && subtree_test_create_repo "$subtree_test_count/sub proj" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree add --prefix="sub dir" FETCH_HEAD ) && test_create_commit "$subtree_test_count/sub proj" sub2 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && check_equal "$(last_commit_message)" "Merge commit '''''$(git rev-parse FETCH_HEAD)'''''" ) ' next_test test_expect_success 'merge new subproj history into sub dir/ with --prefix and --message' ' subtree_test_create_repo "$subtree_test_count" && subtree_test_create_repo "$subtree_test_count/sub proj" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree add --prefix="sub dir" FETCH_HEAD ) && test_create_commit "$subtree_test_count/sub proj" sub2 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" --message="Merged changes from subproject" FETCH_HEAD && check_equal "$(last_commit_message)" "Merged changes from subproject" ) ' next_test test_expect_success 'merge new subproj history into sub dir/ with --squash and --prefix and --message' ' subtree_test_create_repo "$subtree_test_count/sub proj" && subtree_test_create_repo "$subtree_test_count" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree add --prefix="sub dir" FETCH_HEAD ) && test_create_commit "$subtree_test_count/sub proj" sub2 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" --message="Merged changes from subproject using squash" --squash FETCH_HEAD && check_equal "$(last_commit_message)" "Merged changes from subproject using squash" ) ' next_test test_expect_success 'merge the added subproj again, should do nothing' ' subtree_test_create_repo "$subtree_test_count" && subtree_test_create_repo "$subtree_test_count/sub proj" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree add --prefix="sub dir" FETCH_HEAD && # this shouldn not actually do anything, since FETCH_HEAD # is already a parent result=$(git merge -s ours -m "merge -s -ours" FETCH_HEAD) && check_equal "${result}" "Already up-to-date." ) ' next_test test_expect_success 'merge new subproj history into subdir/ with a slash appended to the argument of --prefix' ' test_create_repo "$test_count" && test_create_repo "$test_count/subproj" && test_create_commit "$test_count" main1 && test_create_commit "$test_count/subproj" sub1 && ( cd "$test_count" && git fetch ./subproj master && git subtree add --prefix=subdir/ FETCH_HEAD ) && test_create_commit "$test_count/subproj" sub2 && ( cd "$test_count" && git fetch ./subproj master && git subtree merge --prefix=subdir/ FETCH_HEAD && check_equal "$(last_commit_message)" "Merge commit '''''$(git rev-parse FETCH_HEAD)'''''" ) ' # # Tests for 'git subtree split' # next_test test_expect_success 'split requires option --prefix' ' subtree_test_create_repo "$subtree_test_count" && subtree_test_create_repo "$subtree_test_count/sub proj" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree add --prefix="sub dir" FETCH_HEAD && echo "You must provide the --prefix option." > expected && test_must_fail git subtree split > actual 2>&1 && test_debug "printf '"expected: "'" && test_debug "cat expected" && test_debug "printf '"actual: "'" && test_debug "cat actual" && test_cmp expected actual ) ' next_test test_expect_success 'split requires path given by option --prefix must exist' ' subtree_test_create_repo "$subtree_test_count" && subtree_test_create_repo "$subtree_test_count/sub proj" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree add --prefix="sub dir" FETCH_HEAD && echo "'''''non-existent-directory''''' does not exist; use '''''git subtree add'''''" > expected && test_must_fail git subtree split --prefix=non-existent-directory > actual 2>&1 && test_debug "printf '"expected: "'" && test_debug "cat expected" && test_debug "printf '"actual: "'" && test_debug "cat actual" && test_cmp expected actual ) ' next_test test_expect_success 'split sub dir/ with --rejoin' ' subtree_test_create_repo "$subtree_test_count" && subtree_test_create_repo "$subtree_test_count/sub proj" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree add --prefix="sub dir" FETCH_HEAD ) && test_create_commit "$subtree_test_count" "sub dir"/main-sub1 && test_create_commit "$subtree_test_count" main2 && test_create_commit "$subtree_test_count/sub proj" sub2 && test_create_commit "$subtree_test_count" "sub dir"/main-sub2 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && split_hash=$(git subtree split --prefix="sub dir" --annotate="*") && git subtree split --prefix="sub dir" --annotate="*" --rejoin && check_equal "$(last_commit_message)" "Split '''''sub dir/''''' into commit '''''$split_hash'''''" ) ' next_test test_expect_success 'split sub dir/ with --rejoin from scratch' ' subtree_test_create_repo "$subtree_test_count" && test_create_commit "$subtree_test_count" main1 && ( cd "$subtree_test_count" && mkdir "sub dir" && echo file >"sub dir"/file && git add "sub dir/file" && git commit -m"sub dir file" && split_hash=$(git subtree split --prefix="sub dir" --rejoin) && git subtree split --prefix="sub dir" --rejoin && check_equal "$(last_commit_message)" "Split '''''sub dir/''''' into commit '''''$split_hash'''''" ) ' next_test test_expect_success 'split sub dir/ with --rejoin and --message' ' subtree_test_create_repo "$subtree_test_count" && subtree_test_create_repo "$subtree_test_count/sub proj" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree add --prefix="sub dir" FETCH_HEAD ) && test_create_commit "$subtree_test_count" "sub dir"/main-sub1 && test_create_commit "$subtree_test_count" main2 && test_create_commit "$subtree_test_count/sub proj" sub2 && test_create_commit "$subtree_test_count" "sub dir"/main-sub2 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && git subtree split --prefix="sub dir" --message="Split & rejoin" --annotate="*" --rejoin && check_equal "$(last_commit_message)" "Split & rejoin" ) ' next_test test_expect_success 'split "sub dir"/ with --branch' ' subtree_test_create_repo "$subtree_test_count" && subtree_test_create_repo "$subtree_test_count/sub proj" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree add --prefix="sub dir" FETCH_HEAD ) && test_create_commit "$subtree_test_count" "sub dir"/main-sub1 && test_create_commit "$subtree_test_count" main2 && test_create_commit "$subtree_test_count/sub proj" sub2 && test_create_commit "$subtree_test_count" "sub dir"/main-sub2 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && split_hash=$(git subtree split --prefix="sub dir" --annotate="*") && git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br && check_equal "$(git rev-parse subproj-br)" "$split_hash" ) ' next_test test_expect_success 'check hash of split' ' subtree_test_create_repo "$subtree_test_count" && subtree_test_create_repo "$subtree_test_count/sub proj" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree add --prefix="sub dir" FETCH_HEAD ) && test_create_commit "$subtree_test_count" "sub dir"/main-sub1 && test_create_commit "$subtree_test_count" main2 && test_create_commit "$subtree_test_count/sub proj" sub2 && test_create_commit "$subtree_test_count" "sub dir"/main-sub2 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && split_hash=$(git subtree split --prefix="sub dir" --annotate="*") && git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br && check_equal "$(git rev-parse subproj-br)" "$split_hash" && # Check hash of split new_hash=$(git rev-parse subproj-br^2) && ( cd ./"sub proj" && subdir_hash=$(git rev-parse HEAD) && check_equal ''"$new_hash"'' "$subdir_hash" ) ) ' next_test test_expect_success 'split "sub dir"/ with --branch for an existing branch' ' subtree_test_create_repo "$subtree_test_count" && subtree_test_create_repo "$subtree_test_count/sub proj" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git branch subproj-br FETCH_HEAD && git subtree add --prefix="sub dir" FETCH_HEAD ) && test_create_commit "$subtree_test_count" "sub dir"/main-sub1 && test_create_commit "$subtree_test_count" main2 && test_create_commit "$subtree_test_count/sub proj" sub2 && test_create_commit "$subtree_test_count" "sub dir"/main-sub2 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && split_hash=$(git subtree split --prefix="sub dir" --annotate="*") && git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br && check_equal "$(git rev-parse subproj-br)" "$split_hash" ) ' next_test test_expect_success 'split "sub dir"/ with --branch for an incompatible branch' ' subtree_test_create_repo "$subtree_test_count" && subtree_test_create_repo "$subtree_test_count/sub proj" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git branch init HEAD && git fetch ./"sub proj" master && git subtree add --prefix="sub dir" FETCH_HEAD ) && test_create_commit "$subtree_test_count" "sub dir"/main-sub1 && test_create_commit "$subtree_test_count" main2 && test_create_commit "$subtree_test_count/sub proj" sub2 && test_create_commit "$subtree_test_count" "sub dir"/main-sub2 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && test_must_fail git subtree split --prefix="sub dir" --branch init ) ' # # Validity checking # next_test test_expect_success 'make sure exactly the right set of files ends up in the subproj' ' subtree_test_create_repo "$subtree_test_count" && subtree_test_create_repo "$subtree_test_count/sub proj" && test_create_commit "$subtree_test_count" main1 && test_create_commit "$subtree_test_count/sub proj" sub1 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree add --prefix="sub dir" FETCH_HEAD ) && test_create_commit "$subtree_test_count" "sub dir"/main-sub1 && test_create_commit "$subtree_test_count" main2 && test_create_commit "$subtree_test_count/sub proj" sub2 && test_create_commit "$subtree_test_count" "sub dir"/main-sub2 && ( cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin ) && test_create_commit "$subtree_test_count/sub proj" sub3 && test_create_commit "$subtree_test_count" "sub dir"/main-sub3 && ( cd "$subtree_test_count/sub proj" && git fetch .. subproj-br && git merge FETCH_HEAD ) && test_create_commit "$subtree_test_count/sub proj" sub4 && ( cd "$subtree_test_count" && git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin ) && test_create_commit "$subtree_test_count" "sub dir"/main-sub4 && ( cd "$subtree_test_count" && git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin ) && ( cd "$subtree_test_count/sub proj" && git fetch .. subproj-br && git merge FETCH_HEAD && chks="sub1 sub2 sub3 sub4" && chks_sub=$(cat < <"\n"> <"This test verifies the basic operation of the add, pull, merge\n"> <"and split subcommands of git subtree.\n"> ) } spids: [15] ) ] spids: [15] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:TEST_DIRECTORY) op: Equal rhs: { (CommandSubPart command_list: (CommandList children:[(C {(pwd)})]) left_token: spids: [25 27] ) (/../../../t) } spids: [24] ) ] spids: [24] ) (C {(export)} {(TEST_DIRECTORY)}) (C {(.)} {(../../../t/test-lib.sh)}) (FuncDef name: subtree_test_create_repo body: (BraceGroup children: [ (AndOr children: [ (C {(test_create_repo)} {(DQ ($ VSub_Number "$1"))}) (Subshell child: (AndOr children: [ (C {(cd)} {(DQ ($ VSub_Number "$1"))}) (C {(git)} {(config)} {(log.date)} {(relative)}) ] op_id: Op_DAmp ) spids: [56 77] ) ] op_id: Op_DAmp ) ] spids: [44] ) spids: [40 43] ) (FuncDef name: create body: (BraceGroup children: [ (AndOr children: [ (SimpleCommand words: [{(echo)} {(DQ ($ VSub_Number "$1"))}] redirects: [ (Redir op_id: Redir_Great fd: -1 arg_word: {(DQ ($ VSub_Number "$1"))} spids: [95] ) ] ) (C {(git)} {(add)} {(DQ ($ VSub_Number "$1"))}) ] op_id: Op_DAmp ) ] spids: [86] ) spids: [82 85] ) (FuncDef name: check_equal body: (BraceGroup children: [ (C {(test_debug)} {(SQ )}) (C {(test_debug)} { (DQ ("echo ") (EscapedLiteralPart token:) ("check a:") (EscapedLiteralPart token:) (" ") (EscapedLiteralPart token:) ("{") ($ VSub_Number "$1") ("}") (EscapedLiteralPart token:) ) } ) (C {(test_debug)} { (DQ ("echo ") (EscapedLiteralPart token:) (" b:") (EscapedLiteralPart token:) (" ") (EscapedLiteralPart token:) ("{") ($ VSub_Number "$2") ("}") (EscapedLiteralPart token:) ) } ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(DQ ($ VSub_Number "$1"))} {(Lit_Other "=")} {(DQ ($ VSub_Number "$2"))} {(Lit_Other "]")} ) terminator: ) ] action: [(ControlFlow token: arg_word:{(0)})] spids: [-1 177] ) ] else_action: [(ControlFlow token: arg_word:{(1)})] spids: [185 193] ) ] spids: [118] ) spids: [114 117] ) (FuncDef name: undo body: (BraceGroup children: [(C {(git)} {(reset)} {(--hard)} {(HEAD) (Lit_Tilde "~")})] spids: [202] ) spids: [198 201] ) (FuncDef name: join_commits body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:commit) op:Equal rhs:{(SQ )} spids:[236])] spids: [236] ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:all) op:Equal rhs:{(SQ )} spids:[239])] spids: [239] ) (While cond: [(Sentence child:(C {(read)} {(x)} {(y)}) terminator:)] body: (DoGroup children: [ (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-z)} {(DQ ($ VSub_Name "$x"))} {(Lit_Other "]")}) terminator: ) ] action: [(ControlFlow token:)] spids: [-1 267] ) (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(DQ ($ VSub_Name "$x"))} {(Lit_Other "=")} {(DQ ("commit:"))} {(Lit_Other "]")} ) terminator: ) ] action: [ (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-n)} {(DQ ($ VSub_Name "$commit"))} {(Lit_Other "]")} ) terminator: ) ] action: [ (C {(echo)} {(DQ ($ VSub_Name "$commit") (" ") ($ VSub_Name "$all"))} ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:all) op: Equal rhs: {(SQ )} spids: [318] ) ] spids: [318] ) ] spids: [-1 306] ) ] spids: [-1 321] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:commit) op: Equal rhs: {(DQ ($ VSub_Name "$y"))} spids: [324] ) ] spids: [324] ) ] spids: [273 290] ) ] else_action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:all) op: Equal rhs: {(DQ ($ VSub_Name "$all") (" ") ($ VSub_Name "$y"))} spids: [333] ) ] spids: [333] ) ] spids: [330 341] ) ] spids: [251 344] ) ) (C {(echo)} {(DQ ($ VSub_Name "$commit") (" ") ($ VSub_Name "$all"))}) ] spids: [233] ) spids: [229 232] ) (FuncDef name: test_create_commit body: (Subshell child: (CommandList children: [ (AndOr children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:repo) op: Equal rhs: {($ VSub_Number "$1")} spids: [365] ) ] spids: [365] ) (AndOr children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:commit) op: Equal rhs: {($ VSub_Number "$2")} spids: [371] ) ] spids: [371] ) (AndOr children: [ (C {(cd)} {(DQ ($ VSub_Name "$repo"))}) (AndOr children: [ (C {(mkdir)} {(-p)} { (DQ (CommandSubPart command_list: (CommandList children: [(C {(dirname)} {(DQ ($ VSub_Name "$commit"))})] ) left_token: spids: [391 397] ) ) } ) (C {(error)} {(DQ ("Could not create directory for commit"))}) ] op_id: Op_DPipe ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) (AndOr children: [ (SimpleCommand words: [{(echo)} {(DQ ($ VSub_Name "$commit"))}] redirects: [ (Redir op_id: Redir_Great fd: -1 arg_word: {(DQ ($ VSub_Name "$commit"))} spids: [417] ) ] ) (AndOr children: [ (C {(git)} {(add)} {(DQ ($ VSub_Name "$commit"))}) (C {(error)} {(DQ ("Could not add commit"))}) ] op_id: Op_DPipe ) ] op_id: Op_DAmp ) (AndOr children: [ (C {(git)} {(commit)} {(-m)} {(DQ ($ VSub_Name "$commit"))}) (C {(error)} {(DQ ("Could not commit"))}) ] op_id: Op_DPipe ) ] ) spids: [362 460] ) spids: [358 361] ) (FuncDef name: last_commit_message body: (BraceGroup children: [ (C {(git)} {(log)} {(--pretty) (Lit_Other "=") (format) (Lit_Other ":") (Lit_Other "%") (s)} {(-1)} ) ] spids: [467] ) spids: [463 466] ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:subtree_test_count) op:Equal rhs:{(0)} spids:[486])] spids: [486] ) (FuncDef name: next_test body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:subtree_test_count) op: Equal rhs: { (ArithSubPart anode: (ArithBinary op_id: Arith_Plus left: (ArithWord w:{($ VSub_Name "$subtree_test_count")}) right: (ArithWord w:{(Lit_Digits 1)}) ) spids: [497 502] ) } spids: [496] ) ] spids: [496] ) ] spids: [493] ) spids: [489 492] ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"no merge from non-existent subtree">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\ttest_must_fail git subtree merge --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"no pull from non-existent subtree">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\ttest_must_fail git subtree pull --prefix=\"sub dir\" ./\"sub proj\" master\n"> <"\t)"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"add subproj as subtree into sub dir/ with --prefix">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD &&\n"> <"\t\tcheck_equal \"$(last_commit_message)\" \"Add "> ) (EscapedLiteralPart token:) (SQ <"sub dir/">) (EscapedLiteralPart token:) (SQ <" from commit ">) (EscapedLiteralPart token:) (SQ <"$(git rev-parse FETCH_HEAD)">) (EscapedLiteralPart token:) (SQ <"\"\n"> <"\t)\n">) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"add subproj as subtree into sub dir/ with --prefix and --message">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> < "\t\tgit subtree add --prefix=\"sub dir\" --message=\"Added subproject\" FETCH_HEAD &&\n" > <"\t\tcheck_equal \"$(last_commit_message)\" \"Added subproject\"\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"add subproj as subtree into sub dir/ with --prefix as -P and --message as -m">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add -P \"sub dir\" -m \"Added subproject\" FETCH_HEAD &&\n"> <"\t\tcheck_equal \"$(last_commit_message)\" \"Added subproject\"\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"add subproj as subtree into sub dir/ with --squash and --prefix and --message">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> < "\t\tgit subtree add --prefix=\"sub dir\" --message=\"Added subproject with squash\" --squash FETCH_HEAD &&\n" > <"\t\tcheck_equal \"$(last_commit_message)\" \"Added subproject with squash\"\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"merge new subproj history into sub dir/ with --prefix">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n"> <"\t\tcheck_equal \"$(last_commit_message)\" \"Merge commit "> ) (EscapedLiteralPart token:) (SQ <"$(git rev-parse FETCH_HEAD)">) (EscapedLiteralPart token:) (SQ <"\"\n"> <"\t)\n">) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"merge new subproj history into sub dir/ with --prefix and --message">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> < "\t\tgit subtree merge --prefix=\"sub dir\" --message=\"Merged changes from subproject\" FETCH_HEAD &&\n" > <"\t\tcheck_equal \"$(last_commit_message)\" \"Merged changes from subproject\"\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"merge new subproj history into sub dir/ with --squash and --prefix and --message">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> < "\t\tgit subtree merge --prefix=\"sub dir\" --message=\"Merged changes from subproject using squash\" --squash FETCH_HEAD &&\n" > <"\t\tcheck_equal \"$(last_commit_message)\" \"Merged changes from subproject using squash\"\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"merge the added subproj again, should do nothing">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD &&\n"> <"\t\t# this shouldn not actually do anything, since FETCH_HEAD\n"> <"\t\t# is already a parent\n"> <"\t\tresult=$(git merge -s ours -m \"merge -s -ours\" FETCH_HEAD) &&\n"> <"\t\tcheck_equal \"${result}\" \"Already up-to-date.\"\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} { (SQ < "merge new subproj history into subdir/ with a slash appended to the argument of --prefix" > ) } { (SQ <"\n"> <"\ttest_create_repo \"$test_count\" &&\n"> <"\ttest_create_repo \"$test_count/subproj\" &&\n"> <"\ttest_create_commit \"$test_count\" main1 &&\n"> <"\ttest_create_commit \"$test_count/subproj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$test_count\" &&\n"> <"\t\tgit fetch ./subproj master &&\n"> <"\t\tgit subtree add --prefix=subdir/ FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$test_count/subproj\" sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$test_count\" &&\n"> <"\t\tgit fetch ./subproj master &&\n"> <"\t\tgit subtree merge --prefix=subdir/ FETCH_HEAD &&\n"> <"\t\tcheck_equal \"$(last_commit_message)\" \"Merge commit "> ) (EscapedLiteralPart token:) (SQ <"$(git rev-parse FETCH_HEAD)">) (EscapedLiteralPart token:) (SQ <"\"\n"> <"\t)\n">) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"split requires option --prefix">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD &&\n"> <"\t\techo \"You must provide the --prefix option.\" > expected &&\n"> <"\t\ttest_must_fail git subtree split > actual 2>&1 &&\n"> <"\t\ttest_debug \"printf "> ) (DQ ("expected: ")) (SQ <"\" &&\n"> <"\t\ttest_debug \"cat expected\" &&\n"> <"\t\ttest_debug \"printf ">) (DQ ("actual: ")) (SQ <"\" &&\n"> <"\t\ttest_debug \"cat actual\" &&\n"> <"\t\ttest_cmp expected actual\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"split requires path given by option --prefix must exist">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD &&\n"> <"\t\techo \""> ) (EscapedLiteralPart token:) (SQ ) (EscapedLiteralPart token:) (SQ <" does not exist; use ">) (EscapedLiteralPart token:) (SQ <"git subtree add">) (EscapedLiteralPart token:) (SQ <"\" > expected &&\n"> < "\t\ttest_must_fail git subtree split --prefix=non-existent-directory > actual 2>&1 &&\n" > <"\t\ttest_debug \"printf "> ) (DQ ("expected: ")) (SQ <"\" &&\n"> <"\t\ttest_debug \"cat expected\" &&\n"> <"\t\ttest_debug \"printf ">) (DQ ("actual: ")) (SQ <"\" &&\n"> <"\t\ttest_debug \"cat actual\" &&\n"> <"\t\ttest_cmp expected actual\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"split sub dir/ with --rejoin">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main2 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n"> <"\t\tsplit_hash=$(git subtree split --prefix=\"sub dir\" --annotate=\"*\") &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --rejoin &&\n"> <"\t\tcheck_equal \"$(last_commit_message)\" \"Split "> ) (EscapedLiteralPart token:) (SQ <"sub dir/">) (EscapedLiteralPart token:) (SQ <" into commit ">) (EscapedLiteralPart token:) (SQ <"$split_hash">) (EscapedLiteralPart token:) (SQ <"\"\n"> <"\t)\n"> <" ">) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"split sub dir/ with --rejoin from scratch">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tmkdir \"sub dir\" &&\n"> <"\t\techo file >\"sub dir\"/file &&\n"> <"\t\tgit add \"sub dir/file\" &&\n"> <"\t\tgit commit -m\"sub dir file\" &&\n"> <"\t\tsplit_hash=$(git subtree split --prefix=\"sub dir\" --rejoin) &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --rejoin &&\n"> <"\t\tcheck_equal \"$(last_commit_message)\" \"Split "> ) (EscapedLiteralPart token:) (SQ <"sub dir/">) (EscapedLiteralPart token:) (SQ <" into commit ">) (EscapedLiteralPart token:) (SQ <"$split_hash">) (EscapedLiteralPart token:) (SQ <"\"\n"> <"\t)\n"> <" ">) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"split sub dir/ with --rejoin and --message">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main2 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n"> < "\t\tgit subtree split --prefix=\"sub dir\" --message=\"Split & rejoin\" --annotate=\"*\" --rejoin &&\n" > <"\t\tcheck_equal \"$(last_commit_message)\" \"Split & rejoin\"\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"split \"sub dir\"/ with --branch">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main2 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n"> <"\t\tsplit_hash=$(git subtree split --prefix=\"sub dir\" --annotate=\"*\") &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br &&\n"> <"\t\tcheck_equal \"$(git rev-parse subproj-br)\" \"$split_hash\"\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"check hash of split">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main2 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n"> <"\t\tsplit_hash=$(git subtree split --prefix=\"sub dir\" --annotate=\"*\") &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br &&\n"> <"\t\tcheck_equal \"$(git rev-parse subproj-br)\" \"$split_hash\" &&\n"> <"\t\t# Check hash of split\n"> <"\t\tnew_hash=$(git rev-parse subproj-br^2) &&\n"> <"\t\t(\n"> <"\t\t\tcd ./\"sub proj\" &&\n"> <"\t\t\tsubdir_hash=$(git rev-parse HEAD) &&\n"> <"\t\t\tcheck_equal "> ) (SQ <"\"$new_hash\"">) (SQ <" \"$subdir_hash\"\n"> <"\t\t)\n"> <"\t)\n">) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"split \"sub dir\"/ with --branch for an existing branch">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit branch subproj-br FETCH_HEAD &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main2 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n"> <"\t\tsplit_hash=$(git subtree split --prefix=\"sub dir\" --annotate=\"*\") &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br &&\n"> <"\t\tcheck_equal \"$(git rev-parse subproj-br)\" \"$split_hash\"\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"split \"sub dir\"/ with --branch for an incompatible branch">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit branch init HEAD &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main2 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n"> <"\t\ttest_must_fail git subtree split --prefix=\"sub dir\" --branch init\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"make sure exactly the right set of files ends up in the subproj">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main2 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub3 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub3 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count/sub proj\" &&\n"> <"\t\tgit fetch .. subproj-br &&\n"> <"\t\tgit merge FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub4 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub4 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n"> <"\t) &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count/sub proj\" &&\n"> <"\t\tgit fetch .. subproj-br &&\n"> <"\t\tgit merge FETCH_HEAD &&\n"> <"\n"> <"\t\tchks=\"sub1\n"> <"sub2\n"> <"sub3\n"> <"sub4\" &&\n"> <"\t\tchks_sub=$(cat < ) (EscapedLiteralPart token:) (SQ <"s,^,sub dir/,">) (EscapedLiteralPart token:) (SQ <"\n"> <"$chks\n"> <"TXT\n"> <") &&\n"> <"\t\tchkms=\"main-sub1\n"> <"main-sub2\n"> <"main-sub3\n"> <"main-sub4\" &&\n"> <"\t\tchkms_sub=$(cat < ) (EscapedLiteralPart token:) (SQ <"s,^,sub dir/,">) (EscapedLiteralPart token:) (SQ <"\n"> <"$chkms\n"> <"TXT\n"> <") &&\n"> <"\n"> <"\t\tsubfiles=$(git ls-files) &&\n"> <"\t\tcheck_equal \"$subfiles\" \"$chkms\n"> <"$chks\"\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"make sure the subproj *only* contains commits that affect the \"sub dir\"">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main2 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub3 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub3 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count/sub proj\" &&\n"> <"\t\tgit fetch .. subproj-br &&\n"> <"\t\tgit merge FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub4 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub4 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n"> <"\t) &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count/sub proj\" &&\n"> <"\t\tgit fetch .. subproj-br &&\n"> <"\t\tgit merge FETCH_HEAD &&\n"> <"\n"> <"\t\tchks=\"sub1\n"> <"sub2\n"> <"sub3\n"> <"sub4\" &&\n"> <"\t\tchks_sub=$(cat < ) (EscapedLiteralPart token:) (SQ <"s,^,sub dir/,">) (EscapedLiteralPart token:) (SQ <"\n"> <"$chks\n"> <"TXT\n"> <") &&\n"> <"\t\tchkms=\"main-sub1\n"> <"main-sub2\n"> <"main-sub3\n"> <"main-sub4\" &&\n"> <"\t\tchkms_sub=$(cat < ) (EscapedLiteralPart token:) (SQ <"s,^,sub dir/,">) (EscapedLiteralPart token:) (SQ <"\n"> <"$chkms\n"> <"TXT\n"> <") &&\n"> < "\t\tallchanges=$(git log --name-only --pretty=format:\"\" | sort | sed \"/^$/d\") &&\n" > <"\t\tcheck_equal \"$allchanges\" \"$chkms\n"> <"$chks\"\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"make sure exactly the right set of files ends up in the mainline">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main2 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub3 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub3 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count/sub proj\" &&\n"> <"\t\tgit fetch .. subproj-br &&\n"> <"\t\tgit merge FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub4 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub4 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n"> <"\t) &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count/sub proj\" &&\n"> <"\t\tgit fetch .. subproj-br &&\n"> <"\t\tgit merge FETCH_HEAD\n"> <"\t) &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree pull --prefix=\"sub dir\" ./\"sub proj\" master &&\n"> <"\n"> <"\t\tchkm=\"main1\n"> <"main2\" &&\n"> <"\t\tchks=\"sub1\n"> <"sub2\n"> <"sub3\n"> <"sub4\" &&\n"> <"\t\tchks_sub=$(cat < ) (EscapedLiteralPart token:) (SQ <"s,^,sub dir/,">) (EscapedLiteralPart token:) (SQ <"\n"> <"$chks\n"> <"TXT\n"> <") &&\n"> <"\t\tchkms=\"main-sub1\n"> <"main-sub2\n"> <"main-sub3\n"> <"main-sub4\" &&\n"> <"\t\tchkms_sub=$(cat < ) (EscapedLiteralPart token:) (SQ <"s,^,sub dir/,">) (EscapedLiteralPart token:) (SQ <"\n"> <"$chkms\n"> <"TXT\n"> <") &&\n"> <"\t\tmainfiles=$(git ls-files) &&\n"> <"\t\tcheck_equal \"$mainfiles\" \"$chkm\n"> <"$chkms_sub\n"> <"$chks_sub\"\n"> <")\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"make sure each filename changed exactly once in the entire history">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit config log.date relative\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main2 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub3 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub3 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count/sub proj\" &&\n"> <"\t\tgit fetch .. subproj-br &&\n"> <"\t\tgit merge FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub4 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub4 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n"> <"\t) &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count/sub proj\" &&\n"> <"\t\tgit fetch .. subproj-br &&\n"> <"\t\tgit merge FETCH_HEAD\n"> <"\t) &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree pull --prefix=\"sub dir\" ./\"sub proj\" master &&\n"> <"\n"> <"\t\tchkm=\"main1\n"> <"main2\" &&\n"> <"\t\tchks=\"sub1\n"> <"sub2\n"> <"sub3\n"> <"sub4\" &&\n"> <"\t\tchks_sub=$(cat < ) (EscapedLiteralPart token:) (SQ <"s,^,sub dir/,">) (EscapedLiteralPart token:) (SQ <"\n"> <"$chks\n"> <"TXT\n"> <") &&\n"> <"\t\tchkms=\"main-sub1\n"> <"main-sub2\n"> <"main-sub3\n"> <"main-sub4\" &&\n"> <"\t\tchkms_sub=$(cat < ) (EscapedLiteralPart token:) (SQ <"s,^,sub dir/,">) (EscapedLiteralPart token:) (SQ <"\n"> <"$chkms\n"> <"TXT\n"> <") &&\n"> <"\n"> <"\t\t# main-sub?? and /\"sub dir\"/main-sub?? both change, because those are the\n"> <"\t\t# changes that were split into their own history. And \"sub dir\"/sub?? never\n"> <"\t\t# change, since they were *only* changed in the subtree branch.\n"> <"\t\tallchanges=$(git log --name-only --pretty=format:\"\" | sort | sed \"/^$/d\") &&\n"> <"\t\texpected="> ) (SQ <"\"$(cat < <"$chkms\n"> <"$chkm\n"> <"$chks\n"> <"$chkms_sub\n"> <"TXT\n"> <")\""> ) (SQ <" &&\n"> <"\t\tcheck_equal \"$allchanges\" \"$expected\"\n"> <"\t)\n">) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"make sure the --rejoin commits never make it into subproj">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main2 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub3 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub3 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count/sub proj\" &&\n"> <"\t\tgit fetch .. subproj-br &&\n"> <"\t\tgit merge FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub4 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub4 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n"> <"\t) &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count/sub proj\" &&\n"> <"\t\tgit fetch .. subproj-br &&\n"> <"\t\tgit merge FETCH_HEAD\n"> <"\t) &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree pull --prefix=\"sub dir\" ./\"sub proj\" master &&\n"> <"\t\tcheck_equal \"$(git log --pretty=format:\"%s\" HEAD^2 | grep -i split)\" \"\"\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"make sure no \"git subtree\" tagged commits make it into subproj">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main2 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub3 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub3 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count/sub proj\" &&\n"> <"\t\tgit fetch .. subproj-br &&\n"> <"\t\t git merge FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub4 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub4 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --annotate=\"*\" --branch subproj-br --rejoin\n"> <"\t) &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count/sub proj\" &&\n"> <"\t\tgit fetch .. subproj-br &&\n"> <"\t\tgit merge FETCH_HEAD\n"> <"\t) &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree pull --prefix=\"sub dir\" ./\"sub proj\" master &&\n"> <"\n"> <"\t\t# They are meaningless to subproj since one side of the merge refers to the mainline\n"> < "\t\tcheck_equal \"$(git log --pretty=format:\"%s%n%b\" HEAD^2 | grep \"git-subtree.*:\")\" \"\"\n" > <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"make sure \"git subtree split\" find the correct parent">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit branch subproj-ref FETCH_HEAD &&\n"> <"\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --branch subproj-br &&\n"> <"\n"> <"\t\t# at this point, the new commit parent should be subproj-ref, if it is\n"> <"\t\t# not, something went wrong (the \"newparent\" of \"master~\" commit should\n"> <"\t\t# have been sub2, but it was not, because its cache was not set to\n"> <"\t\t# itself)\n"> < "\t\tcheck_equal \"$(git log --pretty=format:%P -1 subproj-br)\" \"$(git rev-parse subproj-ref)\"\n" > <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"split a new subtree without --onto option">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --branch subproj-br\n"> <"\t) &&\n"> <"\tmkdir \"$subtree_test_count\"/\"sub dir2\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir2\"/main-sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\n"> <"\t\t# also test that we still can split out an entirely new subtree\n"> <"\t\t# if the parent of the first commit in the tree is not empty,\n"> <"\t\t# then the new subtree has accidentally been attached to something\n"> <"\t\tgit subtree split --prefix=\"sub dir2\" --branch subproj2-br &&\n"> <"\t\tcheck_equal \"$(git log --pretty=format:%P -1 subproj2-br)\" \"\"\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"verify one file change per commit">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit branch sub1 FETCH_HEAD &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" sub1\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree split --prefix=\"sub dir\" --branch subproj-br\n"> <"\t) &&\n"> <"\tmkdir \"$subtree_test_count\"/\"sub dir2\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir2\"/main-sub2 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit subtree split --prefix=\"sub dir2\" --branch subproj2-br &&\n"> <"\n"> <"\t\tx= &&\n"> <"\t\tgit log --pretty=format:\"commit: %H\" | join_commits |\n"> <"\t\t(\n"> <"\t\t\twhile read commit a b; do\n"> <"\t\t\t\ttest_debug \"echo Verifying commit $commit\"\n"> <"\t\t\t\ttest_debug \"echo a: $a\"\n"> <"\t\t\t\ttest_debug \"echo b: $b\"\n"> <"\t\t\t\tcheck_equal \"$b\" \"\"\n"> <"\t\t\t\tx=1\n"> <"\t\t\tdone\n"> <"\t\t\tcheck_equal \"$x\" 1\n"> <"\t\t)\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"push split to subproj">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\tsubtree_test_create_repo \"$subtree_test_count/sub proj\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main1 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub1 &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree add --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub1 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" main2 &&\n"> <"\ttest_create_commit \"$subtree_test_count/sub proj\" sub2 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub2 &&\n"> <"\t(\n"> <"\t\tcd $subtree_test_count/\"sub proj\" &&\n"> <" git branch sub-branch-1 &&\n"> <" cd .. &&\n"> <"\t\tgit fetch ./\"sub proj\" master &&\n"> <"\t\tgit subtree merge --prefix=\"sub dir\" FETCH_HEAD\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" \"sub dir\"/main-sub3 &&\n"> <" (\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t git subtree push ./\"sub proj\" --prefix \"sub dir\" sub-branch-1 &&\n"> <" cd ./\"sub proj\" &&\n"> <" git checkout sub-branch-1 &&\n"> <" \tcheck_equal \"$(last_commit_message)\" \"sub dir/main-sub3\"\n"> <"\t)\n"> ) } ) (C {(next_test)}) (C {(test_expect_success)} {(SQ <"subtree descendant check">)} { (SQ <"\n"> <"\tsubtree_test_create_repo \"$subtree_test_count\" &&\n"> <"\ttest_create_commit \"$subtree_test_count\" folder_subtree/a &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit branch branch\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" folder_subtree/0 &&\n"> <"\ttest_create_commit \"$subtree_test_count\" folder_subtree/b &&\n"> <"\tcherry=$(cd \"$subtree_test_count\"; git rev-parse HEAD) &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit checkout branch\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" commit_on_branch &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit cherry-pick $cherry &&\n"> <"\t\tgit checkout master &&\n"> <"\t\tgit merge -m \"merge should be kept on subtree\" branch &&\n"> <"\t\tgit branch no_subtree_work_branch\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" folder_subtree/d &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit checkout no_subtree_work_branch\n"> <"\t) &&\n"> <"\ttest_create_commit \"$subtree_test_count\" not_a_subtree_change &&\n"> <"\t(\n"> <"\t\tcd \"$subtree_test_count\" &&\n"> <"\t\tgit checkout master &&\n"> <"\t\tgit merge -m \"merge should be skipped on subtree\" no_subtree_work_branch &&\n"> <"\n"> <"\t\tgit subtree split --prefix folder_subtree/ --branch subtree_tip master &&\n"> <"\t\tgit subtree split --prefix folder_subtree/ --branch subtree_branch branch &&\n"> <"\t\tcheck_equal $(git rev-list --count subtree_tip..subtree_branch) 0\n"> <"\t)\n"> ) } ) (C {(test_done)}) ] )