|  | #!/bin/sh | 
|  |  | 
|  | test_description='combined diff' | 
|  |  | 
|  | . ./test-lib.sh | 
|  | . "$TEST_DIRECTORY"/diff-lib.sh | 
|  |  | 
|  | setup_helper () { | 
|  | one=$1 branch=$2 side=$3 && | 
|  |  | 
|  | git branch $side $branch && | 
|  | for l in $one two three fyra | 
|  | do | 
|  | echo $l | 
|  | done >file && | 
|  | git add file && | 
|  | test_tick && | 
|  | git commit -m $branch && | 
|  | git checkout $side && | 
|  | for l in $one two three quatro | 
|  | do | 
|  | echo $l | 
|  | done >file && | 
|  | git add file && | 
|  | test_tick && | 
|  | git commit -m $side && | 
|  | test_must_fail git merge $branch && | 
|  | for l in $one three four | 
|  | do | 
|  | echo $l | 
|  | done >file && | 
|  | git add file && | 
|  | test_tick && | 
|  | git commit -m "merge $branch into $side" | 
|  | } | 
|  |  | 
|  | verify_helper () { | 
|  | it=$1 && | 
|  |  | 
|  | # Ignore lines that were removed only from the other parent | 
|  | sed -e ' | 
|  | 1,/^@@@/d | 
|  | /^ -/d | 
|  | s/^\(.\)./\1/ | 
|  | ' "$it" >"$it.actual.1" && | 
|  | sed -e ' | 
|  | 1,/^@@@/d | 
|  | /^- /d | 
|  | s/^.\(.\)/\1/ | 
|  | ' "$it" >"$it.actual.2" && | 
|  |  | 
|  | git diff "$it^" "$it" -- | sed -e '1,/^@@/d' >"$it.expect.1" && | 
|  | test_cmp "$it.expect.1" "$it.actual.1" && | 
|  |  | 
|  | git diff "$it^2" "$it" -- | sed -e '1,/^@@/d' >"$it.expect.2" && | 
|  | test_cmp "$it.expect.2" "$it.actual.2" | 
|  | } | 
|  |  | 
|  | test_expect_success setup ' | 
|  | >file && | 
|  | git add file && | 
|  | test_tick && | 
|  | git commit -m initial && | 
|  |  | 
|  | git branch withone && | 
|  | git branch sansone && | 
|  |  | 
|  | git checkout withone && | 
|  | setup_helper one withone sidewithone && | 
|  |  | 
|  | git checkout sansone && | 
|  | setup_helper "" sansone sidesansone | 
|  | ' | 
|  |  | 
|  | test_expect_success 'check combined output (1)' ' | 
|  | git show sidewithone -- >sidewithone && | 
|  | verify_helper sidewithone | 
|  | ' | 
|  |  | 
|  | test_expect_success 'check combined output (2)' ' | 
|  | git show sidesansone -- >sidesansone && | 
|  | verify_helper sidesansone | 
|  | ' | 
|  |  | 
|  | test_expect_success 'diagnose truncated file' ' | 
|  | >file && | 
|  | git add file && | 
|  | git commit --amend -C HEAD && | 
|  | git show >out && | 
|  | grep "diff --cc file" out | 
|  | ' | 
|  |  | 
|  | test_expect_success 'setup for --cc --raw' ' | 
|  | blob=$(echo file | git hash-object --stdin -w) && | 
|  | base_tree=$(echo "100644 blob $blob	file" | git mktree) && | 
|  | trees= && | 
|  | for i in $(test_seq 1 40) | 
|  | do | 
|  | blob=$(echo file$i | git hash-object --stdin -w) && | 
|  | trees="$trees$(echo "100644 blob $blob	file" | git mktree)$LF" | 
|  | done | 
|  | ' | 
|  |  | 
|  | test_expect_success 'check --cc --raw with four trees' ' | 
|  | four_trees=$(echo "$trees" | sed -e 4q) && | 
|  | git diff --cc --raw $four_trees $base_tree >out && | 
|  | # Check for four leading colons in the output: | 
|  | grep "^::::[^:]" out | 
|  | ' | 
|  |  | 
|  | test_expect_success 'check --cc --raw with forty trees' ' | 
|  | git diff --cc --raw $trees $base_tree >out && | 
|  | # Check for forty leading colons in the output: | 
|  | grep "^::::::::::::::::::::::::::::::::::::::::[^:]" out | 
|  | ' | 
|  |  | 
|  | test_expect_success 'setup combined ignore spaces' ' | 
|  | git checkout master && | 
|  | >test && | 
|  | git add test && | 
|  | git commit -m initial && | 
|  |  | 
|  | tr -d Q <<-\EOF >test && | 
|  | always coalesce | 
|  | eol space coalesce Q | 
|  | space  change coalesce | 
|  | all spa ces coalesce | 
|  | eol spaces Q | 
|  | space  change | 
|  | all spa ces | 
|  | EOF | 
|  | git commit -m "test space change" -a && | 
|  |  | 
|  | git checkout -b side HEAD^ && | 
|  | tr -d Q <<-\EOF >test && | 
|  | always coalesce | 
|  | eol space coalesce | 
|  | space change coalesce | 
|  | all spaces coalesce | 
|  | eol spaces | 
|  | space change | 
|  | all spaces | 
|  | EOF | 
|  | git commit -m "test other space changes" -a && | 
|  |  | 
|  | test_must_fail git merge master && | 
|  | tr -d Q <<-\EOF >test && | 
|  | eol spaces Q | 
|  | space  change | 
|  | all spa ces | 
|  | EOF | 
|  | git commit -m merged -a | 
|  | ' | 
|  |  | 
|  | test_expect_success 'check combined output (no ignore space)' ' | 
|  | git show >actual.tmp && | 
|  | sed -e "1,/^@@@/d" < actual.tmp >actual && | 
|  | tr -d Q <<-\EOF >expected && | 
|  | --always coalesce | 
|  | - eol space coalesce | 
|  | - space change coalesce | 
|  | - all spaces coalesce | 
|  | - eol spaces | 
|  | - space change | 
|  | - all spaces | 
|  | -eol space coalesce Q | 
|  | -space  change coalesce | 
|  | -all spa ces coalesce | 
|  | + eol spaces Q | 
|  | + space  change | 
|  | + all spa ces | 
|  | EOF | 
|  | compare_diff_patch expected actual | 
|  | ' | 
|  |  | 
|  | test_expect_success 'check combined output (ignore space at eol)' ' | 
|  | git show --ignore-space-at-eol >actual.tmp && | 
|  | sed -e "1,/^@@@/d" < actual.tmp >actual && | 
|  | tr -d Q <<-\EOF >expected && | 
|  | --always coalesce | 
|  | --eol space coalesce | 
|  | - space change coalesce | 
|  | - all spaces coalesce | 
|  | -space  change coalesce | 
|  | -all spa ces coalesce | 
|  | eol spaces Q | 
|  | - space change | 
|  | - all spaces | 
|  | + space  change | 
|  | + all spa ces | 
|  | EOF | 
|  | compare_diff_patch expected actual | 
|  | ' | 
|  |  | 
|  | test_expect_success 'check combined output (ignore space change)' ' | 
|  | git show -b >actual.tmp && | 
|  | sed -e "1,/^@@@/d" < actual.tmp >actual && | 
|  | tr -d Q <<-\EOF >expected && | 
|  | --always coalesce | 
|  | --eol space coalesce | 
|  | --space change coalesce | 
|  | - all spaces coalesce | 
|  | -all spa ces coalesce | 
|  | eol spaces Q | 
|  | space  change | 
|  | - all spaces | 
|  | + all spa ces | 
|  | EOF | 
|  | compare_diff_patch expected actual | 
|  | ' | 
|  |  | 
|  | test_expect_success 'check combined output (ignore all spaces)' ' | 
|  | git show -w >actual.tmp && | 
|  | sed -e "1,/^@@@/d" < actual.tmp >actual && | 
|  | tr -d Q <<-\EOF >expected && | 
|  | --always coalesce | 
|  | --eol space coalesce | 
|  | --space change coalesce | 
|  | --all spaces coalesce | 
|  | eol spaces Q | 
|  | space  change | 
|  | all spa ces | 
|  | EOF | 
|  | compare_diff_patch expected actual | 
|  | ' | 
|  |  | 
|  | test_expect_success 'combine diff coalesce simple' ' | 
|  | >test && | 
|  | git add test && | 
|  | git commit -m initial && | 
|  | test_seq 4 >test && | 
|  | git commit -a -m empty1 && | 
|  | git branch side1 && | 
|  | git checkout HEAD^ && | 
|  | test_seq 5 >test && | 
|  | git commit -a -m empty2 && | 
|  | test_must_fail git merge side1 && | 
|  | >test && | 
|  | git commit -a -m merge && | 
|  | git show >actual.tmp && | 
|  | sed -e "1,/^@@@/d" < actual.tmp >actual && | 
|  | tr -d Q <<-\EOF >expected && | 
|  | --1 | 
|  | --2 | 
|  | --3 | 
|  | --4 | 
|  | - 5 | 
|  | EOF | 
|  | compare_diff_patch expected actual | 
|  | ' | 
|  |  | 
|  | test_expect_success 'combine diff coalesce tricky' ' | 
|  | >test && | 
|  | git add test && | 
|  | git commit -m initial --allow-empty && | 
|  | cat <<-\EOF >test && | 
|  | 3 | 
|  | 1 | 
|  | 2 | 
|  | 3 | 
|  | 4 | 
|  | EOF | 
|  | git commit -a -m empty1 && | 
|  | git branch -f side1 && | 
|  | git checkout HEAD^ && | 
|  | cat <<-\EOF >test && | 
|  | 1 | 
|  | 3 | 
|  | 5 | 
|  | 4 | 
|  | EOF | 
|  | git commit -a -m empty2 && | 
|  | git branch -f side2 && | 
|  | test_must_fail git merge side1 && | 
|  | >test && | 
|  | git commit -a -m merge && | 
|  | git show >actual.tmp && | 
|  | sed -e "1,/^@@@/d" < actual.tmp >actual && | 
|  | tr -d Q <<-\EOF >expected && | 
|  | -3 | 
|  | --1 | 
|  | -2 | 
|  | --3 | 
|  | - 5 | 
|  | --4 | 
|  | EOF | 
|  | compare_diff_patch expected actual && | 
|  | git checkout -f side1 && | 
|  | test_must_fail git merge side2 && | 
|  | >test && | 
|  | git commit -a -m merge && | 
|  | git show >actual.tmp && | 
|  | sed -e "1,/^@@@/d" < actual.tmp >actual && | 
|  | tr -d Q <<-\EOF >expected && | 
|  | - 3 | 
|  | --1 | 
|  | - 2 | 
|  | --3 | 
|  | -5 | 
|  | --4 | 
|  | EOF | 
|  | compare_diff_patch expected actual | 
|  | ' | 
|  |  | 
|  | test_expect_failure 'combine diff coalesce three parents' ' | 
|  | >test && | 
|  | git add test && | 
|  | git commit -m initial --allow-empty && | 
|  | cat <<-\EOF >test && | 
|  | 3 | 
|  | 1 | 
|  | 2 | 
|  | 3 | 
|  | 4 | 
|  | EOF | 
|  | git commit -a -m empty1 && | 
|  | git checkout -B side1 && | 
|  | git checkout HEAD^ && | 
|  | cat <<-\EOF >test && | 
|  | 1 | 
|  | 3 | 
|  | 7 | 
|  | 5 | 
|  | 4 | 
|  | EOF | 
|  | git commit -a -m empty2 && | 
|  | git branch -f side2 && | 
|  | git checkout HEAD^ && | 
|  | cat <<-\EOF >test && | 
|  | 3 | 
|  | 1 | 
|  | 6 | 
|  | 5 | 
|  | 4 | 
|  | EOF | 
|  | git commit -a -m empty3 && | 
|  | >test && | 
|  | git add test && | 
|  | TREE=$(git write-tree) && | 
|  | COMMIT=$(git commit-tree -p HEAD -p side1 -p side2 -m merge $TREE) && | 
|  | git show $COMMIT >actual.tmp && | 
|  | sed -e "1,/^@@@/d" < actual.tmp >actual && | 
|  | tr -d Q <<-\EOF >expected && | 
|  | -- 3 | 
|  | ---1 | 
|  | -  6 | 
|  | - 2 | 
|  | --3 | 
|  | -7 | 
|  | - -5 | 
|  | ---4 | 
|  | EOF | 
|  | compare_diff_patch expected actual | 
|  | ' | 
|  |  | 
|  | # Test for a bug reported at | 
|  | # https://public-inbox.org/git/20130515143508.GO25742@login.drsnuggles.stderr.nl/ | 
|  | # where a delete lines were missing from combined diff output when they | 
|  | # occurred exactly before the context lines of a later change. | 
|  | test_expect_success 'combine diff missing delete bug' ' | 
|  | git commit -m initial --allow-empty && | 
|  | cat <<-\EOF >test && | 
|  | 1 | 
|  | 2 | 
|  | 3 | 
|  | 4 | 
|  | EOF | 
|  | git add test && | 
|  | git commit -a -m side1 && | 
|  | git checkout -B side1 && | 
|  | git checkout HEAD^ && | 
|  | cat <<-\EOF >test && | 
|  | 0 | 
|  | 1 | 
|  | 2 | 
|  | 3 | 
|  | 4modified | 
|  | EOF | 
|  | git add test && | 
|  | git commit -m side2 && | 
|  | git branch -f side2 && | 
|  | test_must_fail git merge --no-commit side1 && | 
|  | cat <<-\EOF >test && | 
|  | 1 | 
|  | 2 | 
|  | 3 | 
|  | 4modified | 
|  | EOF | 
|  | git add test && | 
|  | git commit -a -m merge && | 
|  | git diff-tree -c -p HEAD >actual.tmp && | 
|  | sed -e "1,/^@@@/d" < actual.tmp >actual && | 
|  | tr -d Q <<-\EOF >expected && | 
|  | - 0 | 
|  | 1 | 
|  | 2 | 
|  | 3 | 
|  | -4 | 
|  | +4modified | 
|  | EOF | 
|  | compare_diff_patch expected actual | 
|  | ' | 
|  |  | 
|  | test_expect_success 'combine diff gets tree sorting right' ' | 
|  | # create a directory and a file that sort differently in trees | 
|  | # versus byte-wise (implied "/" sorts after ".") | 
|  | git checkout -f master && | 
|  | mkdir foo && | 
|  | echo base >foo/one && | 
|  | echo base >foo/two && | 
|  | echo base >foo.ext && | 
|  | git add foo foo.ext && | 
|  | git commit -m base && | 
|  |  | 
|  | # one side modifies a file in the directory, along with the root | 
|  | # file... | 
|  | echo master >foo/one && | 
|  | echo master >foo.ext && | 
|  | git commit -a -m master && | 
|  |  | 
|  | # the other side modifies the other file in the directory | 
|  | git checkout -b other HEAD^ && | 
|  | echo other >foo/two && | 
|  | git commit -a -m other && | 
|  |  | 
|  | # And now we merge. The files in the subdirectory will resolve cleanly, | 
|  | # meaning that a combined diff will not find them interesting. But it | 
|  | # will find the tree itself interesting, because it had to be merged. | 
|  | git checkout master && | 
|  | git merge other && | 
|  |  | 
|  | printf "MM\tfoo\n" >expect && | 
|  | git diff-tree -c --name-status -t HEAD >actual.tmp && | 
|  | sed 1d <actual.tmp >actual && | 
|  | test_cmp expect actual | 
|  | ' | 
|  |  | 
|  | test_expect_success 'setup for --combined-all-paths' ' | 
|  | git branch side1c && | 
|  | git branch side2c && | 
|  | git checkout side1c && | 
|  | test_seq 1 10 >filename-side1c && | 
|  | git add filename-side1c && | 
|  | git commit -m with && | 
|  | git checkout side2c && | 
|  | test_seq 1 9 >filename-side2c && | 
|  | echo ten >>filename-side2c && | 
|  | git add filename-side2c && | 
|  | git commit -m iam && | 
|  | git checkout -b mergery side1c && | 
|  | git merge --no-commit side2c && | 
|  | git rm filename-side1c && | 
|  | echo eleven >>filename-side2c && | 
|  | git mv filename-side2c filename-merged && | 
|  | git add filename-merged && | 
|  | git commit | 
|  | ' | 
|  |  | 
|  | test_expect_success '--combined-all-paths and --raw' ' | 
|  | cat <<-\EOF >expect && | 
|  | ::100644 100644 100644 f00c965d8307308469e537302baa73048488f162 088bd5d92c2a8e0203ca8e7e4c2a5c692f6ae3f7 333b9c62519f285e1854830ade0fe1ef1d40ee1b RR	filename-side1c	filename-side2c	filename-merged | 
|  | EOF | 
|  | git diff-tree -c -M --raw --combined-all-paths HEAD >actual.tmp && | 
|  | sed 1d <actual.tmp >actual && | 
|  | test_cmp expect actual | 
|  | ' | 
|  |  | 
|  | test_expect_success '--combined-all-paths and --cc' ' | 
|  | cat <<-\EOF >expect && | 
|  | --- a/filename-side1c | 
|  | --- a/filename-side2c | 
|  | +++ b/filename-merged | 
|  | EOF | 
|  | git diff-tree --cc -M --combined-all-paths HEAD >actual.tmp && | 
|  | grep ^[-+][-+][-+] <actual.tmp >actual && | 
|  | test_cmp expect actual | 
|  | ' | 
|  |  | 
|  | test_expect_success FUNNYNAMES 'setup for --combined-all-paths with funny names' ' | 
|  | git branch side1d && | 
|  | git branch side2d && | 
|  | git checkout side1d && | 
|  | test_seq 1 10 >"$(printf "file\twith\ttabs")" && | 
|  | git add file* && | 
|  | git commit -m with && | 
|  | git checkout side2d && | 
|  | test_seq 1 9 >"$(printf "i\tam\ttabbed")" && | 
|  | echo ten >>"$(printf "i\tam\ttabbed")" && | 
|  | git add *tabbed && | 
|  | git commit -m iam && | 
|  | git checkout -b funny-names-mergery side1d && | 
|  | git merge --no-commit side2d && | 
|  | git rm *tabs && | 
|  | echo eleven >>"$(printf "i\tam\ttabbed")" && | 
|  | git mv "$(printf "i\tam\ttabbed")" "$(printf "fickle\tnaming")" && | 
|  | git add fickle* && | 
|  | git commit | 
|  | ' | 
|  |  | 
|  | test_expect_success FUNNYNAMES '--combined-all-paths and --raw and funny names' ' | 
|  | cat <<-\EOF >expect && | 
|  | ::100644 100644 100644 f00c965d8307308469e537302baa73048488f162 088bd5d92c2a8e0203ca8e7e4c2a5c692f6ae3f7 333b9c62519f285e1854830ade0fe1ef1d40ee1b RR	"file\twith\ttabs"	"i\tam\ttabbed"	"fickle\tnaming" | 
|  | EOF | 
|  | git diff-tree -c -M --raw --combined-all-paths HEAD >actual.tmp && | 
|  | sed 1d <actual.tmp >actual && | 
|  | test_cmp expect actual | 
|  | ' | 
|  |  | 
|  | test_expect_success FUNNYNAMES '--combined-all-paths and --raw -and -z and funny names' ' | 
|  | printf "aaf8087c3cbd4db8e185a2d074cf27c53cfb75d7\0::100644 100644 100644 f00c965d8307308469e537302baa73048488f162 088bd5d92c2a8e0203ca8e7e4c2a5c692f6ae3f7 333b9c62519f285e1854830ade0fe1ef1d40ee1b RR\0file\twith\ttabs\0i\tam\ttabbed\0fickle\tnaming\0" >expect && | 
|  | git diff-tree -c -M --raw --combined-all-paths -z HEAD >actual && | 
|  | test_cmp expect actual | 
|  | ' | 
|  |  | 
|  | test_expect_success FUNNYNAMES '--combined-all-paths and --cc and funny names' ' | 
|  | cat <<-\EOF >expect && | 
|  | --- "a/file\twith\ttabs" | 
|  | --- "a/i\tam\ttabbed" | 
|  | +++ "b/fickle\tnaming" | 
|  | EOF | 
|  | git diff-tree --cc -M --combined-all-paths HEAD >actual.tmp && | 
|  | grep ^[-+][-+][-+] <actual.tmp >actual && | 
|  | test_cmp expect actual | 
|  | ' | 
|  |  | 
|  | test_done |