]> git.ipfire.org Git - thirdparty/git.git/blob - t/t5574-fetch-output.sh
parse-options: simplify positivation handling
[thirdparty/git.git] / t / t5574-fetch-output.sh
1 #!/bin/sh
2
3 test_description='git fetch output format'
4
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7
8 . ./test-lib.sh
9
10 test_expect_success 'fetch with invalid output format configuration' '
11 test_when_finished "rm -rf clone" &&
12 git clone . clone &&
13
14 test_must_fail git -C clone -c fetch.output fetch origin 2>actual.err &&
15 cat >expect <<-EOF &&
16 error: missing value for ${SQ}fetch.output${SQ}
17 fatal: unable to parse ${SQ}fetch.output${SQ} from command-line config
18 EOF
19 test_cmp expect actual.err &&
20
21 test_must_fail git -C clone -c fetch.output= fetch origin 2>actual.err &&
22 cat >expect <<-EOF &&
23 fatal: invalid value for ${SQ}fetch.output${SQ}: ${SQ}${SQ}
24 EOF
25 test_cmp expect actual.err &&
26
27 test_must_fail git -C clone -c fetch.output=garbage fetch origin 2>actual.err &&
28 cat >expect <<-EOF &&
29 fatal: invalid value for ${SQ}fetch.output${SQ}: ${SQ}garbage${SQ}
30 EOF
31 test_cmp expect actual.err
32 '
33
34 test_expect_success 'fetch aligned output' '
35 git clone . full-output &&
36 test_commit looooooooooooong-tag &&
37 (
38 cd full-output &&
39 git -c fetch.output=full fetch origin >actual 2>&1 &&
40 grep -e "->" actual | cut -c 22- >../actual
41 ) &&
42 cat >expect <<-\EOF &&
43 main -> origin/main
44 looooooooooooong-tag -> looooooooooooong-tag
45 EOF
46 test_cmp expect actual
47 '
48
49 test_expect_success 'fetch compact output' '
50 git clone . compact &&
51 test_commit extraaa &&
52 (
53 cd compact &&
54 git -c fetch.output=compact fetch origin >actual 2>&1 &&
55 grep -e "->" actual | cut -c 22- >../actual
56 ) &&
57 cat >expect <<-\EOF &&
58 main -> origin/*
59 extraaa -> *
60 EOF
61 test_cmp expect actual
62 '
63
64 test_expect_success 'fetch porcelain output' '
65 test_when_finished "rm -rf porcelain" &&
66
67 # Set up a bunch of references that we can use to demonstrate different
68 # kinds of flag symbols in the output format.
69 MAIN_OLD=$(git rev-parse HEAD) &&
70 git branch "fast-forward" &&
71 git branch "deleted-branch" &&
72 git checkout -b force-updated &&
73 test_commit --no-tag force-update-old &&
74 FORCE_UPDATED_OLD=$(git rev-parse HEAD) &&
75 git checkout main &&
76
77 # Clone and pre-seed the repositories. We fetch references into two
78 # namespaces so that we can test that rejected and force-updated
79 # references are reported properly.
80 refspecs="refs/heads/*:refs/unforced/* +refs/heads/*:refs/forced/*" &&
81 git clone . porcelain &&
82 git -C porcelain fetch origin $refspecs &&
83
84 # Now that we have set up the client repositories we can change our
85 # local references.
86 git branch new-branch &&
87 git branch -d deleted-branch &&
88 git checkout fast-forward &&
89 test_commit --no-tag fast-forward-new &&
90 FAST_FORWARD_NEW=$(git rev-parse HEAD) &&
91 git checkout force-updated &&
92 git reset --hard HEAD~ &&
93 test_commit --no-tag force-update-new &&
94 FORCE_UPDATED_NEW=$(git rev-parse HEAD) &&
95
96 cat >expect <<-EOF &&
97 - $MAIN_OLD $ZERO_OID refs/forced/deleted-branch
98 - $MAIN_OLD $ZERO_OID refs/unforced/deleted-branch
99 $MAIN_OLD $FAST_FORWARD_NEW refs/unforced/fast-forward
100 ! $FORCE_UPDATED_OLD $FORCE_UPDATED_NEW refs/unforced/force-updated
101 * $ZERO_OID $MAIN_OLD refs/unforced/new-branch
102 $MAIN_OLD $FAST_FORWARD_NEW refs/forced/fast-forward
103 + $FORCE_UPDATED_OLD $FORCE_UPDATED_NEW refs/forced/force-updated
104 * $ZERO_OID $MAIN_OLD refs/forced/new-branch
105 $MAIN_OLD $FAST_FORWARD_NEW refs/remotes/origin/fast-forward
106 + $FORCE_UPDATED_OLD $FORCE_UPDATED_NEW refs/remotes/origin/force-updated
107 * $ZERO_OID $MAIN_OLD refs/remotes/origin/new-branch
108 EOF
109
110 # Execute a dry-run fetch first. We do this to assert that the dry-run
111 # and non-dry-run fetches produces the same output. Execution of the
112 # fetch is expected to fail as we have a rejected reference update.
113 test_must_fail git -C porcelain fetch \
114 --porcelain --dry-run --prune origin $refspecs >actual &&
115 test_cmp expect actual &&
116
117 # And now we perform a non-dry-run fetch.
118 test_must_fail git -C porcelain fetch \
119 --porcelain --prune origin $refspecs >actual 2>stderr &&
120 test_cmp expect actual &&
121 test_must_be_empty stderr
122 '
123
124 test_expect_success 'fetch porcelain with multiple remotes' '
125 test_when_finished "rm -rf porcelain" &&
126
127 git switch --create multiple-remotes &&
128 git clone . porcelain &&
129 git -C porcelain remote add second-remote "$PWD" &&
130 git -C porcelain fetch second-remote &&
131
132 test_commit --no-tag multi-commit &&
133 old_commit=$(git rev-parse HEAD~) &&
134 new_commit=$(git rev-parse HEAD) &&
135
136 cat >expect <<-EOF &&
137 $old_commit $new_commit refs/remotes/origin/multiple-remotes
138 $old_commit $new_commit refs/remotes/second-remote/multiple-remotes
139 EOF
140
141 git -C porcelain fetch --porcelain --all >actual 2>stderr &&
142 test_cmp expect actual &&
143 test_must_be_empty stderr
144 '
145
146 test_expect_success 'fetch porcelain refuses to work with submodules' '
147 test_when_finished "rm -rf porcelain" &&
148
149 cat >expect <<-EOF &&
150 fatal: options ${SQ}--porcelain${SQ} and ${SQ}--recurse-submodules${SQ} cannot be used together
151 EOF
152
153 git init porcelain &&
154 test_must_fail git -C porcelain fetch --porcelain --recurse-submodules=yes 2>stderr &&
155 test_cmp expect stderr &&
156
157 test_must_fail git -C porcelain fetch --porcelain --recurse-submodules=on-demand 2>stderr &&
158 test_cmp expect stderr
159 '
160
161 test_expect_success 'fetch porcelain overrides fetch.output config' '
162 test_when_finished "rm -rf porcelain" &&
163
164 git switch --create config-override &&
165 git clone . porcelain &&
166 test_commit new-commit &&
167 old_commit=$(git rev-parse HEAD~) &&
168 new_commit=$(git rev-parse HEAD) &&
169
170 cat >expect <<-EOF &&
171 $old_commit $new_commit refs/remotes/origin/config-override
172 * $ZERO_OID $new_commit refs/tags/new-commit
173 EOF
174
175 git -C porcelain -c fetch.output=compact fetch --porcelain >stdout 2>stderr &&
176 test_must_be_empty stderr &&
177 test_cmp expect stdout
178 '
179
180 test_expect_success 'fetch --no-porcelain overrides previous --porcelain' '
181 test_when_finished "rm -rf no-porcelain" &&
182
183 git switch --create no-porcelain &&
184 git clone . no-porcelain &&
185 test_commit --no-tag no-porcelain &&
186 old_commit=$(git rev-parse --short HEAD~) &&
187 new_commit=$(git rev-parse --short HEAD) &&
188
189 cat >expect <<-EOF &&
190 From $(test-tool path-utils real_path .)/.
191 $old_commit..$new_commit no-porcelain -> origin/no-porcelain
192 EOF
193
194 git -C no-porcelain fetch --porcelain --no-porcelain >stdout 2>stderr &&
195 test_cmp expect stderr &&
196 test_must_be_empty stdout
197 '
198
199 test_expect_success 'fetch output with HEAD' '
200 test_when_finished "rm -rf head" &&
201 git clone . head &&
202
203 git -C head fetch --dry-run origin HEAD >actual.out 2>actual.err &&
204 cat >expect <<-EOF &&
205 From $(test-tool path-utils real_path .)/.
206 * branch HEAD -> FETCH_HEAD
207 EOF
208 test_must_be_empty actual.out &&
209 test_cmp expect actual.err &&
210
211 git -C head fetch origin HEAD >actual.out 2>actual.err &&
212 test_must_be_empty actual.out &&
213 test_cmp expect actual.err &&
214
215 git -C head fetch --dry-run origin HEAD:foo >actual.out 2>actual.err &&
216 cat >expect <<-EOF &&
217 From $(test-tool path-utils real_path .)/.
218 * [new ref] HEAD -> foo
219 EOF
220 test_must_be_empty actual.out &&
221 test_cmp expect actual.err &&
222
223 git -C head fetch origin HEAD:foo >actual.out 2>actual.err &&
224 test_must_be_empty actual.out &&
225 test_cmp expect actual.err
226 '
227
228 test_expect_success 'fetch porcelain output with HEAD' '
229 test_when_finished "rm -rf head" &&
230 git clone . head &&
231 COMMIT_ID=$(git rev-parse HEAD) &&
232
233 git -C head fetch --porcelain --dry-run origin HEAD >actual &&
234 cat >expect <<-EOF &&
235 * $ZERO_OID $COMMIT_ID FETCH_HEAD
236 EOF
237 test_cmp expect actual &&
238
239 git -C head fetch --porcelain origin HEAD >actual &&
240 test_cmp expect actual &&
241
242 git -C head fetch --porcelain --dry-run origin HEAD:foo >actual &&
243 cat >expect <<-EOF &&
244 * $ZERO_OID $COMMIT_ID refs/heads/foo
245 EOF
246 test_cmp expect actual &&
247
248 git -C head fetch --porcelain origin HEAD:foo >actual &&
249 test_cmp expect actual
250 '
251
252 test_expect_success 'fetch output with object ID' '
253 test_when_finished "rm -rf object-id" &&
254 git clone . object-id &&
255 commit=$(git rev-parse HEAD) &&
256
257 git -C object-id fetch --dry-run origin $commit:object-id >actual.out 2>actual.err &&
258 cat >expect <<-EOF &&
259 From $(test-tool path-utils real_path .)/.
260 * [new ref] $commit -> object-id
261 EOF
262 test_must_be_empty actual.out &&
263 test_cmp expect actual.err &&
264
265 git -C object-id fetch origin $commit:object-id >actual.out 2>actual.err &&
266 test_must_be_empty actual.out &&
267 test_cmp expect actual.err
268 '
269
270 test_expect_success '--no-show-forced-updates' '
271 mkdir forced-updates &&
272 (
273 cd forced-updates &&
274 git init &&
275 test_commit 1 &&
276 test_commit 2
277 ) &&
278 git clone forced-updates forced-update-clone &&
279 git clone forced-updates no-forced-update-clone &&
280 git -C forced-updates reset --hard HEAD~1 &&
281 (
282 cd forced-update-clone &&
283 git fetch --show-forced-updates origin 2>output &&
284 test_grep "(forced update)" output
285 ) &&
286 (
287 cd no-forced-update-clone &&
288 git fetch --no-show-forced-updates origin 2>output &&
289 test_grep ! "(forced update)" output
290 )
291 '
292
293 test_done