diff options
Diffstat (limited to 't/t4038-diff-combined.sh')
-rwxr-xr-x | t/t4038-diff-combined.sh | 546 |
1 files changed, 546 insertions, 0 deletions
diff --git a/t/t4038-diff-combined.sh b/t/t4038-diff-combined.sh new file mode 100755 index 0000000..2ce26e5 --- /dev/null +++ b/t/t4038-diff-combined.sh @@ -0,0 +1,546 @@ +#!/bin/sh + +test_description='combined diff' + +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + +. ./test-lib.sh +. "$TEST_DIRECTORY"/lib-diff.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 (1) with git diff <rev>^!' ' + git diff sidewithone^! -- >sidewithone && + verify_helper sidewithone +' + +test_expect_success 'check combined output (2)' ' + git show sidesansone -- >sidesansone && + verify_helper sidesansone +' + +test_expect_success 'check combined output (2) with git diff <rev>^!' ' + git diff 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" || return 1 + 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 main && + >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 main && + 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://lore.kernel.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 main && + 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 main >foo/one && + echo main >foo.ext && + git commit -a -m main && + + # 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 main && + 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 && + side1cf=$(git hash-object filename-side1c) && + git add filename-side1c && + git commit -m with && + git checkout side2c && + test_seq 1 9 >filename-side2c && + echo ten >>filename-side2c && + side2cf=$(git hash-object 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 && + mergedf=$(git hash-object filename-merged) && + git add filename-merged && + git commit +' + +test_expect_success '--combined-all-paths and --raw' ' + cat <<-EOF >expect && + ::100644 100644 100644 $side1cf $side2cf $mergedf 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* && + side1df=$(git hash-object *tabs) && + git commit -m with && + git checkout side2d && + test_seq 1 9 >"$(printf "i\tam\ttabbed")" && + echo ten >>"$(printf "i\tam\ttabbed")" && + git add *tabbed && + side2df=$(git hash-object *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* && + headf=$(git hash-object fickle*) && + git commit && + head=$(git rev-parse HEAD) +' + +test_expect_success FUNNYNAMES '--combined-all-paths and --raw and funny names' ' + cat <<-EOF >expect && + ::100644 100644 100644 $side1df $side2df $headf 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 "$head\0::100644 100644 100644 $side1df $side2df $headf 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 |