fetch-pack: introduce negotiator API

Introduce the new files fetch-negotiator.{h,c}, which contains an API behind which the details of negotiation are abstracted. Currently, only one algorithm is available: the existing one. This patch is written to be easily reviewed: static functions are moved verbatim from fetch-pack.c to negotiator/default.c, and it can be seen that the lines replaced by negotiator->X() calls are present in the X() functions respectively. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jonathan Tan committed Jun 14, 2018 at 15:54 UTC ec06283844a90c3e9440286401e9ad7d86daa5ae
7 files changed +292 -167
Makefile
+2
@@ -859,6 +859,7 @@ LIB_OBJS += ewah/ewah_bitmap.o
859 LIB_OBJS += ewah/ewah_io.o
860 LIB_OBJS += ewah/ewah_rlw.o
861 LIB_OBJS += exec-cmd.o
862 +LIB_OBJS += fetch-negotiator.o
863 LIB_OBJS += fetch-object.o
864 LIB_OBJS += fetch-pack.o
865 LIB_OBJS += fsck.o
@@ -891,6 +892,7 @@ LIB_OBJS += merge-blobs.o
892 LIB_OBJS += merge-recursive.o
893 LIB_OBJS += mergesort.o
894 LIB_OBJS += name-hash.o
895 +LIB_OBJS += negotiator/default.o
896 LIB_OBJS += notes.o
897 LIB_OBJS += notes-cache.o
898 LIB_OBJS += notes-merge.o
fetch-negotiator.c new
+8
@@ -0,0 +1,8 @@
1 +#include "git-compat-util.h"
2 +#include "fetch-negotiator.h"
3 +#include "negotiator/default.h"
4 +
5 +void fetch_negotiator_init(struct fetch_negotiator *negotiator)
6 +{
7 + default_negotiator_init(negotiator);
8 +}
fetch-negotiator.h new
+57
@@ -0,0 +1,57 @@
1 +#ifndef FETCH_NEGOTIATOR
2 +#define FETCH_NEGOTIATOR
3 +
4 +struct commit;
5 +
6 +/*
7 + * An object that supplies the information needed to negotiate the contents of
8 + * the to-be-sent packfile during a fetch.
9 + *
10 + * To set up the negotiator, call fetch_negotiator_init(), then known_common()
11 + * (0 or more times), then add_tip() (0 or more times).
12 + *
13 + * Then, when "have" lines are required, call next(). Call ack() to report what
14 + * the server tells us.
15 + *
16 + * Once negotiation is done, call release(). The negotiator then cannot be used
17 + * (unless reinitialized with fetch_negotiator_init()).
18 + */
19 +struct fetch_negotiator {
20 + /*
21 + * Before negotiation starts, indicate that the server is known to have
22 + * this commit.
23 + */
24 + void (*known_common)(struct fetch_negotiator *, struct commit *);
25 +
26 + /*
27 + * Once this function is invoked, known_common() cannot be invoked any
28 + * more.
29 + *
30 + * Indicate that this commit and all its ancestors are to be checked
31 + * for commonality with the server.
32 + */
33 + void (*add_tip)(struct fetch_negotiator *, struct commit *);
34 +
35 + /*
36 + * Once this function is invoked, known_common() and add_tip() cannot
37 + * be invoked any more.
38 + *
39 + * Return the next commit that the client should send as a "have" line.
40 + */
41 + const struct object_id *(*next)(struct fetch_negotiator *);
42 +
43 + /*
44 + * Inform the negotiator that the server has the given commit. This
45 + * method must only be called on commits returned by next().
46 + */
47 + int (*ack)(struct fetch_negotiator *, struct commit *);
48 +
49 + void (*release)(struct fetch_negotiator *);
50 +
51 + /* internal use */
52 + void *data;
53 +};
54 +
55 +void fetch_negotiator_init(struct fetch_negotiator *negotiator);
56 +
57 +#endif
fetch-pack.c
+39 -166
@@ -15,10 +15,10 @@
15 #include "connect.h"
16 #include "transport.h"
17 #include "version.h"
18 -#include "prio-queue.h"
18 #include "sha1-array.h"
19 #include "oidset.h"
20 #include "packfile.h"
21 +#include "fetch-negotiator.h"
22
23 static int transfer_unpack_limit = -1;
24 static int fetch_unpack_limit = -1;
@@ -36,13 +36,7 @@ static const char *alternate_shallow_file;
36
37 /* Remember to update object flag allocation in object.h */
38 #define COMPLETE (1U << 0)
39 -#define COMMON (1U << 1)
40 -#define COMMON_REF (1U << 2)
41 -#define SEEN (1U << 3)
42 -#define POPPED (1U << 4)
43 -#define ALTERNATE (1U << 5)
44 -
45 -static int marked;
39 +#define ALTERNATE (1U << 1)
40
41 /*
42 * After sending this many "have"s if we do not get any new ACK , we
@@ -50,11 +44,6 @@ static int marked;
44 */
45 #define MAX_IN_VAIN 256
46
53 -struct negotiation_state {
54 - struct prio_queue rev_list;
55 - int non_common_revs;
56 -};
57 -
47 static int multi_ack, use_sideband;
48 /* Allow specifying sha1 if it is a ref tip. */
49 #define ALLOW_TIP_SHA1 01
@@ -97,8 +86,8 @@ static void cache_one_alternate(const char *refname,
86 cache->items[cache->nr++] = obj;
87 }
88
100 -static void for_each_cached_alternate(struct negotiation_state *ns,
101 - void (*cb)(struct negotiation_state *,
89 +static void for_each_cached_alternate(struct fetch_negotiator *negotiator,
90 + void (*cb)(struct fetch_negotiator *,
91 struct object *))
92 {
93 static int initialized;
@@ -111,33 +100,17 @@ static void for_each_cached_alternate(struct negotiation_state *ns,
100 }
101
102 for (i = 0; i < cache.nr; i++)
114 - cb(ns, cache.items[i]);
115 -}
116 -
117 -static void rev_list_push(struct negotiation_state *ns,
118 - struct commit *commit, int mark)
119 -{
120 - if (!(commit->object.flags & mark)) {
121 - commit->object.flags |= mark;
122 -
123 - if (parse_commit(commit))
124 - return;
125 -
126 - prio_queue_put(&ns->rev_list, commit);
127 -
128 - if (!(commit->object.flags & COMMON))
129 - ns->non_common_revs++;
130 - }
103 + cb(negotiator, cache.items[i]);
104 }
105
133 -static int rev_list_insert_ref(struct negotiation_state *ns,
106 +static int rev_list_insert_ref(struct fetch_negotiator *negotiator,
107 const char *refname,
108 const struct object_id *oid)
109 {
110 struct object *o = deref_tag(parse_object(oid), refname, 0);
111
112 if (o && o->type == OBJ_COMMIT)
140 - rev_list_push(ns, (struct commit *)o, SEEN);
113 + negotiator->add_tip(negotiator, (struct commit *)o);
114
115 return 0;
116 }
@@ -148,98 +121,6 @@ static int rev_list_insert_ref_oid(const char *refname, const struct object_id *
121 return rev_list_insert_ref(cb_data, refname, oid);
122 }
123
151 -static int clear_marks(const char *refname, const struct object_id *oid,
152 - int flag, void *cb_data)
153 -{
154 - struct object *o = deref_tag(parse_object(oid), refname, 0);
155 -
156 - if (o && o->type == OBJ_COMMIT)
157 - clear_commit_marks((struct commit *)o,
158 - COMMON | COMMON_REF | SEEN | POPPED);
159 - return 0;
160 -}
161 -
162 -/*
163 - This function marks a rev and its ancestors as common.
164 - In some cases, it is desirable to mark only the ancestors (for example
165 - when only the server does not yet know that they are common).
166 -*/
167 -
168 -static void mark_common(struct negotiation_state *ns, struct commit *commit,
169 - int ancestors_only, int dont_parse)
170 -{
171 - if (commit != NULL && !(commit->object.flags & COMMON)) {
172 - struct object *o = (struct object *)commit;
173 -
174 - if (!ancestors_only)
175 - o->flags |= COMMON;
176 -
177 - if (!(o->flags & SEEN))
178 - rev_list_push(ns, commit, SEEN);
179 - else {
180 - struct commit_list *parents;
181 -
182 - if (!ancestors_only && !(o->flags & POPPED))
183 - ns->non_common_revs--;
184 - if (!o->parsed && !dont_parse)
185 - if (parse_commit(commit))
186 - return;
187 -
188 - for (parents = commit->parents;
189 - parents;
190 - parents = parents->next)
191 - mark_common(ns, parents->item, 0,
192 - dont_parse);
193 - }
194 - }
195 -}
196 -
197 -/*
198 - Get the next rev to send, ignoring the common.
199 -*/
200 -
201 -static const struct object_id *get_rev(struct negotiation_state *ns)
202 -{
203 - struct commit *commit = NULL;
204 -
205 - while (commit == NULL) {
206 - unsigned int mark;
207 - struct commit_list *parents;
208 -
209 - if (ns->rev_list.nr == 0 || ns->non_common_revs == 0)
210 - return NULL;
211 -
212 - commit = prio_queue_get(&ns->rev_list);
213 - parse_commit(commit);
214 - parents = commit->parents;
215 -
216 - commit->object.flags |= POPPED;
217 - if (!(commit->object.flags & COMMON))
218 - ns->non_common_revs--;
219 -
220 - if (commit->object.flags & COMMON) {
221 - /* do not send "have", and ignore ancestors */
222 - commit = NULL;
223 - mark = COMMON | SEEN;
224 - } else if (commit->object.flags & COMMON_REF)
225 - /* send "have", and ignore ancestors */
226 - mark = COMMON | SEEN;
227 - else
228 - /* send "have", also for its ancestors */
229 - mark = SEEN;
230 -
231 - while (parents) {
232 - if (!(parents->item->object.flags & SEEN))
233 - rev_list_push(ns, parents->item, mark);
234 - if (mark & COMMON)
235 - mark_common(ns, parents->item, 1, 0);
236 - parents = parents->next;
237 - }
238 - }
239 -
240 - return &commit->object.oid;
241 -}
242 -
124 enum ack_type {
125 NAK = 0,
126 ACK,
@@ -306,10 +187,10 @@ static void send_request(struct fetch_pack_args *args,
187 write_or_die(fd, buf->buf, buf->len);
188 }
189
309 -static void insert_one_alternate_object(struct negotiation_state *ns,
190 +static void insert_one_alternate_object(struct fetch_negotiator *negotiator,
191 struct object *obj)
192 {
312 - rev_list_insert_ref(ns, NULL, &obj->oid);
193 + rev_list_insert_ref(negotiator, NULL, &obj->oid);
194 }
195
196 #define INITIAL_FLUSH 16
@@ -332,7 +213,7 @@ static int next_flush(int stateless_rpc, int count)
213 return count;
214 }
215
335 -static int find_common(struct negotiation_state *ns,
216 +static int find_common(struct fetch_negotiator *negotiator,
217 struct fetch_pack_args *args,
218 int fd[2], struct object_id *result_oid,
219 struct ref *refs)
@@ -349,8 +230,8 @@ static int find_common(struct negotiation_state *ns,
230 if (args->stateless_rpc && multi_ack == 1)
231 die(_("--stateless-rpc requires multi_ack_detailed"));
232
352 - for_each_ref(rev_list_insert_ref_oid, ns);
353 - for_each_cached_alternate(ns, insert_one_alternate_object);
233 + for_each_ref(rev_list_insert_ref_oid, negotiator);
234 + for_each_cached_alternate(negotiator, insert_one_alternate_object);
235
236 fetching = 0;
237 for ( ; refs ; refs = refs->next) {
@@ -468,7 +349,7 @@ static int find_common(struct negotiation_state *ns,
349 retval = -1;
350 if (args->no_dependents)
351 goto done;
471 - while ((oid = get_rev(ns))) {
352 + while ((oid = negotiator->next(negotiator))) {
353 packet_buf_write(&req_buf, "have %s\n", oid_to_hex(oid));
354 print_verbose(args, "have %s", oid_to_hex(oid));
355 in_vain++;
@@ -508,8 +389,7 @@ static int find_common(struct negotiation_state *ns,
389 int was_common;
390 if (!commit)
391 die(_("invalid commit %s"), oid_to_hex(result_oid));
511 - was_common = commit->object.flags & COMMON;
512 - mark_common(ns, commit, 0, 1);
392 + was_common = negotiator->ack(negotiator, commit);
393 if (args->stateless_rpc
394 && ack == ACK_common
395 && !was_common) {
@@ -718,7 +598,7 @@ static void filter_refs(struct fetch_pack_args *args,
598 *refs = newlist;
599 }
600
721 -static void mark_alternate_complete(struct negotiation_state *unused,
601 +static void mark_alternate_complete(struct fetch_negotiator *unused,
602 struct object *obj)
603 {
604 mark_complete(&obj->oid);
@@ -756,7 +636,7 @@ static int add_loose_objects_to_set(const struct object_id *oid,
636 * earliest commit time of the objects in refs that are commits and that we know
637 * the commit time of.
638 */
759 -static void mark_complete_and_common_ref(struct negotiation_state *ns,
639 +static void mark_complete_and_common_ref(struct fetch_negotiator *negotiator,
640 struct fetch_pack_args *args,
641 struct ref **refs)
642 {
@@ -825,12 +705,8 @@ static void mark_complete_and_common_ref(struct negotiation_state *ns,
705 if (!o || o->type != OBJ_COMMIT || !(o->flags & COMPLETE))
706 continue;
707
828 - if (!(o->flags & SEEN)) {
829 - rev_list_push(ns, (struct commit *)o,
830 - COMMON_REF | SEEN);
831 -
832 - mark_common(ns, (struct commit *)o, 1, 1);
833 - }
708 + negotiator->known_common(negotiator,
709 + (struct commit *)o);
710 }
711 }
712
@@ -1012,7 +888,8 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
888 struct object_id oid;
889 const char *agent_feature;
890 int agent_len;
1015 - struct negotiation_state ns = { { compare_commits_by_commit_date } };
891 + struct fetch_negotiator negotiator;
892 + fetch_negotiator_init(&negotiator);
893
894 sort_ref_list(&ref, ref_compare_name);
895 QSORT(sought, nr_sought, cmp_ref_by_name);
@@ -1085,16 +962,13 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
962 if (!server_supports("deepen-relative") && args->deepen_relative)
963 die(_("Server does not support --deepen"));
964
1088 - if (marked)
1089 - for_each_ref(clear_marks, NULL);
1090 - marked = 1;
1091 - mark_complete_and_common_ref(&ns, args, &ref);
965 + mark_complete_and_common_ref(&negotiator, args, &ref);
966 filter_refs(args, &ref, sought, nr_sought);
967 if (everything_local(args, &ref)) {
968 packet_flush(fd[1]);
969 goto all_done;
970 }
1097 - if (find_common(&ns, args, fd, &oid, ref) < 0)
971 + if (find_common(&negotiator, args, fd, &oid, ref) < 0)
972 if (!args->keep_pack)
973 /* When cloning, it is not unusual to have
974 * no common commit.
@@ -1114,7 +988,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
988 die(_("git fetch-pack: fetch failed."));
989
990 all_done:
1117 - clear_prio_queue(&ns.rev_list);
991 + negotiator.release(&negotiator);
992 return ref;
993 }
994
@@ -1176,14 +1050,15 @@ static void add_common(struct strbuf *req_buf, struct oidset *common)
1050 }
1051 }
1052
1179 -static int add_haves(struct negotiation_state *ns, struct strbuf *req_buf,
1053 +static int add_haves(struct fetch_negotiator *negotiator,
1054 + struct strbuf *req_buf,
1055 int *haves_to_send, int *in_vain)
1056 {
1057 int ret = 0;
1058 int haves_added = 0;
1059 const struct object_id *oid;
1060
1186 - while ((oid = get_rev(ns))) {
1061 + while ((oid = negotiator->next(negotiator))) {
1062 packet_buf_write(req_buf, "have %s\n", oid_to_hex(oid));
1063 if (++haves_added >= *haves_to_send)
1064 break;
@@ -1202,7 +1077,7 @@ static int add_haves(struct negotiation_state *ns, struct strbuf *req_buf,
1077 return ret;
1078 }
1079
1205 -static int send_fetch_request(struct negotiation_state *ns, int fd_out,
1080 +static int send_fetch_request(struct fetch_negotiator *negotiator, int fd_out,
1081 const struct fetch_pack_args *args,
1082 const struct ref *wants, struct oidset *common,
1083 int *haves_to_send, int *in_vain)
@@ -1259,7 +1134,7 @@ static int send_fetch_request(struct negotiation_state *ns, int fd_out,
1134 add_common(&req_buf, common);
1135
1136 /* Add initial haves */
1262 - ret = add_haves(ns, &req_buf, haves_to_send, in_vain);
1137 + ret = add_haves(negotiator, &req_buf, haves_to_send, in_vain);
1138 }
1139
1140 /* Send request */
@@ -1296,7 +1171,7 @@ static int process_section_header(struct packet_reader *reader,
1171 return ret;
1172 }
1173
1299 -static int process_acks(struct negotiation_state *ns,
1174 +static int process_acks(struct fetch_negotiator *negotiator,
1175 struct packet_reader *reader,
1176 struct oidset *common)
1177 {
@@ -1317,7 +1192,7 @@ static int process_acks(struct negotiation_state *ns,
1192 struct commit *commit;
1193 oidset_insert(common, &oid);
1194 commit = lookup_commit(&oid);
1320 - mark_common(ns, commit, 0, 1);
1195 + negotiator->ack(negotiator, commit);
1196 }
1197 continue;
1198 }
@@ -1395,7 +1270,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1270 struct packet_reader reader;
1271 int in_vain = 0;
1272 int haves_to_send = INITIAL_FLUSH;
1398 - struct negotiation_state ns = { { compare_commits_by_commit_date } };
1273 + struct fetch_negotiator negotiator;
1274 + fetch_negotiator_init(&negotiator);
1275 packet_reader_init(&reader, fd[0], NULL, 0,
1276 PACKET_READ_CHOMP_NEWLINE);
1277
@@ -1411,24 +1287,21 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1287 if (args->depth > 0 || args->deepen_since || args->deepen_not)
1288 args->deepen = 1;
1289
1414 - if (marked)
1415 - for_each_ref(clear_marks, NULL);
1416 - marked = 1;
1417 -
1290 /* Filter 'ref' by 'sought' and those that aren't local */
1419 - mark_complete_and_common_ref(&ns, args, &ref);
1291 + mark_complete_and_common_ref(&negotiator, args, &ref);
1292 filter_refs(args, &ref, sought, nr_sought);
1293 if (everything_local(args, &ref))
1294 state = FETCH_DONE;
1295 else
1296 state = FETCH_SEND_REQUEST;
1297
1426 - for_each_ref(rev_list_insert_ref_oid, &ns);
1427 - for_each_cached_alternate(&ns,
1298 + for_each_ref(rev_list_insert_ref_oid, &negotiator);
1299 + for_each_cached_alternate(&negotiator,
1300 insert_one_alternate_object);
1301 break;
1302 case FETCH_SEND_REQUEST:
1431 - if (send_fetch_request(&ns, fd[1], args, ref, &common,
1303 + if (send_fetch_request(&negotiator, fd[1], args, ref,
1304 + &common,
1305 &haves_to_send, &in_vain))
1306 state = FETCH_GET_PACK;
1307 else
@@ -1436,7 +1309,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1309 break;
1310 case FETCH_PROCESS_ACKS:
1311 /* Process ACKs/NAKs */
1439 - switch (process_acks(&ns, &reader, &common)) {
1312 + switch (process_acks(&negotiator, &reader, &common)) {
1313 case 2:
1314 state = FETCH_GET_PACK;
1315 break;
@@ -1465,7 +1338,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1338 }
1339 }
1340
1468 - clear_prio_queue(&ns.rev_list);
1341 + negotiator.release(&negotiator);
1342 oidset_clear(&common);
1343 return ref;
1344 }
negotiator/default.c new
+176
@@ -0,0 +1,176 @@
1 +#include "cache.h"
2 +#include "default.h"
3 +#include "../commit.h"
4 +#include "../fetch-negotiator.h"
5 +#include "../prio-queue.h"
6 +#include "../refs.h"
7 +#include "../tag.h"
8 +
9 +/* Remember to update object flag allocation in object.h */
10 +#define COMMON (1U << 2)
11 +#define COMMON_REF (1U << 3)
12 +#define SEEN (1U << 4)
13 +#define POPPED (1U << 5)
14 +
15 +static int marked;
16 +
17 +struct negotiation_state {
18 + struct prio_queue rev_list;
19 + int non_common_revs;
20 +};
21 +
22 +static void rev_list_push(struct negotiation_state *ns,
23 + struct commit *commit, int mark)
24 +{
25 + if (!(commit->object.flags & mark)) {
26 + commit->object.flags |= mark;
27 +
28 + if (parse_commit(commit))
29 + return;
30 +
31 + prio_queue_put(&ns->rev_list, commit);
32 +
33 + if (!(commit->object.flags & COMMON))
34 + ns->non_common_revs++;
35 + }
36 +}
37 +
38 +static int clear_marks(const char *refname, const struct object_id *oid,
39 + int flag, void *cb_data)
40 +{
41 + struct object *o = deref_tag(parse_object(oid), refname, 0);
42 +
43 + if (o && o->type == OBJ_COMMIT)
44 + clear_commit_marks((struct commit *)o,
45 + COMMON | COMMON_REF | SEEN | POPPED);
46 + return 0;
47 +}
48 +
49 +/*
50 + * This function marks a rev and its ancestors as common.
51 + * In some cases, it is desirable to mark only the ancestors (for example
52 + * when only the server does not yet know that they are common).
53 + */
54 +static void mark_common(struct negotiation_state *ns, struct commit *commit,
55 + int ancestors_only, int dont_parse)
56 +{
57 + if (commit != NULL && !(commit->object.flags & COMMON)) {
58 + struct object *o = (struct object *)commit;
59 +
60 + if (!ancestors_only)
61 + o->flags |= COMMON;
62 +
63 + if (!(o->flags & SEEN))
64 + rev_list_push(ns, commit, SEEN);
65 + else {
66 + struct commit_list *parents;
67 +
68 + if (!ancestors_only && !(o->flags & POPPED))
69 + ns->non_common_revs--;
70 + if (!o->parsed && !dont_parse)
71 + if (parse_commit(commit))
72 + return;
73 +
74 + for (parents = commit->parents;
75 + parents;
76 + parents = parents->next)
77 + mark_common(ns, parents->item, 0,
78 + dont_parse);
79 + }
80 + }
81 +}
82 +
83 +/*
84 + * Get the next rev to send, ignoring the common.
85 + */
86 +static const struct object_id *get_rev(struct negotiation_state *ns)
87 +{
88 + struct commit *commit = NULL;
89 +
90 + while (commit == NULL) {
91 + unsigned int mark;
92 + struct commit_list *parents;
93 +
94 + if (ns->rev_list.nr == 0 || ns->non_common_revs == 0)
95 + return NULL;
96 +
97 + commit = prio_queue_get(&ns->rev_list);
98 + parse_commit(commit);
99 + parents = commit->parents;
100 +
101 + commit->object.flags |= POPPED;
102 + if (!(commit->object.flags & COMMON))
103 + ns->non_common_revs--;
104 +
105 + if (commit->object.flags & COMMON) {
106 + /* do not send "have", and ignore ancestors */
107 + commit = NULL;
108 + mark = COMMON | SEEN;
109 + } else if (commit->object.flags & COMMON_REF)
110 + /* send "have", and ignore ancestors */
111 + mark = COMMON | SEEN;
112 + else
113 + /* send "have", also for its ancestors */
114 + mark = SEEN;
115 +
116 + while (parents) {
117 + if (!(parents->item->object.flags & SEEN))
118 + rev_list_push(ns, parents->item, mark);
119 + if (mark & COMMON)
120 + mark_common(ns, parents->item, 1, 0);
121 + parents = parents->next;
122 + }
123 + }
124 +
125 + return &commit->object.oid;
126 +}
127 +
128 +static void known_common(struct fetch_negotiator *n, struct commit *c)
129 +{
130 + if (!(c->object.flags & SEEN)) {
131 + rev_list_push(n->data, c, COMMON_REF | SEEN);
132 + mark_common(n->data, c, 1, 1);
133 + }
134 +}
135 +
136 +static void add_tip(struct fetch_negotiator *n, struct commit *c)
137 +{
138 + n->known_common = NULL;
139 + rev_list_push(n->data, c, SEEN);
140 +}
141 +
142 +static const struct object_id *next(struct fetch_negotiator *n)
143 +{
144 + n->known_common = NULL;
145 + n->add_tip = NULL;
146 + return get_rev(n->data);
147 +}
148 +
149 +static int ack(struct fetch_negotiator *n, struct commit *c)
150 +{
151 + int known_to_be_common = !!(c->object.flags & COMMON);
152 + mark_common(n->data, c, 0, 1);
153 + return known_to_be_common;
154 +}
155 +
156 +static void release(struct fetch_negotiator *n)
157 +{
158 + clear_prio_queue(&((struct negotiation_state *)n->data)->rev_list);
159 + FREE_AND_NULL(n->data);
160 +}
161 +
162 +void default_negotiator_init(struct fetch_negotiator *negotiator)
163 +{
164 + struct negotiation_state *ns;
165 + negotiator->known_common = known_common;
166 + negotiator->add_tip = add_tip;
167 + negotiator->next = next;
168 + negotiator->ack = ack;
169 + negotiator->release = release;
170 + negotiator->data = ns = xcalloc(1, sizeof(*ns));
171 + ns->rev_list.compare = compare_commits_by_commit_date;
172 +
173 + if (marked)
174 + for_each_ref(clear_marks, NULL);
175 + marked = 1;
176 +}
negotiator/default.h new
+8
@@ -0,0 +1,8 @@
1 +#ifndef NEGOTIATOR_DEFAULT_H
2 +#define NEGOTIATOR_DEFAULT_H
3 +
4 +struct fetch_negotiator;
5 +
6 +void default_negotiator_init(struct fetch_negotiator *negotiator);
7 +
8 +#endif
object.h
+2 -1
@@ -28,7 +28,8 @@ struct object_array {
28 /*
29 * object flag allocation:
30 * revision.h: 0---------10 26
31 - * fetch-pack.c: 0----5
31 + * fetch-pack.c: 01
32 + * negotiator/default.c: 2--5
33 * walker.c: 0-2
34 * upload-pack.c: 4 11----------------19
35 * builtin/blame.c: 12-13