]>
Commit | Line | Data |
---|---|---|
caf3827e JH |
1 | #!/bin/sh |
2 | ||
3 | test_description='git rev-list using object filtering' | |
4 | ||
1550bb6e | 5 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main |
334afbc7 JS |
6 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME |
7 | ||
caf3827e JH |
8 | . ./test-lib.sh |
9 | ||
10 | # Test the blob:none filter. | |
11 | ||
12 | test_expect_success 'setup r1' ' | |
13 | echo "{print \$1}" >print_1.awk && | |
14 | echo "{print \$2}" >print_2.awk && | |
15 | ||
16 | git init r1 && | |
17 | for n in 1 2 3 4 5 | |
18 | do | |
74d2f569 ES |
19 | echo "This is file: $n" > r1/file.$n && |
20 | git -C r1 add file.$n && | |
0c51d6b4 | 21 | git -C r1 commit -m "$n" || return 1 |
caf3827e JH |
22 | done |
23 | ' | |
24 | ||
25 | test_expect_success 'verify blob:none omits all 5 blobs' ' | |
61de0ff6 MD |
26 | git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 \ |
27 | >ls_files_result && | |
28 | awk -f print_2.awk ls_files_result | | |
bdbc17e8 MD |
29 | sort >expected && |
30 | ||
8d6ba495 MD |
31 | git -C r1 rev-list --quiet --objects --filter-print-omitted \ |
32 | --filter=blob:none HEAD >revs && | |
61de0ff6 | 33 | awk -f print_1.awk revs | |
bdbc17e8 MD |
34 | sed "s/~//" | |
35 | sort >observed && | |
36 | ||
dcbaa0b3 | 37 | test_cmp expected observed |
caf3827e JH |
38 | ' |
39 | ||
99c9aa95 MD |
40 | test_expect_success 'specify blob explicitly prevents filtering' ' |
41 | file_3=$(git -C r1 ls-files -s file.3 | | |
42 | awk -f print_2.awk) && | |
43 | ||
44 | file_4=$(git -C r1 ls-files -s file.4 | | |
45 | awk -f print_2.awk) && | |
46 | ||
47 | git -C r1 rev-list --objects --filter=blob:none HEAD $file_3 >observed && | |
d9e6d094 MD |
48 | grep "$file_3" observed && |
49 | ! grep "$file_4" observed | |
99c9aa95 MD |
50 | ' |
51 | ||
caf3827e | 52 | test_expect_success 'verify emitted+omitted == all' ' |
8d6ba495 | 53 | git -C r1 rev-list --objects HEAD >revs && |
61de0ff6 | 54 | awk -f print_1.awk revs | |
bdbc17e8 MD |
55 | sort >expected && |
56 | ||
8d6ba495 MD |
57 | git -C r1 rev-list --objects --filter-print-omitted --filter=blob:none \ |
58 | HEAD >revs && | |
61de0ff6 | 59 | awk -f print_1.awk revs | |
bdbc17e8 MD |
60 | sed "s/~//" | |
61 | sort >observed && | |
62 | ||
dcbaa0b3 | 63 | test_cmp expected observed |
caf3827e JH |
64 | ' |
65 | ||
66 | ||
67 | # Test blob:limit=<n>[kmg] filter. | |
68 | # We boundary test around the size parameter. The filter is strictly less than | |
69 | # the value, so size 500 and 1000 should have the same results, but 1001 should | |
70 | # filter more. | |
71 | ||
72 | test_expect_success 'setup r2' ' | |
73 | git init r2 && | |
74 | for n in 1000 10000 | |
75 | do | |
74d2f569 ES |
76 | printf "%"$n"s" X > r2/large.$n && |
77 | git -C r2 add large.$n && | |
0c51d6b4 | 78 | git -C r2 commit -m "$n" || return 1 |
caf3827e JH |
79 | done |
80 | ' | |
81 | ||
82 | test_expect_success 'verify blob:limit=500 omits all blobs' ' | |
61de0ff6 MD |
83 | git -C r2 ls-files -s large.1000 large.10000 >ls_files_result && |
84 | awk -f print_2.awk ls_files_result | | |
bdbc17e8 MD |
85 | sort >expected && |
86 | ||
8d6ba495 MD |
87 | git -C r2 rev-list --quiet --objects --filter-print-omitted \ |
88 | --filter=blob:limit=500 HEAD >revs && | |
61de0ff6 | 89 | awk -f print_1.awk revs | |
bdbc17e8 MD |
90 | sed "s/~//" | |
91 | sort >observed && | |
92 | ||
dcbaa0b3 | 93 | test_cmp expected observed |
caf3827e JH |
94 | ' |
95 | ||
96 | test_expect_success 'verify emitted+omitted == all' ' | |
8d6ba495 | 97 | git -C r2 rev-list --objects HEAD >revs && |
61de0ff6 | 98 | awk -f print_1.awk revs | |
bdbc17e8 MD |
99 | sort >expected && |
100 | ||
8d6ba495 MD |
101 | git -C r2 rev-list --objects --filter-print-omitted \ |
102 | --filter=blob:limit=500 HEAD >revs && | |
61de0ff6 | 103 | awk -f print_1.awk revs | |
bdbc17e8 MD |
104 | sed "s/~//" | |
105 | sort >observed && | |
106 | ||
dcbaa0b3 | 107 | test_cmp expected observed |
caf3827e JH |
108 | ' |
109 | ||
110 | test_expect_success 'verify blob:limit=1000' ' | |
61de0ff6 MD |
111 | git -C r2 ls-files -s large.1000 large.10000 >ls_files_result && |
112 | awk -f print_2.awk ls_files_result | | |
bdbc17e8 MD |
113 | sort >expected && |
114 | ||
8d6ba495 MD |
115 | git -C r2 rev-list --quiet --objects --filter-print-omitted \ |
116 | --filter=blob:limit=1000 HEAD >revs && | |
61de0ff6 | 117 | awk -f print_1.awk revs | |
bdbc17e8 MD |
118 | sed "s/~//" | |
119 | sort >observed && | |
120 | ||
dcbaa0b3 | 121 | test_cmp expected observed |
caf3827e JH |
122 | ' |
123 | ||
124 | test_expect_success 'verify blob:limit=1001' ' | |
61de0ff6 MD |
125 | git -C r2 ls-files -s large.10000 >ls_files_result && |
126 | awk -f print_2.awk ls_files_result | | |
bdbc17e8 MD |
127 | sort >expected && |
128 | ||
8d6ba495 MD |
129 | git -C r2 rev-list --quiet --objects --filter-print-omitted \ |
130 | --filter=blob:limit=1001 HEAD >revs && | |
61de0ff6 | 131 | awk -f print_1.awk revs | |
bdbc17e8 MD |
132 | sed "s/~//" | |
133 | sort >observed && | |
134 | ||
dcbaa0b3 | 135 | test_cmp expected observed |
caf3827e JH |
136 | ' |
137 | ||
138 | test_expect_success 'verify blob:limit=1k' ' | |
61de0ff6 MD |
139 | git -C r2 ls-files -s large.10000 >ls_files_result && |
140 | awk -f print_2.awk ls_files_result | | |
bdbc17e8 MD |
141 | sort >expected && |
142 | ||
8d6ba495 MD |
143 | git -C r2 rev-list --quiet --objects --filter-print-omitted \ |
144 | --filter=blob:limit=1k HEAD >revs && | |
61de0ff6 | 145 | awk -f print_1.awk revs | |
bdbc17e8 MD |
146 | sed "s/~//" | |
147 | sort >observed && | |
148 | ||
dcbaa0b3 | 149 | test_cmp expected observed |
caf3827e JH |
150 | ' |
151 | ||
152 | test_expect_success 'verify blob:limit=1m' ' | |
8d6ba495 MD |
153 | git -C r2 rev-list --quiet --objects --filter-print-omitted \ |
154 | --filter=blob:limit=1m HEAD >revs && | |
61de0ff6 | 155 | awk -f print_1.awk revs | |
bdbc17e8 MD |
156 | sed "s/~//" | |
157 | sort >observed && | |
158 | ||
1c5e94f4 | 159 | test_must_be_empty observed |
caf3827e JH |
160 | ' |
161 | ||
b0c42a53 PS |
162 | # Test object:type=<type> filter. |
163 | ||
164 | test_expect_success 'setup object-type' ' | |
165 | test_create_repo object-type && | |
166 | test_commit --no-tag -C object-type message blob && | |
167 | git -C object-type tag tag -m tag-message | |
168 | ' | |
169 | ||
170 | test_expect_success 'verify object:type= fails with invalid type' ' | |
171 | test_must_fail git -C object-type rev-list --objects --filter=object:type= HEAD && | |
172 | test_must_fail git -C object-type rev-list --objects --filter=object:type=invalid HEAD | |
173 | ' | |
174 | ||
175 | test_expect_success 'verify object:type=blob prints blob and commit' ' | |
176 | git -C object-type rev-parse HEAD >expected && | |
177 | printf "%s blob\n" $(git -C object-type rev-parse HEAD:blob) >>expected && | |
178 | git -C object-type rev-list --objects --filter=object:type=blob HEAD >actual && | |
179 | test_cmp expected actual | |
180 | ' | |
181 | ||
182 | test_expect_success 'verify object:type=tree prints tree and commit' ' | |
183 | ( | |
184 | git -C object-type rev-parse HEAD && | |
185 | printf "%s \n" $(git -C object-type rev-parse HEAD^{tree}) | |
186 | ) >expected && | |
187 | git -C object-type rev-list --objects --filter=object:type=tree HEAD >actual && | |
188 | test_cmp expected actual | |
189 | ' | |
190 | ||
191 | test_expect_success 'verify object:type=commit prints commit' ' | |
192 | git -C object-type rev-parse HEAD >expected && | |
193 | git -C object-type rev-list --objects --filter=object:type=commit HEAD >actual && | |
194 | test_cmp expected actual | |
195 | ' | |
196 | ||
197 | test_expect_success 'verify object:type=tag prints tag' ' | |
198 | ( | |
199 | git -C object-type rev-parse HEAD && | |
200 | printf "%s tag\n" $(git -C object-type rev-parse tag) | |
201 | ) >expected && | |
202 | git -C object-type rev-list --objects --filter=object:type=tag tag >actual && | |
203 | test_cmp expected actual | |
204 | ' | |
205 | ||
9cf68b27 PS |
206 | test_expect_success 'verify object:type=blob prints only blob with --filter-provided-objects' ' |
207 | printf "%s blob\n" $(git -C object-type rev-parse HEAD:blob) >expected && | |
208 | git -C object-type rev-list --objects \ | |
209 | --filter=object:type=blob --filter-provided-objects HEAD >actual && | |
210 | test_cmp expected actual | |
211 | ' | |
212 | ||
213 | test_expect_success 'verify object:type=tree prints only tree with --filter-provided-objects' ' | |
214 | printf "%s \n" $(git -C object-type rev-parse HEAD^{tree}) >expected && | |
215 | git -C object-type rev-list --objects \ | |
216 | --filter=object:type=tree HEAD --filter-provided-objects >actual && | |
217 | test_cmp expected actual | |
218 | ' | |
219 | ||
220 | test_expect_success 'verify object:type=commit prints only commit with --filter-provided-objects' ' | |
221 | git -C object-type rev-parse HEAD >expected && | |
222 | git -C object-type rev-list --objects \ | |
223 | --filter=object:type=commit --filter-provided-objects HEAD >actual && | |
224 | test_cmp expected actual | |
225 | ' | |
226 | ||
227 | test_expect_success 'verify object:type=tag prints only tag with --filter-provided-objects' ' | |
228 | printf "%s tag\n" $(git -C object-type rev-parse tag) >expected && | |
229 | git -C object-type rev-list --objects \ | |
230 | --filter=object:type=tag --filter-provided-objects tag >actual && | |
231 | test_cmp expected actual | |
232 | ' | |
233 | ||
caf3827e | 234 | # Test sparse:path=<path> filter. |
e693237e CC |
235 | # !!!! |
236 | # NOTE: sparse:path filter support has been dropped for security reasons, | |
237 | # so the tests have been changed to make sure that using it fails. | |
238 | # !!!! | |
caf3827e JH |
239 | # Use a local file containing a sparse-checkout specification to filter |
240 | # out blobs not required for the corresponding sparse-checkout. We do not | |
241 | # require sparse-checkout to actually be enabled. | |
242 | ||
243 | test_expect_success 'setup r3' ' | |
244 | git init r3 && | |
245 | mkdir r3/dir1 && | |
246 | for n in sparse1 sparse2 | |
247 | do | |
74d2f569 ES |
248 | echo "This is file: $n" > r3/$n && |
249 | git -C r3 add $n && | |
250 | echo "This is file: dir1/$n" > r3/dir1/$n && | |
0c51d6b4 | 251 | git -C r3 add dir1/$n || return 1 |
caf3827e JH |
252 | done && |
253 | git -C r3 commit -m "sparse" && | |
254 | echo dir1/ >pattern1 && | |
255 | echo sparse1 >pattern2 | |
256 | ' | |
257 | ||
e693237e CC |
258 | test_expect_success 'verify sparse:path=pattern1 fails' ' |
259 | test_must_fail git -C r3 rev-list --quiet --objects \ | |
260 | --filter-print-omitted --filter=sparse:path=../pattern1 HEAD | |
caf3827e JH |
261 | ' |
262 | ||
e693237e CC |
263 | test_expect_success 'verify sparse:path=pattern2 fails' ' |
264 | test_must_fail git -C r3 rev-list --quiet --objects \ | |
265 | --filter-print-omitted --filter=sparse:path=../pattern2 HEAD | |
caf3827e JH |
266 | ' |
267 | ||
268 | # Test sparse:oid=<oid-ish> filter. | |
e693237e CC |
269 | # Use a blob containing a sparse-checkout specification to filter |
270 | # out blobs not required for the corresponding sparse-checkout. We do not | |
271 | # require sparse-checkout to actually be enabled. | |
caf3827e JH |
272 | |
273 | test_expect_success 'setup r3 part 2' ' | |
274 | echo dir1/ >r3/pattern && | |
275 | git -C r3 add pattern && | |
276 | git -C r3 commit -m "pattern" | |
277 | ' | |
278 | ||
279 | test_expect_success 'verify sparse:oid=OID omits top-level files' ' | |
61de0ff6 MD |
280 | git -C r3 ls-files -s pattern sparse1 sparse2 >ls_files_result && |
281 | awk -f print_2.awk ls_files_result | | |
bdbc17e8 MD |
282 | sort >expected && |
283 | ||
caf3827e | 284 | oid=$(git -C r3 ls-files -s pattern | awk -f print_2.awk) && |
bdbc17e8 | 285 | |
8d6ba495 MD |
286 | git -C r3 rev-list --quiet --objects --filter-print-omitted \ |
287 | --filter=sparse:oid=$oid HEAD >revs && | |
61de0ff6 | 288 | awk -f print_1.awk revs | |
bdbc17e8 MD |
289 | sed "s/~//" | |
290 | sort >observed && | |
291 | ||
dcbaa0b3 | 292 | test_cmp expected observed |
caf3827e JH |
293 | ' |
294 | ||
295 | test_expect_success 'verify sparse:oid=oid-ish omits top-level files' ' | |
61de0ff6 MD |
296 | git -C r3 ls-files -s pattern sparse1 sparse2 >ls_files_result && |
297 | awk -f print_2.awk ls_files_result | | |
bdbc17e8 MD |
298 | sort >expected && |
299 | ||
8d6ba495 | 300 | git -C r3 rev-list --quiet --objects --filter-print-omitted \ |
1550bb6e | 301 | --filter=sparse:oid=main:pattern HEAD >revs && |
61de0ff6 | 302 | awk -f print_1.awk revs | |
bdbc17e8 MD |
303 | sed "s/~//" | |
304 | sort >observed && | |
305 | ||
dcbaa0b3 | 306 | test_cmp expected observed |
caf3827e JH |
307 | ' |
308 | ||
7c0fe330 MD |
309 | test_expect_success 'rev-list W/ --missing=print and --missing=allow-any for trees' ' |
310 | TREE=$(git -C r3 rev-parse HEAD:dir1) && | |
311 | ||
312 | # Create a spare repo because we will be deleting objects from this one. | |
313 | git clone r3 r3.b && | |
314 | ||
315 | rm r3.b/.git/objects/$(echo $TREE | sed "s|^..|&/|") && | |
316 | ||
317 | git -C r3.b rev-list --quiet --missing=print --objects HEAD \ | |
318 | >missing_objs 2>rev_list_err && | |
319 | echo "?$TREE" >expected && | |
320 | test_cmp expected missing_objs && | |
321 | ||
322 | # do not complain when a missing tree cannot be parsed | |
323 | test_must_be_empty rev_list_err && | |
324 | ||
325 | git -C r3.b rev-list --missing=allow-any --objects HEAD \ | |
326 | >objs 2>rev_list_err && | |
327 | ! grep $TREE objs && | |
328 | test_must_be_empty rev_list_err | |
329 | ' | |
330 | ||
bc5975d2 MD |
331 | # Test tree:0 filter. |
332 | ||
333 | test_expect_success 'verify tree:0 includes trees in "filtered" output' ' | |
334 | git -C r3 rev-list --quiet --objects --filter-print-omitted \ | |
335 | --filter=tree:0 HEAD >revs && | |
336 | ||
337 | awk -f print_1.awk revs | | |
338 | sed s/~// | | |
339 | xargs -n1 git -C r3 cat-file -t >unsorted_filtered_types && | |
340 | ||
341 | sort -u unsorted_filtered_types >filtered_types && | |
d9e6d094 | 342 | test_write_lines blob tree >expected && |
bc5975d2 MD |
343 | test_cmp expected filtered_types |
344 | ' | |
345 | ||
8b10a206 MD |
346 | # Make sure tree:0 does not iterate through any trees. |
347 | ||
8272f260 | 348 | test_expect_success 'verify skipping tree iteration when not collecting omits' ' |
8b10a206 MD |
349 | GIT_TRACE=1 git -C r3 rev-list \ |
350 | --objects --filter=tree:0 HEAD 2>filter_trace && | |
351 | grep "Skipping contents of tree [.][.][.]" filter_trace >actual && | |
352 | # One line for each commit traversed. | |
353 | test_line_count = 2 actual && | |
354 | ||
355 | # Make sure no other trees were considered besides the root. | |
e987df5f MD |
356 | ! grep "Skipping contents of tree [^.]" filter_trace && |
357 | ||
358 | # Try this again with "combine:". If both sub-filters are skipping | |
359 | # trees, the composite filter should also skip trees. This is not | |
360 | # important unless the user does combine:tree:X+tree:Y or another filter | |
361 | # besides "tree:" is implemented in the future which can skip trees. | |
362 | GIT_TRACE=1 git -C r3 rev-list \ | |
363 | --objects --filter=combine:tree:1+tree:3 HEAD 2>filter_trace && | |
364 | ||
365 | # Only skip the dir1/ tree, which is shared between the two commits. | |
366 | grep "Skipping contents of tree " filter_trace >actual && | |
367 | test_write_lines "Skipping contents of tree dir1/..." >expected && | |
368 | test_cmp expected actual | |
8b10a206 MD |
369 | ' |
370 | ||
c813a7c3 MD |
371 | # Test tree:# filters. |
372 | ||
373 | expect_has () { | |
374 | commit=$1 && | |
375 | name=$2 && | |
376 | ||
377 | hash=$(git -C r3 rev-parse $commit:$name) && | |
378 | grep "^$hash $name$" actual | |
379 | } | |
380 | ||
381 | test_expect_success 'verify tree:1 includes root trees' ' | |
382 | git -C r3 rev-list --objects --filter=tree:1 HEAD >actual && | |
383 | ||
384 | # We should get two root directories and two commits. | |
385 | expect_has HEAD "" && | |
386 | expect_has HEAD~1 "" && | |
387 | test_line_count = 4 actual | |
388 | ' | |
389 | ||
390 | test_expect_success 'verify tree:2 includes root trees and immediate children' ' | |
391 | git -C r3 rev-list --objects --filter=tree:2 HEAD >actual && | |
392 | ||
393 | expect_has HEAD "" && | |
394 | expect_has HEAD~1 "" && | |
395 | expect_has HEAD dir1 && | |
396 | expect_has HEAD pattern && | |
397 | expect_has HEAD sparse1 && | |
398 | expect_has HEAD sparse2 && | |
399 | ||
400 | # There are also 2 commit objects | |
401 | test_line_count = 8 actual | |
402 | ' | |
403 | ||
404 | test_expect_success 'verify tree:3 includes everything expected' ' | |
405 | git -C r3 rev-list --objects --filter=tree:3 HEAD >actual && | |
406 | ||
407 | expect_has HEAD "" && | |
408 | expect_has HEAD~1 "" && | |
409 | expect_has HEAD dir1 && | |
410 | expect_has HEAD dir1/sparse1 && | |
411 | expect_has HEAD dir1/sparse2 && | |
412 | expect_has HEAD pattern && | |
413 | expect_has HEAD sparse1 && | |
414 | expect_has HEAD sparse2 && | |
415 | ||
416 | # There are also 2 commit objects | |
417 | test_line_count = 10 actual | |
418 | ' | |
419 | ||
e987df5f MD |
420 | test_expect_success 'combine:... for a simple combination' ' |
421 | git -C r3 rev-list --objects --filter=combine:tree:2+blob:none HEAD \ | |
422 | >actual && | |
423 | ||
424 | expect_has HEAD "" && | |
425 | expect_has HEAD~1 "" && | |
426 | expect_has HEAD dir1 && | |
427 | ||
428 | # There are also 2 commit objects | |
489fc9ee MD |
429 | test_line_count = 5 actual && |
430 | ||
431 | cp actual expected && | |
432 | ||
433 | # Try again using repeated --filter - this is equivalent to a manual | |
434 | # combine with "combine:...+..." | |
435 | git -C r3 rev-list --objects --filter=combine:tree:2 \ | |
436 | --filter=blob:none HEAD >actual && | |
437 | ||
438 | test_cmp expected actual | |
e987df5f MD |
439 | ' |
440 | ||
441 | test_expect_success 'combine:... with URL encoding' ' | |
442 | git -C r3 rev-list --objects \ | |
443 | --filter=combine:tree%3a2+blob:%6Eon%65 HEAD >actual && | |
444 | ||
445 | expect_has HEAD "" && | |
446 | expect_has HEAD~1 "" && | |
447 | expect_has HEAD dir1 && | |
448 | ||
449 | # There are also 2 commit objects | |
450 | test_line_count = 5 actual | |
451 | ' | |
452 | ||
453 | expect_invalid_filter_spec () { | |
454 | spec="$1" && | |
455 | err="$2" && | |
456 | ||
457 | test_must_fail git -C r3 rev-list --objects --filter="$spec" HEAD \ | |
458 | >actual 2>actual_stderr && | |
459 | test_must_be_empty actual && | |
6789275d | 460 | test_grep "$err" actual_stderr |
e987df5f MD |
461 | } |
462 | ||
463 | test_expect_success 'combine:... while URL-encoding things that should not be' ' | |
464 | expect_invalid_filter_spec combine%3Atree:2+blob:none \ | |
465 | "invalid filter-spec" | |
466 | ' | |
467 | ||
468 | test_expect_success 'combine: with nothing after the :' ' | |
469 | expect_invalid_filter_spec combine: "expected something after combine:" | |
470 | ' | |
471 | ||
472 | test_expect_success 'parse error in first sub-filter in combine:' ' | |
473 | expect_invalid_filter_spec combine:tree:asdf+blob:none \ | |
474 | "expected .tree:<depth>." | |
475 | ' | |
476 | ||
477 | test_expect_success 'combine:... with non-encoded reserved chars' ' | |
478 | expect_invalid_filter_spec combine:tree:2+sparse:@xyz \ | |
479 | "must escape char in sub-filter-spec: .@." && | |
480 | expect_invalid_filter_spec combine:tree:2+sparse:\` \ | |
481 | "must escape char in sub-filter-spec: .\`." && | |
482 | expect_invalid_filter_spec combine:tree:2+sparse:~abc \ | |
483 | "must escape char in sub-filter-spec: .\~." | |
484 | ' | |
485 | ||
486 | test_expect_success 'validate err msg for "combine:<valid-filter>+"' ' | |
487 | expect_invalid_filter_spec combine:tree:2+ "expected .tree:<depth>." | |
488 | ' | |
489 | ||
490 | test_expect_success 'combine:... with edge-case hex digits: Ff Aa 0 9' ' | |
491 | git -C r3 rev-list --objects --filter="combine:tree:2+bl%6Fb:n%6fne" \ | |
492 | HEAD >actual && | |
493 | test_line_count = 5 actual && | |
494 | git -C r3 rev-list --objects --filter="combine:tree%3A2+blob%3anone" \ | |
495 | HEAD >actual && | |
496 | test_line_count = 5 actual && | |
497 | git -C r3 rev-list --objects --filter="combine:tree:%30" HEAD >actual && | |
498 | test_line_count = 2 actual && | |
499 | git -C r3 rev-list --objects --filter="combine:tree:%39+blob:none" \ | |
500 | HEAD >actual && | |
501 | test_line_count = 5 actual | |
502 | ' | |
503 | ||
489fc9ee | 504 | test_expect_success 'add sparse pattern blobs whose paths have reserved chars' ' |
e987df5f | 505 | cp r3/pattern r3/pattern1+renamed% && |
489fc9ee MD |
506 | cp r3/pattern "r3/p;at%ter+n" && |
507 | cp r3/pattern r3/^~pattern && | |
508 | git -C r3 add pattern1+renamed% "p;at%ter+n" ^~pattern && | |
509 | git -C r3 commit -m "add sparse pattern files with reserved chars" | |
e987df5f MD |
510 | ' |
511 | ||
512 | test_expect_success 'combine:... with more than two sub-filters' ' | |
513 | git -C r3 rev-list --objects \ | |
1550bb6e | 514 | --filter=combine:tree:3+blob:limit=40+sparse:oid=main:pattern \ |
e987df5f MD |
515 | HEAD >actual && |
516 | ||
517 | expect_has HEAD "" && | |
518 | expect_has HEAD~1 "" && | |
519 | expect_has HEAD~2 "" && | |
520 | expect_has HEAD dir1 && | |
521 | expect_has HEAD dir1/sparse1 && | |
522 | expect_has HEAD dir1/sparse2 && | |
523 | ||
524 | # Should also have 3 commits | |
525 | test_line_count = 9 actual && | |
526 | ||
527 | # Try again, this time making sure the last sub-filter is only | |
528 | # URL-decoded once. | |
529 | cp actual expect && | |
530 | ||
531 | git -C r3 rev-list --objects \ | |
1550bb6e | 532 | --filter=combine:tree:3+blob:limit=40+sparse:oid=main:pattern1%2brenamed%25 \ |
e987df5f | 533 | HEAD >actual && |
489fc9ee MD |
534 | test_cmp expect actual && |
535 | ||
536 | # Use the same composite filter again, but with a pattern file name that | |
537 | # requires encoding multiple characters, and use implicit filter | |
538 | # combining. | |
539 | test_when_finished "rm -f trace1" && | |
540 | GIT_TRACE=$(pwd)/trace1 git -C r3 rev-list --objects \ | |
541 | --filter=tree:3 --filter=blob:limit=40 \ | |
1550bb6e | 542 | --filter=sparse:oid="main:p;at%ter+n" \ |
489fc9ee MD |
543 | HEAD >actual && |
544 | ||
545 | test_cmp expect actual && | |
1550bb6e | 546 | grep "Add to combine filter-spec: sparse:oid=main:p%3bat%25ter%2bn" \ |
489fc9ee MD |
547 | trace1 && |
548 | ||
549 | # Repeat the above test, but this time, the characters to encode are in | |
550 | # the LHS of the combined filter. | |
551 | test_when_finished "rm -f trace2" && | |
552 | GIT_TRACE=$(pwd)/trace2 git -C r3 rev-list --objects \ | |
1550bb6e | 553 | --filter=sparse:oid=main:^~pattern \ |
489fc9ee MD |
554 | --filter=tree:3 --filter=blob:limit=40 \ |
555 | HEAD >actual && | |
556 | ||
557 | test_cmp expect actual && | |
1550bb6e | 558 | grep "Add to combine filter-spec: sparse:oid=main:%5e%7epattern" \ |
489fc9ee | 559 | trace2 |
e987df5f MD |
560 | ' |
561 | ||
c813a7c3 MD |
562 | # Test provisional omit collection logic with a repo that has objects appearing |
563 | # at multiple depths - first deeper than the filter's threshold, then shallow. | |
564 | ||
565 | test_expect_success 'setup r4' ' | |
566 | git init r4 && | |
567 | ||
568 | echo foo > r4/foo && | |
569 | mkdir r4/subdir && | |
570 | echo bar > r4/subdir/bar && | |
571 | ||
572 | mkdir r4/filt && | |
573 | cp -r r4/foo r4/subdir r4/filt && | |
574 | ||
575 | git -C r4 add foo subdir filt && | |
576 | git -C r4 commit -m "commit msg" | |
577 | ' | |
578 | ||
579 | expect_has_with_different_name () { | |
580 | repo=$1 && | |
581 | name=$2 && | |
582 | ||
583 | hash=$(git -C $repo rev-parse HEAD:$name) && | |
584 | ! grep "^$hash $name$" actual && | |
585 | grep "^$hash " actual && | |
586 | ! grep "~$hash" actual | |
587 | } | |
588 | ||
589 | test_expect_success 'test tree:# filter provisional omit for blob and tree' ' | |
590 | git -C r4 rev-list --objects --filter-print-omitted --filter=tree:2 \ | |
591 | HEAD >actual && | |
592 | expect_has_with_different_name r4 filt/foo && | |
593 | expect_has_with_different_name r4 filt/subdir | |
594 | ' | |
595 | ||
8272f260 MD |
596 | test_expect_success 'verify skipping tree iteration when collecting omits' ' |
597 | GIT_TRACE=1 git -C r4 rev-list --filter-print-omitted \ | |
598 | --objects --filter=tree:0 HEAD 2>filter_trace && | |
599 | grep "^Skipping contents of tree " filter_trace >actual && | |
600 | ||
601 | echo "Skipping contents of tree subdir/..." >expect && | |
602 | test_cmp expect actual | |
603 | ' | |
604 | ||
e987df5f MD |
605 | test_expect_success 'setup r5' ' |
606 | git init r5 && | |
607 | mkdir -p r5/subdir && | |
608 | ||
609 | echo 1 >r5/short-root && | |
610 | echo 12345 >r5/long-root && | |
611 | echo a >r5/subdir/short-subdir && | |
612 | echo abcde >r5/subdir/long-subdir && | |
613 | ||
614 | git -C r5 add short-root long-root subdir && | |
615 | git -C r5 commit -m "commit msg" | |
616 | ' | |
617 | ||
618 | test_expect_success 'verify collecting omits in combined: filter' ' | |
619 | # Note that this test guards against the naive implementation of simply | |
620 | # giving both filters the same "omits" set and expecting it to | |
621 | # automatically merge them. | |
622 | git -C r5 rev-list --objects --quiet --filter-print-omitted \ | |
623 | --filter=combine:tree:2+blob:limit=3 HEAD >actual && | |
624 | ||
625 | # Expect 0 trees/commits, 3 blobs omitted (all blobs except short-root) | |
626 | omitted_1=$(echo 12345 | git hash-object --stdin) && | |
627 | omitted_2=$(echo a | git hash-object --stdin) && | |
628 | omitted_3=$(echo abcde | git hash-object --stdin) && | |
629 | ||
630 | grep ~$omitted_1 actual && | |
631 | grep ~$omitted_2 actual && | |
632 | grep ~$omitted_3 actual && | |
633 | test_line_count = 3 actual | |
634 | ' | |
635 | ||
c813a7c3 MD |
636 | # Test tree:<depth> where a tree is iterated to twice - once where a subentry is |
637 | # too deep to be included, and again where the blob inside it is shallow enough | |
638 | # to be included. This makes sure we don't use LOFR_MARK_SEEN incorrectly (we | |
639 | # can't use it because a tree can be iterated over again at a lower depth). | |
640 | ||
641 | test_expect_success 'tree:<depth> where we iterate over tree at two levels' ' | |
642 | git init r5 && | |
643 | ||
644 | mkdir -p r5/a/subdir/b && | |
645 | echo foo > r5/a/subdir/b/foo && | |
646 | ||
647 | mkdir -p r5/subdir/b && | |
648 | echo foo > r5/subdir/b/foo && | |
649 | ||
650 | git -C r5 add a subdir && | |
651 | git -C r5 commit -m "commit msg" && | |
652 | ||
653 | git -C r5 rev-list --objects --filter=tree:4 HEAD >actual && | |
654 | expect_has_with_different_name r5 a/subdir/b/foo | |
655 | ' | |
656 | ||
657 | test_expect_success 'tree:<depth> which filters out blob but given as arg' ' | |
658 | blob_hash=$(git -C r4 rev-parse HEAD:subdir/bar) && | |
659 | ||
660 | git -C r4 rev-list --objects --filter=tree:1 HEAD $blob_hash >actual && | |
661 | grep ^$blob_hash actual | |
662 | ' | |
663 | ||
caf3827e JH |
664 | # Delete some loose objects and use rev-list, but WITHOUT any filtering. |
665 | # This models previously omitted objects that we did not receive. | |
666 | ||
667 | test_expect_success 'rev-list W/ --missing=print' ' | |
61de0ff6 MD |
668 | git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 \ |
669 | >ls_files_result && | |
670 | awk -f print_2.awk ls_files_result | | |
bdbc17e8 MD |
671 | sort >expected && |
672 | ||
edfa63e7 | 673 | for id in `sed "s|..|&/|" expected` |
caf3827e | 674 | do |
0c51d6b4 | 675 | rm r1/.git/objects/$id || return 1 |
caf3827e | 676 | done && |
bdbc17e8 | 677 | |
8d6ba495 | 678 | git -C r1 rev-list --quiet --missing=print --objects HEAD >revs && |
61de0ff6 | 679 | awk -f print_1.awk revs | |
bdbc17e8 MD |
680 | sed "s/?//" | |
681 | sort >observed && | |
682 | ||
dcbaa0b3 | 683 | test_cmp expected observed |
caf3827e JH |
684 | ' |
685 | ||
686 | test_expect_success 'rev-list W/O --missing fails' ' | |
687 | test_must_fail git -C r1 rev-list --quiet --objects HEAD | |
688 | ' | |
689 | ||
690 | test_expect_success 'rev-list W/ missing=allow-any' ' | |
691 | git -C r1 rev-list --quiet --missing=allow-any --objects HEAD | |
692 | ' | |
693 | ||
87c2d9d3 JS |
694 | # Test expansion of filter specs. |
695 | ||
696 | test_expect_success 'expand blob limit in protocol' ' | |
697 | git -C r2 config --local uploadpack.allowfilter 1 && | |
698 | GIT_TRACE_PACKET="$(pwd)/trace" git -c protocol.version=2 clone \ | |
699 | --filter=blob:limit=1k "file://$(pwd)/r2" limit && | |
700 | ! grep "blob:limit=1k" trace && | |
701 | grep "blob:limit=1024" trace | |
702 | ' | |
703 | ||
caf3827e | 704 | test_done |