Skip to content

Commit ad8f036

Browse files
committed
Merge branch 'jk/partial-clone-sparse-blob'
The name of the blob object that stores the filter specification for sparse cloning/fetching was interpreted in a wrong place in the code, causing Git to abort. * jk/partial-clone-sparse-blob: list-objects-filter: use empty string instead of NULL for sparse "base" list-objects-filter: give a more specific error sparse parsing error list-objects-filter: delay parsing of sparse oid t5616: test cloning/fetching with sparse:oid=<oid> filter
2 parents ba2d451 + a4cafc7 commit ad8f036

5 files changed

+50
-22
lines changed

builtin/rev-list.c

-6
Original file line numberDiff line numberDiff line change
@@ -471,12 +471,6 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
471471
parse_list_objects_filter(&filter_options, arg);
472472
if (filter_options.choice && !revs.blob_objects)
473473
die(_("object filtering requires --objects"));
474-
if (filter_options.choice == LOFC_SPARSE_OID &&
475-
!filter_options.sparse_oid_value)
476-
die(
477-
_("invalid sparse value '%s'"),
478-
list_objects_filter_spec(
479-
&filter_options));
480474
continue;
481475
}
482476
if (!strcmp(arg, ("--no-" CL_ARG__FILTER))) {

list-objects-filter-options.c

+2-12
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,7 @@ static int gently_parse_list_objects_filter(
6262
return 0;
6363

6464
} else if (skip_prefix(arg, "sparse:oid=", &v0)) {
65-
struct object_context oc;
66-
struct object_id sparse_oid;
67-
68-
/*
69-
* Try to parse <oid-expression> into an OID for the current
70-
* command, but DO NOT complain if we don't have the blob or
71-
* ref locally.
72-
*/
73-
if (!get_oid_with_context(the_repository, v0, GET_OID_BLOB,
74-
&sparse_oid, &oc))
75-
filter_options->sparse_oid_value = oiddup(&sparse_oid);
65+
filter_options->sparse_oid_name = xstrdup(v0);
7666
filter_options->choice = LOFC_SPARSE_OID;
7767
return 0;
7868

@@ -320,7 +310,7 @@ void list_objects_filter_release(
320310
if (!filter_options)
321311
return;
322312
string_list_clear(&filter_options->filter_spec, /*free_util=*/0);
323-
free(filter_options->sparse_oid_value);
313+
free(filter_options->sparse_oid_name);
324314
for (sub = 0; sub < filter_options->sub_nr; sub++)
325315
list_objects_filter_release(&filter_options->sub[sub]);
326316
free(filter_options->sub);

list-objects-filter-options.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct list_objects_filter_options {
4545
* some values will be defined for any given choice.
4646
*/
4747

48-
struct object_id *sparse_oid_value;
48+
char *sparse_oid_name;
4949
unsigned long blob_limit_value;
5050
unsigned long tree_exclude_depth;
5151

list-objects-filter.c

+11-3
Original file line numberDiff line numberDiff line change
@@ -483,9 +483,17 @@ static void filter_sparse_oid__init(
483483
struct filter *filter)
484484
{
485485
struct filter_sparse_data *d = xcalloc(1, sizeof(*d));
486-
if (add_patterns_from_blob_to_list(filter_options->sparse_oid_value,
487-
NULL, 0, &d->pl) < 0)
488-
die("could not load filter specification");
486+
struct object_context oc;
487+
struct object_id sparse_oid;
488+
489+
if (get_oid_with_context(the_repository,
490+
filter_options->sparse_oid_name,
491+
GET_OID_BLOB, &sparse_oid, &oc))
492+
die(_("unable to access sparse blob in '%s'"),
493+
filter_options->sparse_oid_name);
494+
if (add_patterns_from_blob_to_list(&sparse_oid, "", 0, &d->pl) < 0)
495+
die(_("unable to parse sparse filter data in %s"),
496+
oid_to_hex(&sparse_oid));
489497

490498
ALLOC_GROW(d->array_frame, d->nr + 1, d->alloc);
491499
d->array_frame[d->nr].default_match = 0; /* default to include */

t/t5616-partial-clone.sh

+36
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,42 @@ test_expect_success 'fetch what is specified on CLI even if already promised' '
260260
! grep "?$(cat blob)" missing_after
261261
'
262262

263+
test_expect_success 'setup src repo for sparse filter' '
264+
git init sparse-src &&
265+
git -C sparse-src config --local uploadpack.allowfilter 1 &&
266+
git -C sparse-src config --local uploadpack.allowanysha1inwant 1 &&
267+
test_commit -C sparse-src one &&
268+
test_commit -C sparse-src two &&
269+
echo /one.t >sparse-src/only-one &&
270+
git -C sparse-src add . &&
271+
git -C sparse-src commit -m "add sparse checkout files"
272+
'
273+
274+
test_expect_success 'partial clone with sparse filter succeeds' '
275+
rm -rf dst.git &&
276+
git clone --no-local --bare \
277+
--filter=sparse:oid=master:only-one \
278+
sparse-src dst.git &&
279+
(
280+
cd dst.git &&
281+
git rev-list --objects --missing=print HEAD >out &&
282+
grep "^$(git rev-parse HEAD:one.t)" out &&
283+
grep "^?$(git rev-parse HEAD:two.t)" out
284+
)
285+
'
286+
287+
test_expect_success 'partial clone with unresolvable sparse filter fails cleanly' '
288+
rm -rf dst.git &&
289+
test_must_fail git clone --no-local --bare \
290+
--filter=sparse:oid=master:no-such-name \
291+
sparse-src dst.git 2>err &&
292+
test_i18ngrep "unable to access sparse blob in .master:no-such-name" err &&
293+
test_must_fail git clone --no-local --bare \
294+
--filter=sparse:oid=master \
295+
sparse-src dst.git 2>err &&
296+
test_i18ngrep "unable to parse sparse filter data in" err
297+
'
298+
263299
. "$TEST_DIRECTORY"/lib-httpd.sh
264300
start_httpd
265301

0 commit comments

Comments
 (0)