Skip to content

Commit 7f57b06

Browse files
committed
Merge branch 'cc/lop-filter-auto' into seen
"auto filter" logic for large-object promisor remote. Comments? * cc/lop-filter-auto: fetch-pack: wire up and enable auto filter logic promisor-remote: keep advertised filter in memory list-objects-filter-options: implement auto filter resolution list-objects-filter-options: support 'auto' mode for --filter doc: fetch: document `--filter=<filter-spec>` option fetch: make filter_options local to cmd_fetch() clone: make filter_options local to cmd_clone() promisor-remote: allow a client to store fields promisor-remote: refactor initialising field lists
2 parents e8342b0 + c01bcb5 commit 7f57b06

17 files changed

+663
-56
lines changed

Documentation/config/promisor.adoc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,36 @@ variable. The fields are checked only if the
8989
`promisor.acceptFromServer` config variable is not set to "None". If
9090
set to "None", this config variable has no effect. See
9191
linkgit:gitprotocol-v2[5].
92+
93+
promisor.storeFields::
94+
A comma or space separated list of additional remote related
95+
field names. If a client accepts an advertised remote, the
96+
client will store the values associated with these field names
97+
taken from the remote advertisement into its configuration,
98+
and then reload its remote configuration. Currently,
99+
"partialCloneFilter" and "token" are the only supported field
100+
names.
101+
+
102+
For example if a server advertises "partialCloneFilter=blob:limit=20k"
103+
for remote "foo", and that remote is accepted, then "blob:limit=20k"
104+
will be stored for the "remote.foo.partialCloneFilter" configuration
105+
variable.
106+
+
107+
If the new field value from an advertised remote is the same as the
108+
existing field value for that remote on the client side, then no
109+
change is made to the client configuration though.
110+
+
111+
When a new value is stored, a message is printed to standard error to
112+
let users know about this.
113+
+
114+
Note that for security reasons, if the remote is not already
115+
configured on the client side, nothing will be stored for that
116+
remote. In any case, no new remote will be created and no URL will be
117+
stored.
118+
+
119+
Before storing a partial clone filter, it's parsed to check it's
120+
valid. If it's not, a warning is emitted and it's not stored.
121+
+
122+
Before storing a token, a check is performed to ensure it contains no
123+
control character. If the check fails, a warning is emitted and it's
124+
not stored.

Documentation/fetch-options.adoc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,25 @@ linkgit:git-config[1].
8888
This is incompatible with `--recurse-submodules=(yes|on-demand)` and takes
8989
precedence over the `fetch.output` config option.
9090

91+
--filter=<filter-spec>::
92+
Use the partial clone feature and request that the server sends
93+
a subset of reachable objects according to a given object filter.
94+
When using `--filter`, the supplied _<filter-spec>_ is used for
95+
the partial fetch.
96+
+
97+
If `--filter=auto` is used, the filter specification is determined
98+
automatically by combining the filter specifications advertised by
99+
the server for the promisor remotes that the client accepts (see
100+
linkgit:gitprotocol-v2[5] and the `promisor.acceptFromServer`
101+
configuration option in linkgit:git-config[1]).
102+
+
103+
For details on all other available filter specifications, see the
104+
`--filter=<filter-spec>` option in linkgit:git-rev-list[1].
105+
+
106+
For example, `--filter=blob:none` will filter out all blobs (file
107+
contents) until needed by Git. Also, `--filter=blob:limit=<size>` will
108+
filter out all blobs of size at least _<size>_.
109+
91110
ifndef::git-pull[]
92111
`--write-fetch-head`::
93112
`--no-write-fetch-head`::

Documentation/git-clone.adoc

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,11 +187,26 @@ objects from the source repository into a pack in the cloned repository.
187187
Use the partial clone feature and request that the server sends
188188
a subset of reachable objects according to a given object filter.
189189
When using `--filter`, the supplied _<filter-spec>_ is used for
190-
the partial clone filter. For example, `--filter=blob:none` will
191-
filter out all blobs (file contents) until needed by Git. Also,
192-
`--filter=blob:limit=<size>` will filter out all blobs of size
193-
at least _<size>_. For more details on filter specifications, see
194-
the `--filter` option in linkgit:git-rev-list[1].
190+
the partial clone filter.
191+
+
192+
If `--filter=auto` is used the filter specification is determined
193+
automatically through the 'promisor-remote' protocol (see
194+
linkgit:gitprotocol-v2[5]) by combining the filter specifications
195+
advertised by the server for the promisor remotes that the client
196+
accepts (see the `promisor.acceptFromServer` configuration option in
197+
linkgit:git-config[1]). This allows the server to suggest the optimal
198+
filter for the available promisor remotes.
199+
+
200+
As with other filter specifications, the "auto" value is persisted in
201+
the configuration. This ensures that future fetches will continue to
202+
adapt to the server's current recommendation.
203+
+
204+
For details on all other available filter specifications, see the
205+
`--filter=<filter-spec>` option in linkgit:git-rev-list[1].
206+
+
207+
For example, `--filter=blob:none` will filter out all blobs (file
208+
contents) until needed by Git. Also, `--filter=blob:limit=<size>` will
209+
filter out all blobs of size at least _<size>_.
195210

196211
`--also-filter-submodules`::
197212
Also apply the partial clone filter to any submodules in the repository.

Documentation/gitprotocol-v2.adoc

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -812,10 +812,15 @@ MUST appear first in each pr-fields, in that order.
812812
After these mandatory fields, the server MAY advertise the following
813813
optional fields in any order:
814814
815-
`partialCloneFilter`:: The filter specification used by the remote.
815+
`partialCloneFilter`:: The filter specification for the remote. It
816+
corresponds to the "remote.<name>.partialCloneFilter" config setting.
816817
Clients can use this to determine if the remote's filtering strategy
817-
is compatible with their needs (e.g., checking if both use "blob:none").
818-
It corresponds to the "remote.<name>.partialCloneFilter" config setting.
818+
is compatible with their needs (e.g., checking if both use
819+
"blob:none"). Additionally they can use this through the
820+
`--filter=auto` option in linkgit:git-clone[1]. With that option, the
821+
filter specification of the clone will be automatically computed by
822+
combining the filter specifications of the promisor remotes the client
823+
accepts.
819824
820825
`token`:: An authentication token that clients can use when
821826
connecting to the remote. It corresponds to the "remote.<name>.token"
@@ -826,9 +831,11 @@ are case-sensitive and MUST be transmitted exactly as specified
826831
above. Clients MUST ignore fields they don't recognize to allow for
827832
future protocol extensions.
828833
829-
For now, the client can only use information transmitted through these
830-
fields to decide if it accepts the advertised promisor remote. In the
831-
future that information might be used for other purposes though.
834+
The client can use information transmitted through these fields to
835+
decide if it accepts the advertised promisor remote. Also, the client
836+
can be configured to store the values of these fields or use them
837+
to automatically configure the repository (see "promisor.storeFields"
838+
in linkgit:git-config[1] and `--filter=auto` in linkgit:git-clone[1]).
832839
833840
Field values MUST be urlencoded.
834841
@@ -856,8 +863,9 @@ the server advertised, the client shouldn't advertise the
856863
On the server side, the "promisor.advertise" and "promisor.sendFields"
857864
configuration options can be used to control what it advertises. On
858865
the client side, the "promisor.acceptFromServer" configuration option
859-
can be used to control what it accepts. See the documentation of these
860-
configuration options for more information.
866+
can be used to control what it accepts, and the "promisor.storeFields"
867+
option, to control what it stores. See the documentation of these
868+
configuration options in linkgit:git-config[1] for more information.
861869
862870
Note that in the future it would be nice if the "promisor-remote"
863871
protocol capability could be used by the server, when responding to

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,6 +1517,7 @@ CLAR_TEST_SUITES += u-dir
15171517
CLAR_TEST_SUITES += u-example-decorate
15181518
CLAR_TEST_SUITES += u-hash
15191519
CLAR_TEST_SUITES += u-hashmap
1520+
CLAR_TEST_SUITES += u-list-objects-filter-options
15201521
CLAR_TEST_SUITES += u-mem-pool
15211522
CLAR_TEST_SUITES += u-oid-array
15221523
CLAR_TEST_SUITES += u-oidmap

builtin/clone.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ static struct string_list option_required_reference = STRING_LIST_INIT_NODUP;
7777
static struct string_list option_optional_reference = STRING_LIST_INIT_NODUP;
7878
static int max_jobs = -1;
7979
static struct string_list option_recurse_submodules = STRING_LIST_INIT_NODUP;
80-
static struct list_objects_filter_options filter_options = LIST_OBJECTS_FILTER_INIT;
8180
static int config_filter_submodules = -1; /* unspecified */
8281
static int option_remote_submodules;
8382

@@ -634,7 +633,9 @@ static int git_sparse_checkout_init(const char *repo)
634633
return result;
635634
}
636635

637-
static int checkout(int submodule_progress, int filter_submodules,
636+
static int checkout(int submodule_progress,
637+
struct list_objects_filter_options *filter_options,
638+
int filter_submodules,
638639
enum ref_storage_format ref_storage_format)
639640
{
640641
struct object_id oid;
@@ -723,9 +724,9 @@ static int checkout(int submodule_progress, int filter_submodules,
723724
strvec_pushf(&cmd.args, "--ref-format=%s",
724725
ref_storage_format_to_name(ref_storage_format));
725726

726-
if (filter_submodules && filter_options.choice)
727+
if (filter_submodules && filter_options->choice)
727728
strvec_pushf(&cmd.args, "--filter=%s",
728-
expand_list_objects_filter_spec(&filter_options));
729+
expand_list_objects_filter_spec(filter_options));
729730

730731
if (option_single_branch >= 0)
731732
strvec_push(&cmd.args, option_single_branch ?
@@ -903,6 +904,7 @@ int cmd_clone(int argc,
903904
enum transport_family family = TRANSPORT_FAMILY_ALL;
904905
struct string_list option_config = STRING_LIST_INIT_DUP;
905906
int option_dissociate = 0;
907+
struct list_objects_filter_options filter_options = LIST_OBJECTS_FILTER_INIT;
906908
int option_filter_submodules = -1; /* unspecified */
907909
struct string_list server_options = STRING_LIST_INIT_NODUP;
908910
const char *bundle_uri = NULL;
@@ -999,6 +1001,8 @@ int cmd_clone(int argc,
9991001
NULL
10001002
};
10011003

1004+
filter_options.allow_auto_filter = 1;
1005+
10021006
packet_trace_identity("clone");
10031007

10041008
repo_config(the_repository, git_clone_config, NULL);
@@ -1625,9 +1629,13 @@ int cmd_clone(int argc,
16251629
return 1;
16261630

16271631
junk_mode = JUNK_LEAVE_REPO;
1628-
err = checkout(submodule_progress, filter_submodules,
1632+
err = checkout(submodule_progress,
1633+
&filter_options,
1634+
filter_submodules,
16291635
ref_storage_format);
16301636

1637+
list_objects_filter_release(&filter_options);
1638+
16311639
string_list_clear(&option_not, 0);
16321640
string_list_clear(&option_config, 0);
16331641
string_list_clear(&server_options, 0);

0 commit comments

Comments
 (0)