#!/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