diff options
author | Junio C Hamano <gitster@pobox.com> | 2018-08-02 15:30:43 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2018-08-02 15:30:43 -0700 |
commit | 30bf8d9f4f06d8e35793612c8611cb03c53a73db (patch) | |
tree | 194baa306b8fb60956fe05d8a6daa42c6cc0bfb4 /builtin | |
parent | Merge branch 'en/t6042-insane-merge-rename-testcases' (diff) | |
parent | fetch-pack: support negotiation tip whitelist (diff) | |
download | tgif-30bf8d9f4f06d8e35793612c8611cb03c53a73db.tar.xz |
Merge branch 'jt/fetch-nego-tip'
"git fetch" learned a new option "--negotiation-tip" to limit the
set of commits it tells the other end as "have", to reduce wasted
bandwidth and cycles, which would be helpful when the receiving
repository has a lot of refs that have little to do with the
history at the remote it is fetching from.
* jt/fetch-nego-tip:
fetch-pack: support negotiation tip whitelist
Diffstat (limited to 'builtin')
-rw-r--r-- | builtin/fetch.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/builtin/fetch.c b/builtin/fetch.c index c3c58a5453..34d2bd123b 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -64,6 +64,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) { @@ -162,6 +163,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() }; @@ -1060,6 +1063,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; @@ -1086,6 +1123,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; } |