fetch-pack: support negotiation tip whitelist
During negotiation, fetch-pack eventually reports as "have" lines all commits reachable from all refs. Allow the user to restrict the commits sent in this way by providing a whitelist of tips; only the tips themselves and their ancestors will be sent. Both globs and single objects are supported. This feature is only supported for protocols that support connect or stateless-connect (such as HTTP with protocol v2). This will speed up negotiation when the repository has multiple relatively independent branches (for example, when a repository interacts with multiple repositories, such as with linux-next [1] and torvalds/linux [2]), and the user knows which local branch is likely to have commits in common with the upstream branch they are fetching. [1] https://kernel.googlesource.com/pub/scm/linux/kernel/git/next/linux-next/ [2] https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux/ Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
ec06283844
commit
3390e42adb
@ -63,6 +63,7 @@ static int shown_url = 0;
|
||||
static struct refspec refmap = REFSPEC_INIT_FETCH;
|
||||
static struct list_objects_filter_options filter_options;
|
||||
static struct string_list server_options = STRING_LIST_INIT_DUP;
|
||||
static struct string_list negotiation_tip = STRING_LIST_INIT_NODUP;
|
||||
|
||||
static int git_fetch_config(const char *k, const char *v, void *cb)
|
||||
{
|
||||
@ -174,6 +175,8 @@ static struct option builtin_fetch_options[] = {
|
||||
TRANSPORT_FAMILY_IPV4),
|
||||
OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"),
|
||||
TRANSPORT_FAMILY_IPV6),
|
||||
OPT_STRING_LIST(0, "negotiation-tip", &negotiation_tip, N_("revision"),
|
||||
N_("report that we have only objects reachable from this object")),
|
||||
OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
|
||||
OPT_END()
|
||||
};
|
||||
@ -1049,6 +1052,40 @@ static void set_option(struct transport *transport, const char *name, const char
|
||||
name, transport->url);
|
||||
}
|
||||
|
||||
|
||||
static int add_oid(const char *refname, const struct object_id *oid, int flags,
|
||||
void *cb_data)
|
||||
{
|
||||
struct oid_array *oids = cb_data;
|
||||
|
||||
oid_array_append(oids, oid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void add_negotiation_tips(struct git_transport_options *smart_options)
|
||||
{
|
||||
struct oid_array *oids = xcalloc(1, sizeof(*oids));
|
||||
int i;
|
||||
|
||||
for (i = 0; i < negotiation_tip.nr; i++) {
|
||||
const char *s = negotiation_tip.items[i].string;
|
||||
int old_nr;
|
||||
if (!has_glob_specials(s)) {
|
||||
struct object_id oid;
|
||||
if (get_oid(s, &oid))
|
||||
die("%s is not a valid object", s);
|
||||
oid_array_append(oids, &oid);
|
||||
continue;
|
||||
}
|
||||
old_nr = oids->nr;
|
||||
for_each_glob_ref(add_oid, s, oids);
|
||||
if (old_nr == oids->nr)
|
||||
warning("Ignoring --negotiation-tip=%s because it does not match any refs",
|
||||
s);
|
||||
}
|
||||
smart_options->negotiation_tips = oids;
|
||||
}
|
||||
|
||||
static struct transport *prepare_transport(struct remote *remote, int deepen)
|
||||
{
|
||||
struct transport *transport;
|
||||
@ -1075,6 +1112,12 @@ static struct transport *prepare_transport(struct remote *remote, int deepen)
|
||||
filter_options.filter_spec);
|
||||
set_option(transport, TRANS_OPT_FROM_PROMISOR, "1");
|
||||
}
|
||||
if (negotiation_tip.nr) {
|
||||
if (transport->smart_options)
|
||||
add_negotiation_tips(transport->smart_options);
|
||||
else
|
||||
warning("Ignoring --negotiation-tip because the protocol does not support it.");
|
||||
}
|
||||
return transport;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user