Skip to content

Commit aa57b87

Browse files
jeffhostetlergitster
authored andcommittedDec 8, 2017
fetch: inherit filter-spec from partial clone
Teach (partial) fetch to inherit the filter-spec used by the partial clone. Extend --no-filter to override this inheritance. Signed-off-by: Jeff Hostetler <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 35a7ae9 commit aa57b87

6 files changed

+89
-7
lines changed
 

‎builtin/fetch-pack.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
158158
continue;
159159
}
160160
if (!strcmp(arg, ("--no-" CL_ARG__FILTER))) {
161-
list_objects_filter_release(&args.filter_options);
161+
list_objects_filter_set_no_filter(&args.filter_options);
162162
continue;
163163
}
164164
usage(fetch_pack_usage);

‎builtin/fetch.c

+53-3
Original file line numberDiff line numberDiff line change
@@ -1275,6 +1275,56 @@ static int fetch_multiple(struct string_list *list)
12751275
return result;
12761276
}
12771277

1278+
/*
1279+
* Fetching from the promisor remote should use the given filter-spec
1280+
* or inherit the default filter-spec from the config.
1281+
*/
1282+
static inline void fetch_one_setup_partial(struct remote *remote)
1283+
{
1284+
/*
1285+
* Explicit --no-filter argument overrides everything, regardless
1286+
* of any prior partial clones and fetches.
1287+
*/
1288+
if (filter_options.no_filter)
1289+
return;
1290+
1291+
/*
1292+
* If no prior partial clone/fetch and the current fetch DID NOT
1293+
* request a partial-fetch, do a normal fetch.
1294+
*/
1295+
if (!repository_format_partial_clone && !filter_options.choice)
1296+
return;
1297+
1298+
/*
1299+
* If this is the FIRST partial-fetch request, we enable partial
1300+
* on this repo and remember the given filter-spec as the default
1301+
* for subsequent fetches to this remote.
1302+
*/
1303+
if (!repository_format_partial_clone && filter_options.choice) {
1304+
partial_clone_register(remote->name, &filter_options);
1305+
return;
1306+
}
1307+
1308+
/*
1309+
* We are currently limited to only ONE promisor remote and only
1310+
* allow partial-fetches from the promisor remote.
1311+
*/
1312+
if (strcmp(remote->name, repository_format_partial_clone)) {
1313+
if (filter_options.choice)
1314+
die(_("--filter can only be used with the remote configured in core.partialClone"));
1315+
return;
1316+
}
1317+
1318+
/*
1319+
* Do a partial-fetch from the promisor remote using either the
1320+
* explicitly given filter-spec or inherit the filter-spec from
1321+
* the config.
1322+
*/
1323+
if (!filter_options.choice)
1324+
partial_clone_get_default_filter_spec(&filter_options);
1325+
return;
1326+
}
1327+
12781328
static int fetch_one(struct remote *remote, int argc, const char **argv)
12791329
{
12801330
static const char **refs = NULL;
@@ -1404,13 +1454,13 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
14041454
}
14051455

14061456
if (remote) {
1407-
if (filter_options.choice &&
1408-
strcmp(remote->name, repository_format_partial_clone))
1409-
die(_("--filter can only be used with the remote configured in core.partialClone"));
1457+
if (filter_options.choice || repository_format_partial_clone)
1458+
fetch_one_setup_partial(remote);
14101459
result = fetch_one(remote, argc, argv);
14111460
} else {
14121461
if (filter_options.choice)
14131462
die(_("--filter can only be used with the remote configured in core.partialClone"));
1463+
/* TODO should this also die if we have a previous partial-clone? */
14141464
result = fetch_multiple(&list);
14151465
}
14161466

‎builtin/rev-list.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
460460
continue;
461461
}
462462
if (!strcmp(arg, ("--no-" CL_ARG__FILTER))) {
463-
list_objects_filter_release(&filter_options);
463+
list_objects_filter_set_no_filter(&filter_options);
464464
continue;
465465
}
466466
if (!strcmp(arg, "--filter-print-omitted")) {

‎list-objects-filter-options.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ int opt_parse_list_objects_filter(const struct option *opt,
9494
struct list_objects_filter_options *filter_options = opt->value;
9595

9696
if (unset || !arg) {
97-
list_objects_filter_release(filter_options);
97+
list_objects_filter_set_no_filter(filter_options);
9898
return 0;
9999
}
100100

‎list-objects-filter-options.h

+12
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ struct list_objects_filter_options {
3030
*/
3131
enum list_objects_filter_choice choice;
3232

33+
/*
34+
* Choice is LOFC_DISABLED because "--no-filter" was requested.
35+
*/
36+
unsigned int no_filter : 1;
37+
3338
/*
3439
* Parsed values (fields) from within the filter-spec. These are
3540
* choice-specific; not all values will be defined for any given
@@ -58,6 +63,13 @@ int opt_parse_list_objects_filter(const struct option *opt,
5863
void list_objects_filter_release(
5964
struct list_objects_filter_options *filter_options);
6065

66+
static inline void list_objects_filter_set_no_filter(
67+
struct list_objects_filter_options *filter_options)
68+
{
69+
list_objects_filter_release(filter_options);
70+
filter_options->no_filter = 1;
71+
}
72+
6173
void partial_clone_register(
6274
const char *remote,
6375
const struct list_objects_filter_options *filter_options);

‎t/t5616-partial-clone.sh

+21-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ test_expect_success 'push new commits to server' '
5959
git -C src remote add srv "file://$(pwd)/srv.bare" &&
6060
for x in a b c d e
6161
do
62-
echo "Mod $x" >>src/file.1.txt
62+
echo "Mod file.1.txt $x" >>src/file.1.txt
6363
git -C src add file.1.txt
6464
git -C src commit -m "mod $x"
6565
done &&
@@ -93,4 +93,24 @@ test_expect_success 'verify blame causes dynamic object fetch' '
9393
test_line_count = 0 observed
9494
'
9595

96+
# create new commits in "src" repo to establish a history on file.2.txt
97+
# and push to "srv.bare".
98+
test_expect_success 'push new commits to server for file.2.txt' '
99+
for x in a b c d e f
100+
do
101+
echo "Mod file.2.txt $x" >>src/file.2.txt
102+
git -C src add file.2.txt
103+
git -C src commit -m "mod $x"
104+
done &&
105+
git -C src push -u srv master
106+
'
107+
108+
# Do FULL fetch by disabling filter-spec using --no-filter.
109+
# Verify we have all the new blobs.
110+
test_expect_success 'override inherited filter-spec using --no-filter' '
111+
git -C pc1 fetch --no-filter origin &&
112+
git -C pc1 rev-list master..origin/master --quiet --objects --missing=print >observed &&
113+
test_line_count = 0 observed
114+
'
115+
96116
test_done

0 commit comments

Comments
 (0)
Please sign in to comment.