]>
Commit | Line | Data |
---|---|---|
2c5691d6 PS |
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 | ||
3daf6558 PS |
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 | ||
2c5691d6 PS |
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 | ||
97d82b29 | 64 | test_expect_success 'setup for fetch porcelain output' ' |
dd781e38 PS |
65 | # Set up a bunch of references that we can use to demonstrate different |
66 | # kinds of flag symbols in the output format. | |
97d82b29 | 67 | test_commit commit-for-porcelain-output && |
dd781e38 PS |
68 | MAIN_OLD=$(git rev-parse HEAD) && |
69 | git branch "fast-forward" && | |
70 | git branch "deleted-branch" && | |
71 | git checkout -b force-updated && | |
72 | test_commit --no-tag force-update-old && | |
73 | FORCE_UPDATED_OLD=$(git rev-parse HEAD) && | |
74 | git checkout main && | |
75 | ||
97d82b29 JX |
76 | # Backup to preseed.git |
77 | git clone --mirror . preseed.git && | |
dd781e38 | 78 | |
97d82b29 | 79 | # Continue changing our local references. |
dd781e38 PS |
80 | git branch new-branch && |
81 | git branch -d deleted-branch && | |
82 | git checkout fast-forward && | |
83 | test_commit --no-tag fast-forward-new && | |
84 | FAST_FORWARD_NEW=$(git rev-parse HEAD) && | |
85 | git checkout force-updated && | |
86 | git reset --hard HEAD~ && | |
87 | test_commit --no-tag force-update-new && | |
97d82b29 | 88 | FORCE_UPDATED_NEW=$(git rev-parse HEAD) |
dd781e38 PS |
89 | ' |
90 | ||
97d82b29 JX |
91 | for opt in "" "--atomic" |
92 | do | |
18ce4891 | 93 | test_expect_success "fetch porcelain output ${opt:+(atomic)}" ' |
97d82b29 JX |
94 | test_when_finished "rm -rf porcelain" && |
95 | ||
96 | # Clone and pre-seed the repositories. We fetch references into two | |
97 | # namespaces so that we can test that rejected and force-updated | |
98 | # references are reported properly. | |
99 | refspecs="refs/heads/*:refs/unforced/* +refs/heads/*:refs/forced/*" && | |
100 | git clone preseed.git porcelain && | |
101 | git -C porcelain fetch origin $opt $refspecs && | |
102 | ||
103 | cat >expect <<-EOF && | |
104 | - $MAIN_OLD $ZERO_OID refs/forced/deleted-branch | |
105 | - $MAIN_OLD $ZERO_OID refs/unforced/deleted-branch | |
106 | $MAIN_OLD $FAST_FORWARD_NEW refs/unforced/fast-forward | |
107 | ! $FORCE_UPDATED_OLD $FORCE_UPDATED_NEW refs/unforced/force-updated | |
108 | * $ZERO_OID $MAIN_OLD refs/unforced/new-branch | |
109 | $MAIN_OLD $FAST_FORWARD_NEW refs/forced/fast-forward | |
110 | + $FORCE_UPDATED_OLD $FORCE_UPDATED_NEW refs/forced/force-updated | |
111 | * $ZERO_OID $MAIN_OLD refs/forced/new-branch | |
112 | $MAIN_OLD $FAST_FORWARD_NEW refs/remotes/origin/fast-forward | |
113 | + $FORCE_UPDATED_OLD $FORCE_UPDATED_NEW refs/remotes/origin/force-updated | |
114 | * $ZERO_OID $MAIN_OLD refs/remotes/origin/new-branch | |
115 | EOF | |
116 | ||
117 | # Change the URL of the repository to fetch different references. | |
118 | git -C porcelain remote set-url origin .. && | |
119 | ||
120 | # Execute a dry-run fetch first. We do this to assert that the dry-run | |
121 | # and non-dry-run fetches produces the same output. Execution of the | |
122 | # fetch is expected to fail as we have a rejected reference update. | |
123 | test_must_fail git -C porcelain fetch $opt \ | |
124 | --porcelain --dry-run --prune origin $refspecs >actual && | |
125 | test_cmp expect actual && | |
126 | ||
127 | # And now we perform a non-dry-run fetch. | |
128 | test_must_fail git -C porcelain fetch $opt \ | |
129 | --porcelain --prune origin $refspecs >actual 2>stderr && | |
130 | test_cmp expect actual && | |
131 | test_must_be_empty stderr | |
132 | ' | |
133 | done | |
134 | ||
dd781e38 PS |
135 | test_expect_success 'fetch porcelain with multiple remotes' ' |
136 | test_when_finished "rm -rf porcelain" && | |
137 | ||
138 | git switch --create multiple-remotes && | |
139 | git clone . porcelain && | |
140 | git -C porcelain remote add second-remote "$PWD" && | |
141 | git -C porcelain fetch second-remote && | |
142 | ||
143 | test_commit --no-tag multi-commit && | |
144 | old_commit=$(git rev-parse HEAD~) && | |
145 | new_commit=$(git rev-parse HEAD) && | |
146 | ||
147 | cat >expect <<-EOF && | |
148 | $old_commit $new_commit refs/remotes/origin/multiple-remotes | |
149 | $old_commit $new_commit refs/remotes/second-remote/multiple-remotes | |
150 | EOF | |
151 | ||
152 | git -C porcelain fetch --porcelain --all >actual 2>stderr && | |
153 | test_cmp expect actual && | |
154 | test_must_be_empty stderr | |
155 | ' | |
156 | ||
157 | test_expect_success 'fetch porcelain refuses to work with submodules' ' | |
158 | test_when_finished "rm -rf porcelain" && | |
159 | ||
160 | cat >expect <<-EOF && | |
161 | fatal: options ${SQ}--porcelain${SQ} and ${SQ}--recurse-submodules${SQ} cannot be used together | |
162 | EOF | |
163 | ||
164 | git init porcelain && | |
165 | test_must_fail git -C porcelain fetch --porcelain --recurse-submodules=yes 2>stderr && | |
166 | test_cmp expect stderr && | |
167 | ||
168 | test_must_fail git -C porcelain fetch --porcelain --recurse-submodules=on-demand 2>stderr && | |
169 | test_cmp expect stderr | |
170 | ' | |
171 | ||
172 | test_expect_success 'fetch porcelain overrides fetch.output config' ' | |
173 | test_when_finished "rm -rf porcelain" && | |
174 | ||
175 | git switch --create config-override && | |
176 | git clone . porcelain && | |
177 | test_commit new-commit && | |
178 | old_commit=$(git rev-parse HEAD~) && | |
179 | new_commit=$(git rev-parse HEAD) && | |
180 | ||
181 | cat >expect <<-EOF && | |
182 | $old_commit $new_commit refs/remotes/origin/config-override | |
183 | * $ZERO_OID $new_commit refs/tags/new-commit | |
184 | EOF | |
185 | ||
186 | git -C porcelain -c fetch.output=compact fetch --porcelain >stdout 2>stderr && | |
187 | test_must_be_empty stderr && | |
188 | test_cmp expect stdout | |
189 | ' | |
190 | ||
191 | test_expect_success 'fetch --no-porcelain overrides previous --porcelain' ' | |
192 | test_when_finished "rm -rf no-porcelain" && | |
193 | ||
194 | git switch --create no-porcelain && | |
195 | git clone . no-porcelain && | |
196 | test_commit --no-tag no-porcelain && | |
197 | old_commit=$(git rev-parse --short HEAD~) && | |
198 | new_commit=$(git rev-parse --short HEAD) && | |
199 | ||
200 | cat >expect <<-EOF && | |
201 | From $(test-tool path-utils real_path .)/. | |
202 | $old_commit..$new_commit no-porcelain -> origin/no-porcelain | |
203 | EOF | |
204 | ||
205 | git -C no-porcelain fetch --porcelain --no-porcelain >stdout 2>stderr && | |
206 | test_cmp expect stderr && | |
207 | test_must_be_empty stdout | |
208 | ' | |
209 | ||
1c31764d PS |
210 | test_expect_success 'fetch output with HEAD' ' |
211 | test_when_finished "rm -rf head" && | |
212 | git clone . head && | |
213 | ||
214 | git -C head fetch --dry-run origin HEAD >actual.out 2>actual.err && | |
215 | cat >expect <<-EOF && | |
216 | From $(test-tool path-utils real_path .)/. | |
217 | * branch HEAD -> FETCH_HEAD | |
218 | EOF | |
219 | test_must_be_empty actual.out && | |
220 | test_cmp expect actual.err && | |
221 | ||
222 | git -C head fetch origin HEAD >actual.out 2>actual.err && | |
223 | test_must_be_empty actual.out && | |
224 | test_cmp expect actual.err && | |
225 | ||
226 | git -C head fetch --dry-run origin HEAD:foo >actual.out 2>actual.err && | |
227 | cat >expect <<-EOF && | |
228 | From $(test-tool path-utils real_path .)/. | |
229 | * [new ref] HEAD -> foo | |
230 | EOF | |
231 | test_must_be_empty actual.out && | |
232 | test_cmp expect actual.err && | |
233 | ||
234 | git -C head fetch origin HEAD:foo >actual.out 2>actual.err && | |
235 | test_must_be_empty actual.out && | |
236 | test_cmp expect actual.err | |
237 | ' | |
238 | ||
dd781e38 PS |
239 | test_expect_success 'fetch porcelain output with HEAD' ' |
240 | test_when_finished "rm -rf head" && | |
241 | git clone . head && | |
242 | COMMIT_ID=$(git rev-parse HEAD) && | |
243 | ||
244 | git -C head fetch --porcelain --dry-run origin HEAD >actual && | |
245 | cat >expect <<-EOF && | |
246 | * $ZERO_OID $COMMIT_ID FETCH_HEAD | |
247 | EOF | |
248 | test_cmp expect actual && | |
249 | ||
250 | git -C head fetch --porcelain origin HEAD >actual && | |
251 | test_cmp expect actual && | |
252 | ||
253 | git -C head fetch --porcelain --dry-run origin HEAD:foo >actual && | |
254 | cat >expect <<-EOF && | |
255 | * $ZERO_OID $COMMIT_ID refs/heads/foo | |
256 | EOF | |
257 | test_cmp expect actual && | |
258 | ||
259 | git -C head fetch --porcelain origin HEAD:foo >actual && | |
260 | test_cmp expect actual | |
261 | ' | |
262 | ||
1c31764d PS |
263 | test_expect_success 'fetch output with object ID' ' |
264 | test_when_finished "rm -rf object-id" && | |
265 | git clone . object-id && | |
266 | commit=$(git rev-parse HEAD) && | |
267 | ||
268 | git -C object-id fetch --dry-run origin $commit:object-id >actual.out 2>actual.err && | |
269 | cat >expect <<-EOF && | |
270 | From $(test-tool path-utils real_path .)/. | |
271 | * [new ref] $commit -> object-id | |
272 | EOF | |
273 | test_must_be_empty actual.out && | |
274 | test_cmp expect actual.err && | |
275 | ||
276 | git -C object-id fetch origin $commit:object-id >actual.out 2>actual.err && | |
277 | test_must_be_empty actual.out && | |
278 | test_cmp expect actual.err | |
279 | ' | |
280 | ||
2c5691d6 PS |
281 | test_expect_success '--no-show-forced-updates' ' |
282 | mkdir forced-updates && | |
283 | ( | |
284 | cd forced-updates && | |
285 | git init && | |
286 | test_commit 1 && | |
287 | test_commit 2 | |
288 | ) && | |
289 | git clone forced-updates forced-update-clone && | |
290 | git clone forced-updates no-forced-update-clone && | |
291 | git -C forced-updates reset --hard HEAD~1 && | |
292 | ( | |
293 | cd forced-update-clone && | |
294 | git fetch --show-forced-updates origin 2>output && | |
6789275d | 295 | test_grep "(forced update)" output |
2c5691d6 PS |
296 | ) && |
297 | ( | |
298 | cd no-forced-update-clone && | |
299 | git fetch --no-show-forced-updates origin 2>output && | |
6789275d | 300 | test_grep ! "(forced update)" output |
2c5691d6 PS |
301 | ) |
302 | ' | |
303 | ||
304 | test_done |