Skip to content

Commit 87c2d9d

Browse files
steadmongitster
authored andcommitted
filter-options: expand scaled numbers
When communicating with a remote server or a subprocess, use expanded numbers rather than numbers with scaling suffix in the object filter spec (e.g. "limit:blob=1k" becomes "limit:blob=1024"). Update the protocol docs to note that clients should always perform this expansion, to allow for more compatibility between server implementations. Signed-off-by: Josh Steadmon <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 8272f26 commit 87c2d9d

File tree

9 files changed

+94
-16
lines changed

9 files changed

+94
-16
lines changed

Documentation/technical/protocol-v2.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,13 @@ included in the client's request:
296296
Request that various objects from the packfile be omitted
297297
using one of several filtering techniques. These are intended
298298
for use with partial clone and partial fetch operations. See
299-
`rev-list` for possible "filter-spec" values.
299+
`rev-list` for possible "filter-spec" values. When communicating
300+
with other processes, senders SHOULD translate scaled integers
301+
(e.g. "1k") into a fully-expanded form (e.g. "1024") to aid
302+
interoperability with older receivers that may not understand
303+
newly-invented scaling suffixes. However, receivers SHOULD
304+
accept the following suffixes: 'k', 'm', and 'g' for 1024,
305+
1048576, and 1073741824, respectively.
300306

301307
If the 'ref-in-want' feature is advertised, the following argument can
302308
be included in the client's request as well as the potential addition of

builtin/clone.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1130,9 +1130,13 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
11301130
option_upload_pack);
11311131

11321132
if (filter_options.choice) {
1133+
struct strbuf expanded_filter_spec = STRBUF_INIT;
1134+
expand_list_objects_filter_spec(&filter_options,
1135+
&expanded_filter_spec);
11331136
transport_set_option(transport, TRANS_OPT_LIST_OBJECTS_FILTER,
1134-
filter_options.filter_spec);
1137+
expanded_filter_spec.buf);
11351138
transport_set_option(transport, TRANS_OPT_FROM_PROMISOR, "1");
1139+
strbuf_release(&expanded_filter_spec);
11361140
}
11371141

11381142
if (transport->smart_options && !deepen && !filter_options.choice)

builtin/fetch.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,7 @@ static void add_negotiation_tips(struct git_transport_options *smart_options)
11721172
static struct transport *prepare_transport(struct remote *remote, int deepen)
11731173
{
11741174
struct transport *transport;
1175+
11751176
transport = transport_get(remote, NULL);
11761177
transport_set_verbosity(transport, verbosity, progress);
11771178
transport->family = family;
@@ -1191,9 +1192,13 @@ static struct transport *prepare_transport(struct remote *remote, int deepen)
11911192
if (update_shallow)
11921193
set_option(transport, TRANS_OPT_UPDATE_SHALLOW, "yes");
11931194
if (filter_options.choice) {
1195+
struct strbuf expanded_filter_spec = STRBUF_INIT;
1196+
expand_list_objects_filter_spec(&filter_options,
1197+
&expanded_filter_spec);
11941198
set_option(transport, TRANS_OPT_LIST_OBJECTS_FILTER,
1195-
filter_options.filter_spec);
1199+
expanded_filter_spec.buf);
11961200
set_option(transport, TRANS_OPT_FROM_PROMISOR, "1");
1201+
strbuf_release(&expanded_filter_spec);
11971202
}
11981203
if (negotiation_tip.nr) {
11991204
if (transport->smart_options)

fetch-pack.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,14 @@ static int find_common(struct fetch_negotiator *negotiator,
329329
packet_buf_write(&req_buf, "deepen-not %s", s->string);
330330
}
331331
}
332-
if (server_supports_filtering && args->filter_options.choice)
332+
if (server_supports_filtering && args->filter_options.choice) {
333+
struct strbuf expanded_filter_spec = STRBUF_INIT;
334+
expand_list_objects_filter_spec(&args->filter_options,
335+
&expanded_filter_spec);
333336
packet_buf_write(&req_buf, "filter %s",
334-
args->filter_options.filter_spec);
337+
expanded_filter_spec.buf);
338+
strbuf_release(&expanded_filter_spec);
339+
}
335340
packet_buf_flush(&req_buf);
336341
state_len = req_buf.len;
337342

@@ -1155,9 +1160,13 @@ static int send_fetch_request(struct fetch_negotiator *negotiator, int fd_out,
11551160
/* Add filter */
11561161
if (server_supports_feature("fetch", "filter", 0) &&
11571162
args->filter_options.choice) {
1163+
struct strbuf expanded_filter_spec = STRBUF_INIT;
11581164
print_verbose(args, _("Server supports filter"));
1165+
expand_list_objects_filter_spec(&args->filter_options,
1166+
&expanded_filter_spec);
11591167
packet_buf_write(&req_buf, "filter %s",
1160-
args->filter_options.filter_spec);
1168+
expanded_filter_spec.buf);
1169+
strbuf_release(&expanded_filter_spec);
11611170
} else if (args->filter_options.choice) {
11621171
warning("filtering not recognized by server, ignoring");
11631172
}

list-objects-filter-options.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@
1818
* See Documentation/rev-list-options.txt for allowed values for <arg>.
1919
*
2020
* Capture the given arg as the "filter_spec". This can be forwarded to
21-
* subordinate commands when necessary. We also "intern" the arg for
22-
* the convenience of the current command.
21+
* subordinate commands when necessary (although it's better to pass it through
22+
* expand_list_objects_filter_spec() first). We also "intern" the arg for the
23+
* convenience of the current command.
2324
*/
2425
static int gently_parse_list_objects_filter(
2526
struct list_objects_filter_options *filter_options,
@@ -111,6 +112,21 @@ int opt_parse_list_objects_filter(const struct option *opt,
111112
return parse_list_objects_filter(filter_options, arg);
112113
}
113114

115+
void expand_list_objects_filter_spec(
116+
const struct list_objects_filter_options *filter,
117+
struct strbuf *expanded_spec)
118+
{
119+
strbuf_init(expanded_spec, strlen(filter->filter_spec));
120+
if (filter->choice == LOFC_BLOB_LIMIT)
121+
strbuf_addf(expanded_spec, "blob:limit=%lu",
122+
filter->blob_limit_value);
123+
else if (filter->choice == LOFC_TREE_DEPTH)
124+
strbuf_addf(expanded_spec, "tree:%lu",
125+
filter->tree_exclude_depth);
126+
else
127+
strbuf_addstr(expanded_spec, filter->filter_spec);
128+
}
129+
114130
void list_objects_filter_release(
115131
struct list_objects_filter_options *filter_options)
116132
{

list-objects-filter-options.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define LIST_OBJECTS_FILTER_OPTIONS_H
33

44
#include "parse-options.h"
5+
#include "strbuf.h"
56

67
/*
78
* The list of defined filters for list-objects.
@@ -20,8 +21,9 @@ struct list_objects_filter_options {
2021
/*
2122
* 'filter_spec' is the raw argument value given on the command line
2223
* or protocol request. (The part after the "--keyword=".) For
23-
* commands that launch filtering sub-processes, this value should be
24-
* passed to them as received by the current process.
24+
* commands that launch filtering sub-processes, or for communication
25+
* over the network, don't use this value; use the result of
26+
* expand_list_objects_filter_spec() instead.
2527
*/
2628
char *filter_spec;
2729

@@ -62,6 +64,17 @@ int opt_parse_list_objects_filter(const struct option *opt,
6264
N_("object filtering"), 0, \
6365
opt_parse_list_objects_filter }
6466

67+
/*
68+
* Translates abbreviated numbers in the filter's filter_spec into their
69+
* fully-expanded forms (e.g., "limit:blob=1k" becomes "limit:blob=1024").
70+
*
71+
* This form should be used instead of the raw filter_spec field when
72+
* communicating with a remote process or subprocess.
73+
*/
74+
void expand_list_objects_filter_spec(
75+
const struct list_objects_filter_options *filter,
76+
struct strbuf *expanded_spec);
77+
6578
void list_objects_filter_release(
6679
struct list_objects_filter_options *filter_options);
6780

t/t6112-rev-list-filters-objects.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,4 +444,21 @@ test_expect_success 'rev-list W/ missing=allow-any' '
444444
git -C r1 rev-list --quiet --missing=allow-any --objects HEAD
445445
'
446446

447+
# Test expansion of filter specs.
448+
449+
test_expect_success 'expand blob limit in protocol' '
450+
git -C r2 config --local uploadpack.allowfilter 1 &&
451+
GIT_TRACE_PACKET="$(pwd)/trace" git -c protocol.version=2 clone \
452+
--filter=blob:limit=1k "file://$(pwd)/r2" limit &&
453+
! grep "blob:limit=1k" trace &&
454+
grep "blob:limit=1024" trace
455+
'
456+
457+
test_expect_success 'expand tree depth limit in protocol' '
458+
GIT_TRACE_PACKET="$(pwd)/tree_trace" git -c protocol.version=2 clone \
459+
--filter=tree:0k "file://$(pwd)/r2" tree &&
460+
! grep "tree:0k" tree_trace &&
461+
grep "tree:0" tree_trace
462+
'
463+
447464
test_done

transport-helper.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -679,10 +679,15 @@ static int fetch(struct transport *transport,
679679
if (data->transport_options.update_shallow)
680680
set_helper_option(transport, "update-shallow", "true");
681681

682-
if (data->transport_options.filter_options.choice)
683-
set_helper_option(
684-
transport, "filter",
685-
data->transport_options.filter_options.filter_spec);
682+
if (data->transport_options.filter_options.choice) {
683+
struct strbuf expanded_filter_spec = STRBUF_INIT;
684+
expand_list_objects_filter_spec(
685+
&data->transport_options.filter_options,
686+
&expanded_filter_spec);
687+
set_helper_option(transport, "filter",
688+
expanded_filter_spec.buf);
689+
strbuf_release(&expanded_filter_spec);
690+
}
686691

687692
if (data->transport_options.negotiation_tips)
688693
warning("Ignoring --negotiation-tip because the protocol does not support it.");

upload-pack.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,14 +140,17 @@ static void create_pack_file(const struct object_array *have_obj,
140140
if (use_include_tag)
141141
argv_array_push(&pack_objects.args, "--include-tag");
142142
if (filter_options.filter_spec) {
143+
struct strbuf expanded_filter_spec = STRBUF_INIT;
144+
expand_list_objects_filter_spec(&filter_options,
145+
&expanded_filter_spec);
143146
if (pack_objects.use_shell) {
144147
struct strbuf buf = STRBUF_INIT;
145-
sq_quote_buf(&buf, filter_options.filter_spec);
148+
sq_quote_buf(&buf, expanded_filter_spec.buf);
146149
argv_array_pushf(&pack_objects.args, "--filter=%s", buf.buf);
147150
strbuf_release(&buf);
148151
} else {
149152
argv_array_pushf(&pack_objects.args, "--filter=%s",
150-
filter_options.filter_spec);
153+
expanded_filter_spec.buf);
151154
}
152155
}
153156

0 commit comments

Comments
 (0)