Use the partial clone feature and request that the server sends
a subset of reachable objects according to a given object filter.
When using `--filter`, the supplied _<filter-spec>_ is used for
- the partial fetch. For example, `--filter=blob:none` will filter
- out all blobs (file contents) until needed by Git. Also,
- `--filter=blob:limit=<size>` will filter out all blobs of size
- at least _<size>_. For more details on filter specifications, see
- the `--filter` option in linkgit:git-rev-list[1].
+ the partial fetch.
++
+If `--filter=auto` is used, the filter specification is determined
+automatically by combining the filter specifications advertised by
+the server for the promisor remotes that the client accepts (see
+linkgit:gitprotocol-v2[5] and the `promisor.acceptFromServer`
+configuration option in linkgit:git-config[1]).
++
+For details on all other available filter specifications, see the
+`--filter=<filter-spec>` option in linkgit:git-rev-list[1].
++
+For example, `--filter=blob:none` will filter out all blobs (file
+contents) until needed by Git. Also, `--filter=blob:limit=<size>` will
+filter out all blobs of size at least _<size>_.
ifndef::git-pull[]
`--write-fetch-head`::
Use the partial clone feature and request that the server sends
a subset of reachable objects according to a given object filter.
When using `--filter`, the supplied _<filter-spec>_ is used for
- the partial clone filter. For example, `--filter=blob:none` will
- filter out all blobs (file contents) until needed by Git. Also,
- `--filter=blob:limit=<size>` will filter out all blobs of size
- at least _<size>_. For more details on filter specifications, see
- the `--filter` option in linkgit:git-rev-list[1].
+ the partial clone filter.
++
+If `--filter=auto` is used the filter specification is determined
+automatically through the 'promisor-remote' protocol (see
+linkgit:gitprotocol-v2[5]) by combining the filter specifications
+advertised by the server for the promisor remotes that the client
+accepts (see the `promisor.acceptFromServer` configuration option in
+linkgit:git-config[1]). This allows the server to suggest the optimal
+filter for the available promisor remotes.
++
+As with other filter specifications, the "auto" value is persisted in
+the configuration. This ensures that future fetches will continue to
+adapt to the server's current recommendation.
++
+For details on all other available filter specifications, see the
+`--filter=<filter-spec>` option in linkgit:git-rev-list[1].
++
+For example, `--filter=blob:none` will filter out all blobs (file
+contents) until needed by Git. Also, `--filter=blob:limit=<size>` will
+filter out all blobs of size at least _<size>_.
`--also-filter-submodules`::
Also apply the partial clone filter to any submodules in the repository.
After these mandatory fields, the server MAY advertise the following
optional fields in any order:
-`partialCloneFilter`:: The filter specification used by the remote.
+`partialCloneFilter`:: The filter specification for the remote. It
+corresponds to the "remote.<name>.partialCloneFilter" config setting.
Clients can use this to determine if the remote's filtering strategy
-is compatible with their needs (e.g., checking if both use "blob:none").
-It corresponds to the "remote.<name>.partialCloneFilter" config setting.
+is compatible with their needs (e.g., checking if both use
+"blob:none"). Additionally they can use this through the
+`--filter=auto` option in linkgit:git-clone[1]. With that option, the
+filter specification of the clone will be automatically computed by
+combining the filter specifications of the promisor remotes the client
+accepts.
`token`:: An authentication token that clients can use when
connecting to the remote. It corresponds to the "remote.<name>.token"
The client can use information transmitted through these fields to
decide if it accepts the advertised promisor remote. Also, the client
-can be configured to store the values of these fields (see
-"promisor.storeFields" in linkgit:git-config[1]).
+can be configured to store the values of these fields or use them
+to automatically configure the repository (see "promisor.storeFields"
+in linkgit:git-config[1] and `--filter=auto` in linkgit:git-clone[1]).
Field values MUST be urlencoded.
NULL
};
+ filter_options.allow_auto_filter = 1;
+
packet_trace_identity("clone");
repo_config(the_repository, git_clone_config, NULL);
OPT_END()
};
+ filter_options.allow_auto_filter = 1;
+
packet_trace_identity("fetch");
/* Record the command line for the reflog */
#include "sigchain.h"
#include "mergesort.h"
#include "prio-queue.h"
+#include "promisor-remote.h"
static int transfer_unpack_limit = -1;
static int fetch_unpack_limit = -1;
struct string_list packfile_uris = STRING_LIST_INIT_DUP;
int i;
struct strvec index_pack_args = STRVEC_INIT;
+ const char *promisor_remote_config;
+
+ if (server_feature_v2("promisor-remote", &promisor_remote_config)) {
+ char *remote_name = promisor_remote_reply(promisor_remote_config);
+ free(remote_name);
+ }
+
+ if (args->filter_options.choice == LOFC_AUTO) {
+ struct strbuf errbuf = STRBUF_INIT;
+ char *constructed_filter = promisor_remote_construct_filter(r);
+
+ list_objects_filter_resolve_auto(&args->filter_options,
+ constructed_filter, &errbuf);
+ if (errbuf.len > 0)
+ die(_("couldn't resolve 'auto' filter: %s"), errbuf.buf);
+
+ free(constructed_filter);
+ strbuf_release(&errbuf);
+ }
negotiator = &negotiator_alloc;
if (args->refetch)
check_missing_objects server 1 "$oid"
'
+test_expect_success "clone and fetch with --filter=auto" '
+ git -C server config promisor.advertise true &&
+ test_when_finished "rm -rf client trace" &&
+
+ git -C server config remote.lop.partialCloneFilter "blob:limit=9500" &&
+ test_config -C server promisor.sendFields "partialCloneFilter" &&
+
+ GIT_TRACE_PACKET="$(pwd)/trace" GIT_NO_LAZY_FETCH=0 git clone \
+ -c remote.lop.promisor=true \
+ -c remote.lop.url="file://$(pwd)/lop" \
+ -c promisor.acceptfromserver=All \
+ --no-local --filter=auto server client 2>err &&
+
+ test_grep "filter blob:limit=9500" trace &&
+ test_grep ! "filter auto" trace &&
+
+ # Verify "auto" is persisted in config
+ echo auto >expected &&
+ git -C client config remote.origin.partialCloneFilter >actual &&
+ test_cmp expected actual &&
+
+ # Check that the largest object is still missing on the server
+ check_missing_objects server 1 "$oid" &&
+
+ # Now change the filter on the server
+ git -C server config remote.lop.partialCloneFilter "blob:limit=5678" &&
+
+ # Get a new commit on the server to ensure "git fetch" actually runs fetch-pack
+ test_commit -C template new-commit &&
+ git -C template push --all "$(pwd)/server" &&
+
+ # Perform a fetch WITH --filter=auto
+ rm -rf trace &&
+ GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch --filter=auto &&
+
+ # Verify that the new filter was used
+ test_grep "filter blob:limit=5678" trace &&
+
+ # Check that the largest object is still missing on the server
+ check_missing_objects server 1 "$oid" &&
+
+ # Change the filter on the server again
+ git -C server config remote.lop.partialCloneFilter "blob:limit=5432" &&
+
+ # Get yet a new commit on the server to ensure fetch-pack runs
+ test_commit -C template yet-a-new-commit &&
+ git -C template push --all "$(pwd)/server" &&
+
+ # Perform a fetch WITHOUT --filter=auto
+ # Relies on "auto" being persisted in the client config
+ rm -rf trace &&
+ GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch &&
+
+ # Verify that the new filter was used
+ test_grep "filter blob:limit=5432" trace &&
+
+ # Check that the largest object is still missing on the server
+ check_missing_objects server 1 "$oid"
+'
+
test_expect_success "clone with promisor.advertise set to 'true' but don't delete the client" '
git -C server config promisor.advertise true &&
*/
struct git_transport_data *data = xcalloc(1, sizeof(*data));
list_objects_filter_init(&data->options.filter_options);
+ data->options.filter_options.allow_auto_filter = 1;
ret->data = data;
ret->vtable = &builtin_smart_vtable;
ret->smart_options = &(data->options);