Merge branch 'jk/peel-iterated-oid'
[git] / t / t4068-diff-symmetric-merge-base.sh
1 #!/bin/sh
2
3 test_description='behavior of diff with symmetric-diff setups and --merge-base'
4
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7
8 . ./test-lib.sh
9
10 # build these situations:
11 #  - normal merge with one merge base (br1...b2r);
12 #  - criss-cross merge ie 2 merge bases (br1...main);
13 #  - disjoint subgraph (orphan branch, br3...main).
14 #
15 #     B---E   <-- main
16 #    / \ /
17 #   A   X
18 #    \ / \
19 #     C---D--G   <-- br1
20 #      \    /
21 #       ---F   <-- br2
22 #
23 #  H  <-- br3
24 #
25 # We put files into a few commits so that we can verify the
26 # output as well.
27
28 test_expect_success setup '
29         git commit --allow-empty -m A &&
30         echo b >b &&
31         git add b &&
32         git commit -m B &&
33         git checkout -b br1 HEAD^ &&
34         echo c >c &&
35         git add c &&
36         git commit -m C &&
37         git tag commit-C &&
38         git merge -m D main &&
39         git tag commit-D &&
40         git checkout main &&
41         git merge -m E commit-C &&
42         git checkout -b br2 commit-C &&
43         echo f >f &&
44         git add f &&
45         git commit -m F &&
46         git checkout br1 &&
47         git merge -m G br2 &&
48         git checkout --orphan br3 &&
49         git commit -m H
50 '
51
52 test_expect_success 'diff with one merge base' '
53         git diff commit-D...br1 >tmp &&
54         tail -n 1 tmp >actual &&
55         echo +f >expect &&
56         test_cmp expect actual
57 '
58
59 # The output (in tmp) can have +b or +c depending
60 # on which merge base (commit B or C) is picked.
61 # It should have one of those two, which comes out
62 # to seven lines.
63 test_expect_success 'diff with two merge bases' '
64         git diff br1...main >tmp 2>err &&
65         test_line_count = 7 tmp &&
66         test_line_count = 1 err
67 '
68
69 test_expect_success 'diff with no merge bases' '
70         test_must_fail git diff br2...br3 2>err &&
71         test_i18ngrep "fatal: br2...br3: no merge base" err
72 '
73
74 test_expect_success 'diff with too many symmetric differences' '
75         test_must_fail git diff br1...main br2...br3 2>err &&
76         test_i18ngrep "usage" err
77 '
78
79 test_expect_success 'diff with symmetric difference and extraneous arg' '
80         test_must_fail git diff main br1...main 2>err &&
81         test_i18ngrep "usage" err
82 '
83
84 test_expect_success 'diff with two ranges' '
85         test_must_fail git diff main br1..main br2..br3 2>err &&
86         test_i18ngrep "usage" err
87 '
88
89 test_expect_success 'diff with ranges and extra arg' '
90         test_must_fail git diff main br1..main commit-D 2>err &&
91         test_i18ngrep "usage" err
92 '
93
94 test_expect_success 'diff --merge-base with no commits' '
95         test_must_fail git diff --merge-base
96 '
97
98 test_expect_success 'diff --merge-base with three commits' '
99         test_must_fail git diff --merge-base br1 br2 main 2>err &&
100         test_i18ngrep "usage" err
101 '
102
103 for cmd in diff-index diff
104 do
105         test_expect_success "$cmd --merge-base with one commit" '
106                 git checkout main &&
107                 git $cmd commit-C >expect &&
108                 git $cmd --merge-base br2 >actual &&
109                 test_cmp expect actual
110         '
111
112         test_expect_success "$cmd --merge-base with one commit and unstaged changes" '
113                 git checkout main &&
114                 test_when_finished git reset --hard &&
115                 echo unstaged >>c &&
116                 git $cmd commit-C >expect &&
117                 git $cmd --merge-base br2 >actual &&
118                 test_cmp expect actual
119         '
120
121         test_expect_success "$cmd --merge-base with one commit and staged and unstaged changes" '
122                 git checkout main &&
123                 test_when_finished git reset --hard &&
124                 echo staged >>c &&
125                 git add c &&
126                 echo unstaged >>c &&
127                 git $cmd commit-C >expect &&
128                 git $cmd --merge-base br2 >actual &&
129                 test_cmp expect actual
130         '
131
132         test_expect_success "$cmd --merge-base --cached with one commit and staged and unstaged changes" '
133                 git checkout main &&
134                 test_when_finished git reset --hard &&
135                 echo staged >>c &&
136                 git add c &&
137                 echo unstaged >>c &&
138                 git $cmd --cached commit-C >expect &&
139                 git $cmd --cached --merge-base br2 >actual &&
140                 test_cmp expect actual
141         '
142
143         test_expect_success "$cmd --merge-base with non-commit" '
144                 git checkout main &&
145                 test_must_fail git $cmd --merge-base main^{tree} 2>err &&
146                 test_i18ngrep "fatal: --merge-base only works with commits" err
147         '
148
149         test_expect_success "$cmd --merge-base with no merge bases and one commit" '
150                 git checkout main &&
151                 test_must_fail git $cmd --merge-base br3 2>err &&
152                 test_i18ngrep "fatal: no merge base found" err
153         '
154
155         test_expect_success "$cmd --merge-base with multiple merge bases and one commit" '
156                 git checkout main &&
157                 test_must_fail git $cmd --merge-base br1 2>err &&
158                 test_i18ngrep "fatal: multiple merge bases found" err
159         '
160 done
161
162 for cmd in diff-tree diff
163 do
164         test_expect_success "$cmd --merge-base with two commits" '
165                 git $cmd commit-C main >expect &&
166                 git $cmd --merge-base br2 main >actual &&
167                 test_cmp expect actual
168         '
169
170         test_expect_success "$cmd --merge-base commit and non-commit" '
171                 test_must_fail git $cmd --merge-base br2 main^{tree} 2>err &&
172                 test_i18ngrep "fatal: --merge-base only works with commits" err
173         '
174
175         test_expect_success "$cmd --merge-base with no merge bases and two commits" '
176                 test_must_fail git $cmd --merge-base br2 br3 2>err &&
177                 test_i18ngrep "fatal: no merge base found" err
178         '
179
180         test_expect_success "$cmd --merge-base with multiple merge bases and two commits" '
181                 test_must_fail git $cmd --merge-base main br1 2>err &&
182                 test_i18ngrep "fatal: multiple merge bases found" err
183         '
184 done
185
186 test_expect_success 'diff-tree --merge-base with one commit' '
187         test_must_fail git diff-tree --merge-base main 2>err &&
188         test_i18ngrep "fatal: --merge-base only works with two commits" err
189 '
190
191 test_expect_success 'diff --merge-base with range' '
192         test_must_fail git diff --merge-base br2..br3 2>err &&
193         test_i18ngrep "fatal: --merge-base does not work with ranges" err
194 '
195
196 test_done