Skip to content

Commit acb0c57

Browse files
jeffhostetlergitster
authored andcommitted
fetch: support filters
Teach fetch to support filters. This is only allowed for the remote configured in extensions.partialcloneremote. Signed-off-by: Jonathan Tan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a174334 commit acb0c57

File tree

4 files changed

+65
-2
lines changed

4 files changed

+65
-2
lines changed

builtin/fetch.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "argv-array.h"
1919
#include "utf8.h"
2020
#include "packfile.h"
21+
#include "list-objects-filter-options.h"
2122

2223
static const char * const builtin_fetch_usage[] = {
2324
N_("git fetch [<options>] [<repository> [<refspec>...]]"),
@@ -55,6 +56,7 @@ static int recurse_submodules_default = RECURSE_SUBMODULES_ON_DEMAND;
5556
static int shown_url = 0;
5657
static int refmap_alloc, refmap_nr;
5758
static const char **refmap_array;
59+
static struct list_objects_filter_options filter_options;
5860

5961
static int git_fetch_config(const char *k, const char *v, void *cb)
6062
{
@@ -160,6 +162,7 @@ static struct option builtin_fetch_options[] = {
160162
TRANSPORT_FAMILY_IPV4),
161163
OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"),
162164
TRANSPORT_FAMILY_IPV6),
165+
OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
163166
OPT_END()
164167
};
165168

@@ -1044,6 +1047,11 @@ static struct transport *prepare_transport(struct remote *remote, int deepen)
10441047
set_option(transport, TRANS_OPT_DEEPEN_RELATIVE, "yes");
10451048
if (update_shallow)
10461049
set_option(transport, TRANS_OPT_UPDATE_SHALLOW, "yes");
1050+
if (filter_options.choice) {
1051+
set_option(transport, TRANS_OPT_LIST_OBJECTS_FILTER,
1052+
filter_options.filter_spec);
1053+
set_option(transport, TRANS_OPT_FROM_PROMISOR, "1");
1054+
}
10471055
return transport;
10481056
}
10491057

@@ -1328,6 +1336,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
13281336

13291337
packet_trace_identity("fetch");
13301338

1339+
fetch_if_missing = 0;
1340+
13311341
/* Record the command line for the reflog */
13321342
strbuf_addstr(&default_rla, "fetch");
13331343
for (i = 1; i < argc; i++)
@@ -1361,6 +1371,9 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
13611371
if (depth || deepen_since || deepen_not.nr)
13621372
deepen = 1;
13631373

1374+
if (filter_options.choice && !repository_format_partial_clone)
1375+
die("--filter can only be used when extensions.partialClone is set");
1376+
13641377
if (all) {
13651378
if (argc == 1)
13661379
die(_("fetch --all does not take a repository argument"));
@@ -1390,10 +1403,16 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
13901403
}
13911404
}
13921405

1393-
if (remote)
1406+
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"));
13941410
result = fetch_one(remote, argc, argv);
1395-
else
1411+
} else {
1412+
if (filter_options.choice)
1413+
die(_("--filter can only be used with the remote configured in core.partialClone"));
13961414
result = fetch_multiple(&list);
1415+
}
13971416

13981417
if (!result && (recurse_submodules != RECURSE_SUBMODULES_OFF)) {
13991418
struct argv_array options = ARGV_ARRAY_INIT;

connected.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ int check_connected(sha1_iterate_fn fn, void *cb_data,
5656
argv_array_push(&rev_list.args,"rev-list");
5757
argv_array_push(&rev_list.args, "--objects");
5858
argv_array_push(&rev_list.args, "--stdin");
59+
if (repository_format_partial_clone)
60+
argv_array_push(&rev_list.args, "--exclude-promisor-objects");
5961
argv_array_push(&rev_list.args, "--not");
6062
argv_array_push(&rev_list.args, "--all");
6163
argv_array_push(&rev_list.args, "--quiet");

remote-curl.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct options {
2424
char *deepen_since;
2525
struct string_list deepen_not;
2626
struct string_list push_options;
27+
char *filter;
2728
unsigned progress : 1,
2829
check_self_contained_and_connected : 1,
2930
cloning : 1,
@@ -165,6 +166,9 @@ static int set_option(const char *name, const char *value)
165166
} else if (!strcmp(name, "no-dependents")) {
166167
options.no_dependents = 1;
167168
return 0;
169+
} else if (!strcmp(name, "filter")) {
170+
options.filter = xstrdup(value);;
171+
return 0;
168172
} else {
169173
return 1 /* unsupported */;
170174
}
@@ -834,6 +838,8 @@ static int fetch_git(struct discovery *heads,
834838
argv_array_push(&args, "--from-promisor");
835839
if (options.no_dependents)
836840
argv_array_push(&args, "--no-dependents");
841+
if (options.filter)
842+
argv_array_pushf(&args, "--filter=%s", options.filter);
837843
argv_array_push(&args, url.buf);
838844

839845
for (i = 0; i < nr_heads; i++) {

t/t5500-fetch-pack.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,4 +782,40 @@ test_expect_success 'filtering by size has no effect if support for it is not ad
782782
test_i18ngrep "filtering not recognized by server" err
783783
'
784784

785+
fetch_filter_blob_limit_zero () {
786+
SERVER="$1"
787+
URL="$2"
788+
789+
rm -rf "$SERVER" client &&
790+
test_create_repo "$SERVER" &&
791+
test_commit -C "$SERVER" one &&
792+
test_config -C "$SERVER" uploadpack.allowfilter 1 &&
793+
794+
git clone "$URL" client &&
795+
test_config -C client extensions.partialclone origin &&
796+
797+
test_commit -C "$SERVER" two &&
798+
799+
git -C client fetch --filter=blob:limit=0 origin HEAD:somewhere &&
800+
801+
# Ensure that commit is fetched, but blob is not
802+
test_config -C client extensions.partialclone "arbitrary string" &&
803+
git -C client cat-file -e $(git -C "$SERVER" rev-parse two) &&
804+
test_must_fail git -C client cat-file -e $(git hash-object "$SERVER/two.t")
805+
}
806+
807+
test_expect_success 'fetch with --filter=blob:limit=0' '
808+
fetch_filter_blob_limit_zero server server
809+
'
810+
811+
. "$TEST_DIRECTORY"/lib-httpd.sh
812+
start_httpd
813+
814+
test_expect_success 'fetch with --filter=blob:limit=0 and HTTP' '
815+
fetch_filter_blob_limit_zero "$HTTPD_DOCUMENT_ROOT_PATH/server" "$HTTPD_URL/smart/server"
816+
'
817+
818+
stop_httpd
819+
820+
785821
test_done

0 commit comments

Comments
 (0)