(command.CommandList children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:test_description) op: assign_op.Equal rhs: { (SQ <'Basic porcelain support for subtrees\n'> <'\n'> <'This test verifies the basic operation of the add, pull, merge\n'> <'and split subcommands of git subtree.\n'> ) } spids: [15] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:TEST_DIRECTORY) op: assign_op.Equal rhs: {(command_sub left_token:<Id.Left_DollarParen '$('> child:(C {<pwd>})) <'/../../../t'>} spids: [24] ) ] ) (C {<export>} {<TEST_DIRECTORY>}) (C {<.>} {<'../../../t/test-lib.sh'>}) (command.ShFunction name: subtree_test_create_repo body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp] children: [ (C {<test_create_repo>} {(DQ ($ Id.VSub_Number '$1'))}) (command.Subshell child: (command.AndOr ops: [Id.Op_DAmp] children: [ (C {<cd>} {(DQ ($ Id.VSub_Number '$1'))}) (C {<git>} {<config>} {<log.date>} {<relative>}) ] ) ) ] ) ] ) ) (command.ShFunction name: create body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp] children: [ (command.Simple words: [{<echo>} {(DQ ($ Id.VSub_Number '$1'))}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {(DQ ($ Id.VSub_Number '$1'))} ) ] do_fork: T ) (C {<git>} {<add>} {(DQ ($ Id.VSub_Number '$1'))}) ] ) ] ) ) (command.ShFunction name: check_equal body: (BraceGroup children: [ (C {<test_debug>} {(SQ <echo>)}) (C {<test_debug>} { (DQ <'echo '> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\"'>) <'check a:'> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\"'>) <' '> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\"'>) <'{'> ($ Id.VSub_Number '$1') <'}'> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\"'>) ) } ) (C {<test_debug>} { (DQ <'echo '> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\"'>) <' b:'> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\"'>) <' '> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\"'>) <'{'> ($ Id.VSub_Number '$2') <'}'> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\"'>) ) } ) (command.If arms: [ (if_arm cond: (condition.Shell commands: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ ($ Id.VSub_Number '$1'))} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_Number '$2'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] ) action: [(command.ControlFlow token:<Id.ControlFlow_Return return> arg_word:{<0>})] spids: [160 177] ) ] else_action: [(command.ControlFlow token:<Id.ControlFlow_Return return> arg_word:{<1>})] ) ] ) ) (command.ShFunction name: undo body: (BraceGroup children:[(C {<git>} {<reset>} {<--hard>} {<HEAD> <Id.Lit_TildeLike '~'>})]) ) (command.ShFunction name: join_commits body: (BraceGroup children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:commit) op: assign_op.Equal rhs: (word.Empty) spids: [236] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:all) op: assign_op.Equal rhs: (word.Empty) spids: [239] ) ] ) (command.WhileUntil keyword: <Id.KW_While while> cond: (condition.Shell commands: [ (command.Sentence child: (C {<read>} {<x>} {<y>}) terminator: <Id.Op_Semi _> ) ] ) body: (command.DoGroup children: [ (command.If arms: [ (if_arm cond: (condition.Shell commands: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-z>} {(DQ ($ Id.VSub_DollarName '$x'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] ) action: [(command.ControlFlow token:<Id.ControlFlow_Continue continue>)] spids: [254 267] ) (if_arm cond: (condition.Shell commands: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {(DQ ($ Id.VSub_DollarName '$x'))} {<Id.Lit_Equals '='>} {(DQ <'commit:'>)} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] ) action: [ (command.If arms: [ (if_arm cond: (condition.Shell commands: [ (command.Sentence child: (C {<Id.Lit_LBracket '['>} {<-n>} {(DQ ($ Id.VSub_DollarName '$commit'))} {<Id.Lit_RBracket ']'>} ) terminator: <Id.Op_Semi _> ) ] ) action: [ (C {<echo>} { (DQ ($ Id.VSub_DollarName '$commit') <' '> ($ Id.VSub_DollarName '$all') ) } ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:all) op: assign_op.Equal rhs: (word.Empty) spids: [318] ) ] ) ] spids: [293 306] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:commit) op: assign_op.Equal rhs: {(DQ ($ Id.VSub_DollarName '$y'))} spids: [324] ) ] ) ] spids: [273 290] ) ] else_action: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:all) op: assign_op.Equal rhs: {(DQ ($ Id.VSub_DollarName '$all') <' '> ($ Id.VSub_DollarName '$y'))} spids: [333] ) ] ) ] ) ] ) ) (C {<echo>} {(DQ ($ Id.VSub_DollarName '$commit') <' '> ($ Id.VSub_DollarName '$all'))}) ] ) ) (command.ShFunction name: test_create_commit body: (command.Subshell child: (command.CommandList children: [ (command.AndOr ops: [Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DPipe] children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:repo) op: assign_op.Equal rhs: {($ Id.VSub_Number '$1')} spids: [365] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:commit) op: assign_op.Equal rhs: {($ Id.VSub_Number '$2')} spids: [371] ) ] ) (C {<cd>} {(DQ ($ Id.VSub_DollarName '$repo'))}) (C {<mkdir>} {<-p>} { (DQ (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<dirname>} {(DQ ($ Id.VSub_DollarName '$commit'))}) ) ) } ) (C {<error>} {(DQ <'Could not create directory for commit'>)}) ] ) (command.AndOr ops: [Id.Op_DAmp Id.Op_DPipe] children: [ (command.Simple words: [{<echo>} {(DQ ($ Id.VSub_DollarName '$commit'))}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {(DQ ($ Id.VSub_DollarName '$commit'))} ) ] do_fork: T ) (C {<git>} {<add>} {(DQ ($ Id.VSub_DollarName '$commit'))}) (C {<error>} {(DQ <'Could not add commit'>)}) ] ) (command.AndOr ops: [Id.Op_DPipe] children: [ (C {<git>} {<commit>} {<-m>} {(DQ ($ Id.VSub_DollarName '$commit'))}) (C {<error>} {(DQ <'Could not commit'>)}) ] ) ] ) ) ) (command.ShFunction name: last_commit_message body: (BraceGroup children: [ (C {<git>} {<log>} {<--pretty> <Id.Lit_Equals '='> <format> <Id.Lit_Colon ':'> <Id.Lit_Other '%'> <s>} {<-1>} ) ] ) ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:subtree_test_count) op: assign_op.Equal rhs: {<0>} spids: [486] ) ] ) (command.ShFunction name: next_test body: (BraceGroup children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:subtree_test_count) op: assign_op.Equal rhs: { (word_part.ArithSub anode: (arith_expr.Binary op_id: Id.Arith_Plus left: {($ Id.VSub_DollarName '$subtree_test_count')} right: {<Id.Lit_Digits 1>} ) ) } spids: [496] ) ] ) ] ) ) (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 '> ) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <'sub dir/'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <' from commit '>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <'$(git rev-parse FETCH_HEAD)'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (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 '> ) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <'$(git rev-parse FETCH_HEAD)'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (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 '> ) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <'$(git rev-parse FETCH_HEAD)'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (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 "'> ) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <non-existent-directory>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <' does not exist; use '>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <'git subtree add'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (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 '> ) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <'sub dir/'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <' into commit '>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <'$split_hash'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (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 '> ) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <'sub dir/'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <' into commit '>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <'$split_hash'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (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 <<TXT | sed '> ) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <'s,^,sub dir/,'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (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 <<TXT | sed '> ) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <'s,^,sub dir/,'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (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 <<TXT | sed '> ) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <'s,^,sub dir/,'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (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 <<TXT | sed '> ) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <'s,^,sub dir/,'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (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 <<TXT | sed '> ) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <'s,^,sub dir/,'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (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 <<TXT | sed '> ) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <'s,^,sub dir/,'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (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 <<TXT | sed '> ) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <'s,^,sub dir/,'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (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 <<TXT | sed '> ) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <'s,^,sub dir/,'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (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 <<TXT | sort\n'> <'$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>}) ] )