(command.CommandList children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:test_description) op: assign_op.Equal rhs: {(SQ <'combined diff'>)} spids: [4] ) ] ) (C {<.>} {<'./test-lib.sh'>}) (C {<.>} {(DQ ($ Id.VSub_DollarName '$TEST_DIRECTORY')) <'/diff-lib.sh'>}) (command.ShFunction name: setup_helper body: (BraceGroup children: [ (command.AndOr ops: [ Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp ] children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:one) op: assign_op.Equal rhs: {($ Id.VSub_Number '$1')} spids: [30] ) (assign_pair lhs: (sh_lhs_expr.Name name:branch) op: assign_op.Equal rhs: {($ Id.VSub_Number '$2')} spids: [33] ) (assign_pair lhs: (sh_lhs_expr.Name name:side) op: assign_op.Equal rhs: {($ Id.VSub_Number '$3')} spids: [36] ) ] ) (C {<git>} {<branch>} {($ Id.VSub_DollarName '$side')} {($ Id.VSub_DollarName '$branch')}) (command.ForEach iter_name: l iter_words: [{($ Id.VSub_DollarName '$one')} {<two>} {<three>} {<fyra>}] do_arg_iter: F body: (command.DoGroup children:[(C {<echo>} {($ Id.VSub_DollarName '$l')})]) redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<file>})] ) (C {<git>} {<add>} {<file>}) (C {<test_tick>}) (C {<git>} {<commit>} {<-m>} {($ Id.VSub_DollarName '$branch')}) (C {<git>} {<checkout>} {($ Id.VSub_DollarName '$side')}) (command.ForEach iter_name: l iter_words: [{($ Id.VSub_DollarName '$one')} {<two>} {<three>} {<quatro>}] do_arg_iter: F body: (command.DoGroup children:[(C {<echo>} {($ Id.VSub_DollarName '$l')})]) redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<file>})] ) (C {<git>} {<add>} {<file>}) (C {<test_tick>}) (C {<git>} {<commit>} {<-m>} {($ Id.VSub_DollarName '$side')}) (C {<test_must_fail>} {<git>} {<merge>} {($ Id.VSub_DollarName '$branch')}) (command.ForEach iter_name: l iter_words: [{($ Id.VSub_DollarName '$one')} {<three>} {<four>}] do_arg_iter: F body: (command.DoGroup children:[(C {<echo>} {($ Id.VSub_DollarName '$l')})]) redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<file>})] ) (C {<git>} {<add>} {<file>}) (C {<test_tick>}) (C {<git>} {<commit>} {<-m>} { (DQ <'merge '> ($ Id.VSub_DollarName '$branch') <' into '> ($ Id.VSub_DollarName '$side') ) } ) ] ) ] ) ) (command.ShFunction name: verify_helper body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp] children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:it) op: assign_op.Equal rhs: {($ Id.VSub_Number '$1')} spids: [253] ) ] ) (command.Simple words: [ {<sed>} {<-e>} { (SQ <'\n'> <'\t\t1,/^@@@/d\n'> <'\t\t/^ -/d\n'> <'\t\ts/^\\(.\\)./\\1/\n'> <'\t'>) } {(DQ ($ Id.VSub_DollarName '$it'))} ] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {(DQ ($ Id.VSub_DollarName '$it') <.actual.1>)} ) ] do_fork: T ) (command.Simple words: [ {<sed>} {<-e>} { (SQ <'\n'> <'\t\t1,/^@@@/d\n'> <'\t\t/^- /d\n'> <'\t\ts/^.\\(.\\)/\\1/\n'> <'\t'>) } {(DQ ($ Id.VSub_DollarName '$it'))} ] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {(DQ ($ Id.VSub_DollarName '$it') <.actual.2>)} ) ] do_fork: T ) (command.Pipeline children: [ (C {<git>} {<diff>} {(DQ ($ Id.VSub_DollarName '$it') <'^'>)} {(DQ ($ Id.VSub_DollarName '$it'))} {<-->} ) (command.Simple words: [{<sed>} {<-e>} {(SQ <'1,/^@@/d'>)}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {(DQ ($ Id.VSub_DollarName '$it') <.expect.1>)} ) ] do_fork: T ) ] negated: F ) (C {<test_cmp>} {(DQ ($ Id.VSub_DollarName '$it') <.expect.1>)} {(DQ ($ Id.VSub_DollarName '$it') <.actual.1>)} ) (command.Pipeline children: [ (C {<git>} {<diff>} {(DQ ($ Id.VSub_DollarName '$it') <'^2'>)} {(DQ ($ Id.VSub_DollarName '$it'))} {<-->} ) (command.Simple words: [{<sed>} {<-e>} {(SQ <'1,/^@@/d'>)}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {(DQ ($ Id.VSub_DollarName '$it') <.expect.2>)} ) ] do_fork: T ) ] negated: F ) (C {<test_cmp>} {(DQ ($ Id.VSub_DollarName '$it') <.expect.2>)} {(DQ ($ Id.VSub_DollarName '$it') <.actual.2>)} ) ] ) ] ) ) (C {<test_expect_success>} {<setup>} { (SQ <'\n'> <'\t>file &&\n'> <'\tgit add file &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m initial &&\n'> <'\n'> <'\tgit branch withone &&\n'> <'\tgit branch sansone &&\n'> <'\n'> <'\tgit checkout withone &&\n'> <'\tsetup_helper one withone sidewithone &&\n'> <'\n'> <'\tgit checkout sansone &&\n'> <'\tsetup_helper "" sansone sidesansone\n'> ) } ) (C {<test_expect_success>} {(SQ <'check combined output (1)'>)} {(SQ <'\n'> <'\tgit show sidewithone -- >sidewithone &&\n'> <'\tverify_helper sidewithone\n'>)} ) (C {<test_expect_success>} {(SQ <'check combined output (2)'>)} {(SQ <'\n'> <'\tgit show sidesansone -- >sidesansone &&\n'> <'\tverify_helper sidesansone\n'>)} ) (C {<test_expect_success>} {(SQ <'diagnose truncated file'>)} { (SQ <'\n'> <'\t>file &&\n'> <'\tgit add file &&\n'> <'\tgit commit --amend -C HEAD &&\n'> <'\tgit show >out &&\n'> <'\tgrep "diff --cc file" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'setup for --cc --raw'>)} { (SQ <'\n'> <'\tblob=$(echo file | git hash-object --stdin -w) &&\n'> <'\tbase_tree=$(echo "100644 blob $blob\tfile" | git mktree) &&\n'> <'\ttrees= &&\n'> <'\tfor i in $(test_seq 1 40)\n'> <'\tdo\n'> <'\t\tblob=$(echo file$i | git hash-object --stdin -w) &&\n'> <'\t\ttrees="$trees$(echo "100644 blob $blob\tfile" | git mktree)$LF"\n'> <'\tdone\n'> ) } ) (C {<test_expect_success>} {(SQ <'check --cc --raw with four trees'>)} { (SQ <'\n'> <'\tfour_trees=$(echo "$trees" | sed -e 4q) &&\n'> <'\tgit diff --cc --raw $four_trees $base_tree >out &&\n'> <'\t# Check for four leading colons in the output:\n'> <'\tgrep "^::::[^:]" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'check --cc --raw with forty trees'>)} { (SQ <'\n'> <'\tgit diff --cc --raw $trees $base_tree >out &&\n'> <'\t# Check for forty leading colons in the output:\n'> <'\tgrep "^::::::::::::::::::::::::::::::::::::::::[^:]" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'setup combined ignore spaces'>)} { (SQ <'\n'> <'\tgit checkout master &&\n'> <'\t>test &&\n'> <'\tgit add test &&\n'> <'\tgit commit -m initial &&\n'> <'\n'> <'\ttr -d Q <<-\\EOF >test &&\n'> <'\talways coalesce\n'> <'\teol space coalesce Q\n'> <'\tspace change coalesce\n'> <'\tall spa ces coalesce\n'> <'\teol spaces Q\n'> <'\tspace change\n'> <'\tall spa ces\n'> <'\tEOF\n'> <'\tgit commit -m "test space change" -a &&\n'> <'\n'> <'\tgit checkout -b side HEAD^ &&\n'> <'\ttr -d Q <<-\\EOF >test &&\n'> <'\talways coalesce\n'> <'\teol space coalesce\n'> <'\tspace change coalesce\n'> <'\tall spaces coalesce\n'> <'\teol spaces\n'> <'\tspace change\n'> <'\tall spaces\n'> <'\tEOF\n'> <'\tgit commit -m "test other space changes" -a &&\n'> <'\n'> <'\ttest_must_fail git merge master &&\n'> <'\ttr -d Q <<-\\EOF >test &&\n'> <'\teol spaces Q\n'> <'\tspace change\n'> <'\tall spa ces\n'> <'\tEOF\n'> <'\tgit commit -m merged -a\n'> ) } ) (C {<test_expect_success>} {(SQ <'check combined output (no ignore space)'>)} { (SQ <'\n'> <'\tgit show >actual.tmp &&\n'> <'\tsed -e "1,/^@@@/d" < actual.tmp >actual &&\n'> <'\ttr -d Q <<-\\EOF >expected &&\n'> <'\t--always coalesce\n'> <'\t- eol space coalesce\n'> <'\t- space change coalesce\n'> <'\t- all spaces coalesce\n'> <'\t- eol spaces\n'> <'\t- space change\n'> <'\t- all spaces\n'> <'\t -eol space coalesce Q\n'> <'\t -space change coalesce\n'> <'\t -all spa ces coalesce\n'> <'\t+ eol spaces Q\n'> <'\t+ space change\n'> <'\t+ all spa ces\n'> <'\tEOF\n'> <'\tcompare_diff_patch expected actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'check combined output (ignore space at eol)'>)} { (SQ <'\n'> <'\tgit show --ignore-space-at-eol >actual.tmp &&\n'> <'\tsed -e "1,/^@@@/d" < actual.tmp >actual &&\n'> <'\ttr -d Q <<-\\EOF >expected &&\n'> <'\t--always coalesce\n'> <'\t--eol space coalesce\n'> <'\t- space change coalesce\n'> <'\t- all spaces coalesce\n'> <'\t -space change coalesce\n'> <'\t -all spa ces coalesce\n'> <'\t eol spaces Q\n'> <'\t- space change\n'> <'\t- all spaces\n'> <'\t+ space change\n'> <'\t+ all spa ces\n'> <'\tEOF\n'> <'\tcompare_diff_patch expected actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'check combined output (ignore space change)'>)} { (SQ <'\n'> <'\tgit show -b >actual.tmp &&\n'> <'\tsed -e "1,/^@@@/d" < actual.tmp >actual &&\n'> <'\ttr -d Q <<-\\EOF >expected &&\n'> <'\t--always coalesce\n'> <'\t--eol space coalesce\n'> <'\t--space change coalesce\n'> <'\t- all spaces coalesce\n'> <'\t -all spa ces coalesce\n'> <'\t eol spaces Q\n'> <'\t space change\n'> <'\t- all spaces\n'> <'\t+ all spa ces\n'> <'\tEOF\n'> <'\tcompare_diff_patch expected actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'check combined output (ignore all spaces)'>)} { (SQ <'\n'> <'\tgit show -w >actual.tmp &&\n'> <'\tsed -e "1,/^@@@/d" < actual.tmp >actual &&\n'> <'\ttr -d Q <<-\\EOF >expected &&\n'> <'\t--always coalesce\n'> <'\t--eol space coalesce\n'> <'\t--space change coalesce\n'> <'\t--all spaces coalesce\n'> <'\t eol spaces Q\n'> <'\t space change\n'> <'\t all spa ces\n'> <'\tEOF\n'> <'\tcompare_diff_patch expected actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'combine diff coalesce simple'>)} { (SQ <'\n'> <'\t>test &&\n'> <'\tgit add test &&\n'> <'\tgit commit -m initial &&\n'> <'\ttest_seq 4 >test &&\n'> <'\tgit commit -a -m empty1 &&\n'> <'\tgit branch side1 &&\n'> <'\tgit checkout HEAD^ &&\n'> <'\ttest_seq 5 >test &&\n'> <'\tgit commit -a -m empty2 &&\n'> <'\ttest_must_fail git merge side1 &&\n'> <'\t>test &&\n'> <'\tgit commit -a -m merge &&\n'> <'\tgit show >actual.tmp &&\n'> <'\tsed -e "1,/^@@@/d" < actual.tmp >actual &&\n'> <'\ttr -d Q <<-\\EOF >expected &&\n'> <'\t--1\n'> <'\t--2\n'> <'\t--3\n'> <'\t--4\n'> <'\t- 5\n'> <'\tEOF\n'> <'\tcompare_diff_patch expected actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'combine diff coalesce tricky'>)} { (SQ <'\n'> <'\t>test &&\n'> <'\tgit add test &&\n'> <'\tgit commit -m initial --allow-empty &&\n'> <'\tcat <<-\\EOF >test &&\n'> <'\t3\n'> <'\t1\n'> <'\t2\n'> <'\t3\n'> <'\t4\n'> <'\tEOF\n'> <'\tgit commit -a -m empty1 &&\n'> <'\tgit branch -f side1 &&\n'> <'\tgit checkout HEAD^ &&\n'> <'\tcat <<-\\EOF >test &&\n'> <'\t1\n'> <'\t3\n'> <'\t5\n'> <'\t4\n'> <'\tEOF\n'> <'\tgit commit -a -m empty2 &&\n'> <'\tgit branch -f side2 &&\n'> <'\ttest_must_fail git merge side1 &&\n'> <'\t>test &&\n'> <'\tgit commit -a -m merge &&\n'> <'\tgit show >actual.tmp &&\n'> <'\tsed -e "1,/^@@@/d" < actual.tmp >actual &&\n'> <'\ttr -d Q <<-\\EOF >expected &&\n'> <'\t -3\n'> <'\t--1\n'> <'\t -2\n'> <'\t--3\n'> <'\t- 5\n'> <'\t--4\n'> <'\tEOF\n'> <'\tcompare_diff_patch expected actual &&\n'> <'\tgit checkout -f side1 &&\n'> <'\ttest_must_fail git merge side2 &&\n'> <'\t>test &&\n'> <'\tgit commit -a -m merge &&\n'> <'\tgit show >actual.tmp &&\n'> <'\tsed -e "1,/^@@@/d" < actual.tmp >actual &&\n'> <'\ttr -d Q <<-\\EOF >expected &&\n'> <'\t- 3\n'> <'\t--1\n'> <'\t- 2\n'> <'\t--3\n'> <'\t -5\n'> <'\t--4\n'> <'\tEOF\n'> <'\tcompare_diff_patch expected actual\n'> ) } ) (C {<test_expect_failure>} {(SQ <'combine diff coalesce three parents'>)} { (SQ <'\n'> <'\t>test &&\n'> <'\tgit add test &&\n'> <'\tgit commit -m initial --allow-empty &&\n'> <'\tcat <<-\\EOF >test &&\n'> <'\t3\n'> <'\t1\n'> <'\t2\n'> <'\t3\n'> <'\t4\n'> <'\tEOF\n'> <'\tgit commit -a -m empty1 &&\n'> <'\tgit checkout -B side1 &&\n'> <'\tgit checkout HEAD^ &&\n'> <'\tcat <<-\\EOF >test &&\n'> <'\t1\n'> <'\t3\n'> <'\t7\n'> <'\t5\n'> <'\t4\n'> <'\tEOF\n'> <'\tgit commit -a -m empty2 &&\n'> <'\tgit branch -f side2 &&\n'> <'\tgit checkout HEAD^ &&\n'> <'\tcat <<-\\EOF >test &&\n'> <'\t3\n'> <'\t1\n'> <'\t6\n'> <'\t5\n'> <'\t4\n'> <'\tEOF\n'> <'\tgit commit -a -m empty3 &&\n'> <'\t>test &&\n'> <'\tgit add test &&\n'> <'\tTREE=$(git write-tree) &&\n'> <'\tCOMMIT=$(git commit-tree -p HEAD -p side1 -p side2 -m merge $TREE) &&\n'> <'\tgit show $COMMIT >actual.tmp &&\n'> <'\tsed -e "1,/^@@@/d" < actual.tmp >actual &&\n'> <'\ttr -d Q <<-\\EOF >expected &&\n'> <'\t-- 3\n'> <'\t---1\n'> <'\t- 6\n'> <'\t - 2\n'> <'\t --3\n'> <'\t -7\n'> <'\t- -5\n'> <'\t---4\n'> <'\tEOF\n'> <'\tcompare_diff_patch expected actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'combine diff missing delete bug'>)} { (SQ <'\n'> <'\tgit commit -m initial --allow-empty &&\n'> <'\tcat <<-\\EOF >test &&\n'> <'\t1\n'> <'\t2\n'> <'\t3\n'> <'\t4\n'> <'\tEOF\n'> <'\tgit add test &&\n'> <'\tgit commit -a -m side1 &&\n'> <'\tgit checkout -B side1 &&\n'> <'\tgit checkout HEAD^ &&\n'> <'\tcat <<-\\EOF >test &&\n'> <'\t0\n'> <'\t1\n'> <'\t2\n'> <'\t3\n'> <'\t4modified\n'> <'\tEOF\n'> <'\tgit add test &&\n'> <'\tgit commit -m side2 &&\n'> <'\tgit branch -f side2 &&\n'> <'\ttest_must_fail git merge --no-commit side1 &&\n'> <'\tcat <<-\\EOF >test &&\n'> <'\t1\n'> <'\t2\n'> <'\t3\n'> <'\t4modified\n'> <'\tEOF\n'> <'\tgit add test &&\n'> <'\tgit commit -a -m merge &&\n'> <'\tgit diff-tree -c -p HEAD >actual.tmp &&\n'> <'\tsed -e "1,/^@@@/d" < actual.tmp >actual &&\n'> <'\ttr -d Q <<-\\EOF >expected &&\n'> <'\t- 0\n'> <'\t 1\n'> <'\t 2\n'> <'\t 3\n'> <'\t -4\n'> <'\t +4modified\n'> <'\tEOF\n'> <'\tcompare_diff_patch expected actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'combine diff gets tree sorting right'>)} { (SQ <'\n'> <'\t# create a directory and a file that sort differently in trees\n'> <'\t# versus byte-wise (implied "/" sorts after ".")\n'> <'\tgit checkout -f master &&\n'> <'\tmkdir foo &&\n'> <'\techo base >foo/one &&\n'> <'\techo base >foo/two &&\n'> <'\techo base >foo.ext &&\n'> <'\tgit add foo foo.ext &&\n'> <'\tgit commit -m base &&\n'> <'\n'> <'\t# one side modifies a file in the directory, along with the root\n'> <'\t# file...\n'> <'\techo master >foo/one &&\n'> <'\techo master >foo.ext &&\n'> <'\tgit commit -a -m master &&\n'> <'\n'> <'\t# the other side modifies the other file in the directory\n'> <'\tgit checkout -b other HEAD^ &&\n'> <'\techo other >foo/two &&\n'> <'\tgit commit -a -m other &&\n'> <'\n'> <'\t# And now we merge. The files in the subdirectory will resolve cleanly,\n'> <'\t# meaning that a combined diff will not find them interesting. But it\n'> <'\t# will find the tree itself interesting, because it had to be merged.\n'> <'\tgit checkout master &&\n'> <'\tgit merge other &&\n'> <'\n'> <'\tprintf "MM\\tfoo\\n" >expect &&\n'> <'\tgit diff-tree -c --name-status -t HEAD >actual.tmp &&\n'> <'\tsed 1d <actual.tmp >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {<test_done>}) ] )