Browse Source

fetch: support filters

Teach fetch to support filters. This is only allowed for the remote
configured in extensions.partialcloneremote.

Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Jeff Hostetler 7 years ago committed by Junio C Hamano
parent
commit
acb0c57260
  1. 23
      builtin/fetch.c
  2. 2
      connected.c
  3. 6
      remote-curl.c
  4. 36
      t/t5500-fetch-pack.sh

23
builtin/fetch.c

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
#include "argv-array.h"
#include "utf8.h"
#include "packfile.h"
#include "list-objects-filter-options.h"

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

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

@ -1044,6 +1047,11 @@ static struct transport *prepare_transport(struct remote *remote, int deepen) @@ -1044,6 +1047,11 @@ static struct transport *prepare_transport(struct remote *remote, int deepen)
set_option(transport, TRANS_OPT_DEEPEN_RELATIVE, "yes");
if (update_shallow)
set_option(transport, TRANS_OPT_UPDATE_SHALLOW, "yes");
if (filter_options.choice) {
set_option(transport, TRANS_OPT_LIST_OBJECTS_FILTER,
filter_options.filter_spec);
set_option(transport, TRANS_OPT_FROM_PROMISOR, "1");
}
return transport;
}

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

packet_trace_identity("fetch");

fetch_if_missing = 0;

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

if (filter_options.choice && !repository_format_partial_clone)
die("--filter can only be used when extensions.partialClone is set");

if (all) {
if (argc == 1)
die(_("fetch --all does not take a repository argument"));
@ -1390,10 +1403,16 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) @@ -1390,10 +1403,16 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
}
}

if (remote)
if (remote) {
if (filter_options.choice &&
strcmp(remote->name, repository_format_partial_clone))
die(_("--filter can only be used with the remote configured in core.partialClone"));
result = fetch_one(remote, argc, argv);
else
} else {
if (filter_options.choice)
die(_("--filter can only be used with the remote configured in core.partialClone"));
result = fetch_multiple(&list);
}

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

2
connected.c

@ -56,6 +56,8 @@ int check_connected(sha1_iterate_fn fn, void *cb_data, @@ -56,6 +56,8 @@ int check_connected(sha1_iterate_fn fn, void *cb_data,
argv_array_push(&rev_list.args,"rev-list");
argv_array_push(&rev_list.args, "--objects");
argv_array_push(&rev_list.args, "--stdin");
if (repository_format_partial_clone)
argv_array_push(&rev_list.args, "--exclude-promisor-objects");
argv_array_push(&rev_list.args, "--not");
argv_array_push(&rev_list.args, "--all");
argv_array_push(&rev_list.args, "--quiet");

6
remote-curl.c

@ -24,6 +24,7 @@ struct options { @@ -24,6 +24,7 @@ struct options {
char *deepen_since;
struct string_list deepen_not;
struct string_list push_options;
char *filter;
unsigned progress : 1,
check_self_contained_and_connected : 1,
cloning : 1,
@ -165,6 +166,9 @@ static int set_option(const char *name, const char *value) @@ -165,6 +166,9 @@ static int set_option(const char *name, const char *value)
} else if (!strcmp(name, "no-dependents")) {
options.no_dependents = 1;
return 0;
} else if (!strcmp(name, "filter")) {
options.filter = xstrdup(value);;
return 0;
} else {
return 1 /* unsupported */;
}
@ -834,6 +838,8 @@ static int fetch_git(struct discovery *heads, @@ -834,6 +838,8 @@ static int fetch_git(struct discovery *heads,
argv_array_push(&args, "--from-promisor");
if (options.no_dependents)
argv_array_push(&args, "--no-dependents");
if (options.filter)
argv_array_pushf(&args, "--filter=%s", options.filter);
argv_array_push(&args, url.buf);

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

36
t/t5500-fetch-pack.sh

@ -782,4 +782,40 @@ test_expect_success 'filtering by size has no effect if support for it is not ad @@ -782,4 +782,40 @@ test_expect_success 'filtering by size has no effect if support for it is not ad
test_i18ngrep "filtering not recognized by server" err
'

fetch_filter_blob_limit_zero () {
SERVER="$1"
URL="$2"

rm -rf "$SERVER" client &&
test_create_repo "$SERVER" &&
test_commit -C "$SERVER" one &&
test_config -C "$SERVER" uploadpack.allowfilter 1 &&

git clone "$URL" client &&
test_config -C client extensions.partialclone origin &&

test_commit -C "$SERVER" two &&

git -C client fetch --filter=blob:limit=0 origin HEAD:somewhere &&

# Ensure that commit is fetched, but blob is not
test_config -C client extensions.partialclone "arbitrary string" &&
git -C client cat-file -e $(git -C "$SERVER" rev-parse two) &&
test_must_fail git -C client cat-file -e $(git hash-object "$SERVER/two.t")
}

test_expect_success 'fetch with --filter=blob:limit=0' '
fetch_filter_blob_limit_zero server server
'

. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd

test_expect_success 'fetch with --filter=blob:limit=0 and HTTP' '
fetch_filter_blob_limit_zero "$HTTPD_DOCUMENT_ROOT_PATH/server" "$HTTPD_URL/smart/server"
'

stop_httpd


test_done

Loading…
Cancel
Save