summaryrefslogtreecommitdiffstats
path: root/t/t4068-diff-symmetric-merge-base.sh
blob: 2d650d8f1032ca7c113fa0f48c72719fb08ab245 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#!/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