| #!/bin/sh | 
 |  | 
 | test_description='behavior of diff with symmetric-diff setups and --merge-base' | 
 |  | 
 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main | 
 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME | 
 |  | 
 | . ./test-lib.sh | 
 |  | 
 | # build these situations: | 
 | #  - normal merge with one merge base (br1...b2r); | 
 | #  - criss-cross merge ie 2 merge bases (br1...main); | 
 | #  - disjoint subgraph (orphan branch, br3...main). | 
 | # | 
 | #     B---E   <-- main | 
 | #    / \ / | 
 | #   A   X | 
 | #    \ / \ | 
 | #     C---D--G   <-- br1 | 
 | #      \    / | 
 | #       ---F   <-- br2 | 
 | # | 
 | #  H  <-- br3 | 
 | # | 
 | # We put files into a few commits so that we can verify the | 
 | # output as well. | 
 |  | 
 | test_expect_success setup ' | 
 | 	git commit --allow-empty -m A && | 
 | 	echo b >b && | 
 | 	git add b && | 
 | 	git commit -m B && | 
 | 	git checkout -b br1 HEAD^ && | 
 | 	echo c >c && | 
 | 	git add c && | 
 | 	git commit -m C && | 
 | 	git tag commit-C && | 
 | 	git merge -m D main && | 
 | 	git tag commit-D && | 
 | 	git checkout main && | 
 | 	git merge -m E commit-C && | 
 | 	git checkout -b br2 commit-C && | 
 | 	echo f >f && | 
 | 	git add f && | 
 | 	git commit -m F && | 
 | 	git checkout br1 && | 
 | 	git merge -m G br2 && | 
 | 	git checkout --orphan br3 && | 
 | 	git commit -m H | 
 | ' | 
 |  | 
 | test_expect_success 'diff with one merge base' ' | 
 | 	git diff commit-D...br1 >tmp && | 
 | 	tail -n 1 tmp >actual && | 
 | 	echo +f >expect && | 
 | 	test_cmp expect actual | 
 | ' | 
 |  | 
 | # The output (in tmp) can have +b or +c depending | 
 | # on which merge base (commit B or C) is picked. | 
 | # It should have one of those two, which comes out | 
 | # to seven lines. | 
 | test_expect_success 'diff with two merge bases' ' | 
 | 	git diff br1...main >tmp 2>err && | 
 | 	test_line_count = 7 tmp && | 
 | 	test_line_count = 1 err | 
 | ' | 
 |  | 
 | test_expect_success 'diff with no merge bases' ' | 
 | 	test_must_fail git diff br2...br3 2>err && | 
 | 	test_i18ngrep "fatal: br2...br3: no merge base" err | 
 | ' | 
 |  | 
 | test_expect_success 'diff with too many symmetric differences' ' | 
 | 	test_must_fail git diff br1...main br2...br3 2>err && | 
 | 	test_i18ngrep "usage" err | 
 | ' | 
 |  | 
 | test_expect_success 'diff with symmetric difference and extraneous arg' ' | 
 | 	test_must_fail git diff main br1...main 2>err && | 
 | 	test_i18ngrep "usage" err | 
 | ' | 
 |  | 
 | test_expect_success 'diff with two ranges' ' | 
 | 	test_must_fail git diff main br1..main br2..br3 2>err && | 
 | 	test_i18ngrep "usage" err | 
 | ' | 
 |  | 
 | test_expect_success 'diff with ranges and extra arg' ' | 
 | 	test_must_fail git diff main br1..main commit-D 2>err && | 
 | 	test_i18ngrep "usage" err | 
 | ' | 
 |  | 
 | test_expect_success 'diff --merge-base with no commits' ' | 
 | 	test_must_fail git diff --merge-base | 
 | ' | 
 |  | 
 | test_expect_success 'diff --merge-base with three commits' ' | 
 | 	test_must_fail git diff --merge-base br1 br2 main 2>err && | 
 | 	test_i18ngrep "usage" err | 
 | ' | 
 |  | 
 | for cmd in diff-index diff | 
 | do | 
 | 	test_expect_success "$cmd --merge-base with one commit" ' | 
 | 		git checkout main && | 
 | 		git $cmd commit-C >expect && | 
 | 		git $cmd --merge-base br2 >actual && | 
 | 		test_cmp expect actual | 
 | 	' | 
 |  | 
 | 	test_expect_success "$cmd --merge-base with one commit and unstaged changes" ' | 
 | 		git checkout main && | 
 | 		test_when_finished git reset --hard && | 
 | 		echo unstaged >>c && | 
 | 		git $cmd commit-C >expect && | 
 | 		git $cmd --merge-base br2 >actual && | 
 | 		test_cmp expect actual | 
 | 	' | 
 |  | 
 | 	test_expect_success "$cmd --merge-base with one commit and staged and unstaged changes" ' | 
 | 		git checkout main && | 
 | 		test_when_finished git reset --hard && | 
 | 		echo staged >>c && | 
 | 		git add c && | 
 | 		echo unstaged >>c && | 
 | 		git $cmd commit-C >expect && | 
 | 		git $cmd --merge-base br2 >actual && | 
 | 		test_cmp expect actual | 
 | 	' | 
 |  | 
 | 	test_expect_success "$cmd --merge-base --cached with one commit and staged and unstaged changes" ' | 
 | 		git checkout main && | 
 | 		test_when_finished git reset --hard && | 
 | 		echo staged >>c && | 
 | 		git add c && | 
 | 		echo unstaged >>c && | 
 | 		git $cmd --cached commit-C >expect && | 
 | 		git $cmd --cached --merge-base br2 >actual && | 
 | 		test_cmp expect actual | 
 | 	' | 
 |  | 
 | 	test_expect_success "$cmd --merge-base with non-commit" ' | 
 | 		git checkout main && | 
 | 		test_must_fail git $cmd --merge-base main^{tree} 2>err && | 
 | 		test_i18ngrep "fatal: --merge-base only works with commits" err | 
 | 	' | 
 |  | 
 | 	test_expect_success "$cmd --merge-base with no merge bases and one commit" ' | 
 | 		git checkout main && | 
 | 		test_must_fail git $cmd --merge-base br3 2>err && | 
 | 		test_i18ngrep "fatal: no merge base found" err | 
 | 	' | 
 |  | 
 | 	test_expect_success "$cmd --merge-base with multiple merge bases and one commit" ' | 
 | 		git checkout main && | 
 | 		test_must_fail git $cmd --merge-base br1 2>err && | 
 | 		test_i18ngrep "fatal: multiple merge bases found" err | 
 | 	' | 
 | done | 
 |  | 
 | for cmd in diff-tree diff | 
 | do | 
 | 	test_expect_success "$cmd --merge-base with two commits" ' | 
 | 		git $cmd commit-C main >expect && | 
 | 		git $cmd --merge-base br2 main >actual && | 
 | 		test_cmp expect actual | 
 | 	' | 
 |  | 
 | 	test_expect_success "$cmd --merge-base commit and non-commit" ' | 
 | 		test_must_fail git $cmd --merge-base br2 main^{tree} 2>err && | 
 | 		test_i18ngrep "fatal: --merge-base only works with commits" err | 
 | 	' | 
 |  | 
 | 	test_expect_success "$cmd --merge-base with no merge bases and two commits" ' | 
 | 		test_must_fail git $cmd --merge-base br2 br3 2>err && | 
 | 		test_i18ngrep "fatal: no merge base found" err | 
 | 	' | 
 |  | 
 | 	test_expect_success "$cmd --merge-base with multiple merge bases and two commits" ' | 
 | 		test_must_fail git $cmd --merge-base main br1 2>err && | 
 | 		test_i18ngrep "fatal: multiple merge bases found" err | 
 | 	' | 
 | done | 
 |  | 
 | test_expect_success 'diff-tree --merge-base with one commit' ' | 
 | 	test_must_fail git diff-tree --merge-base main 2>err && | 
 | 	test_i18ngrep "fatal: --merge-base only works with two commits" err | 
 | ' | 
 |  | 
 | test_expect_success 'diff --merge-base with range' ' | 
 | 	test_must_fail git diff --merge-base br2..br3 2>err && | 
 | 	test_i18ngrep "fatal: --merge-base does not work with ranges" err | 
 | ' | 
 |  | 
 | test_done |