Skip to content

Commit 644f4a2

Browse files
committed
Merge branch 'jt/push-negotiation'
"git push" learns to discover common ancestor with the receiving end over protocol v2. * jt/push-negotiation: send-pack: support push negotiation fetch: teach independent negotiation (no packfile) fetch-pack: refactor command and capability write fetch-pack: refactor add_haves() fetch-pack: refactor process_acks()
2 parents 97eea85 + 477673d commit 644f4a2

File tree

14 files changed

+455
-100
lines changed

14 files changed

+455
-100
lines changed

Documentation/config/push.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,10 @@ push.useForceIfIncludes::
120120
`--force-if-includes` as an option to linkgit:git-push[1]
121121
in the command line. Adding `--no-force-if-includes` at the
122122
time of push overrides this configuration setting.
123+
124+
push.negotiate::
125+
If set to "true", attempt to reduce the size of the packfile
126+
sent by rounds of negotiation in which the client and the
127+
server attempt to find commits in common. If "false", Git will
128+
rely solely on the server's ref advertisement to find commits
129+
in common.

Documentation/technical/protocol-v2.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,14 @@ explained below.
346346
client should download from all given URIs. Currently, the
347347
protocols supported are "http" and "https".
348348

349+
If the 'wait-for-done' feature is advertised, the following argument
350+
can be included in the client's request.
351+
352+
wait-for-done
353+
Indicates to the server that it should never send "ready", but
354+
should wait for the client to say "done" before sending the
355+
packfile.
356+
349357
The response of `fetch` is broken into a number of sections separated by
350358
delimiter packets (0001), with each section beginning with its section
351359
header. Most sections are sent only when the packfile is sent.

builtin/fetch.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ static struct string_list server_options = STRING_LIST_INIT_DUP;
8383
static struct string_list negotiation_tip = STRING_LIST_INIT_NODUP;
8484
static int fetch_write_commit_graph = -1;
8585
static int stdin_refspecs = 0;
86+
static int negotiate_only;
8687

8788
static int git_fetch_config(const char *k, const char *v, void *cb)
8889
{
@@ -205,6 +206,8 @@ static struct option builtin_fetch_options[] = {
205206
TRANSPORT_FAMILY_IPV6),
206207
OPT_STRING_LIST(0, "negotiation-tip", &negotiation_tip, N_("revision"),
207208
N_("report that we have only objects reachable from this object")),
209+
OPT_BOOL(0, "negotiate-only", &negotiate_only,
210+
N_("do not fetch a packfile; instead, print ancestors of negotiation tips")),
208211
OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
209212
OPT_BOOL(0, "auto-maintenance", &enable_auto_gc,
210213
N_("run 'maintenance --auto' after fetching")),
@@ -2043,7 +2046,29 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
20432046
}
20442047
}
20452048

2046-
if (remote) {
2049+
if (negotiate_only) {
2050+
struct oidset acked_commits = OIDSET_INIT;
2051+
struct oidset_iter iter;
2052+
const struct object_id *oid;
2053+
2054+
if (!remote)
2055+
die(_("must supply remote when using --negotiate-only"));
2056+
gtransport = prepare_transport(remote, 1);
2057+
if (gtransport->smart_options) {
2058+
gtransport->smart_options->acked_commits = &acked_commits;
2059+
} else {
2060+
warning(_("Protocol does not support --negotiate-only, exiting."));
2061+
return 1;
2062+
}
2063+
if (server_options.nr)
2064+
gtransport->server_options = &server_options;
2065+
result = transport_fetch_refs(gtransport, NULL);
2066+
2067+
oidset_iter_init(&acked_commits, &iter);
2068+
while ((oid = oidset_iter_next(&iter)))
2069+
printf("%s\n", oid_to_hex(oid));
2070+
oidset_clear(&acked_commits);
2071+
} else if (remote) {
20472072
if (filter_options.choice || has_promisor_remote())
20482073
fetch_one_setup_partial(remote);
20492074
result = fetch_one(remote, argc, argv, prune_tags_ok, stdin_refspecs);

0 commit comments

Comments
 (0)