blob: d07d85ce302d39abc8c017c377d4230d729fdeb4 [file] [log] [blame]
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001#include "cache.h"
Michael Haggerty697cc8e2014-10-01 12:28:42 +02002#include "lockfile.h"
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07003#include "refs.h"
4#include "pkt-line.h"
5#include "commit.h"
6#include "tag.h"
7#include "exec_cmd.h"
8#include "pack.h"
9#include "sideband.h"
10#include "fetch-pack.h"
11#include "remote.h"
12#include "run-command.h"
Junio C Hamano47a59182013-07-08 13:56:53 -070013#include "connect.h"
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +070014#include "transport.h"
15#include "version.h"
Jeff King099327b2013-07-02 02:24:21 -040016#include "prio-queue.h"
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +070017#include "sha1-array.h"
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +070018
19static int transfer_unpack_limit = -1;
20static int fetch_unpack_limit = -1;
21static int unpack_limit = 100;
22static int prefer_ofs_delta = 1;
23static int no_done;
Nguyễn Thái Ngọc Duy508ea882016-06-12 17:53:59 +070024static int deepen_since_ok;
Nguyễn Thái Ngọc Duya45a2602016-06-12 17:54:04 +070025static int deepen_not_ok;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +070026static int fetch_fsck_objects = -1;
27static int transfer_fsck_objects = -1;
28static int agent_supported;
Nguyễn Thái Ngọc Duy6035d6a2013-05-26 08:16:15 +070029static struct lock_file shallow_lock;
30static const char *alternate_shallow_file;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +070031
Nguyễn Thái Ngọc Duy208acbf2014-03-25 20:23:26 +070032/* Remember to update object flag allocation in object.h */
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +070033#define COMPLETE (1U << 0)
34#define COMMON (1U << 1)
35#define COMMON_REF (1U << 2)
36#define SEEN (1U << 3)
37#define POPPED (1U << 4)
Jeff King41a078c2017-02-08 15:53:03 -050038#define ALTERNATE (1U << 5)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +070039
40static int marked;
41
42/*
43 * After sending this many "have"s if we do not get any new ACK , we
44 * give up traversing our history.
45 */
46#define MAX_IN_VAIN 256
47
Jeff King099327b2013-07-02 02:24:21 -040048static struct prio_queue rev_list = { compare_commits_by_commit_date };
Fredrik Medley7199c092015-05-21 22:23:38 +020049static int non_common_revs, multi_ack, use_sideband;
50/* Allow specifying sha1 if it is a ref tip. */
51#define ALLOW_TIP_SHA1 01
Fredrik Medley68ee6282015-05-21 22:23:39 +020052/* Allow request of a sha1 if it is reachable from a ref (possibly hidden ref). */
53#define ALLOW_REACHABLE_SHA1 02
Fredrik Medley7199c092015-05-21 22:23:38 +020054static unsigned int allow_unadvertised_object_request;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +070055
Nguyễn Thái Ngọc Duy0d789a52016-06-12 17:53:54 +070056__attribute__((format (printf, 2, 3)))
57static inline void print_verbose(const struct fetch_pack_args *args,
58 const char *fmt, ...)
59{
60 va_list params;
61
62 if (!args->verbose)
63 return;
64
65 va_start(params, fmt);
66 vfprintf(stderr, fmt, params);
67 va_end(params);
68 fputc('\n', stderr);
69}
70
Jeff King41a078c2017-02-08 15:53:03 -050071struct alternate_object_cache {
72 struct object **items;
73 size_t nr, alloc;
74};
75
76static void cache_one_alternate(const char *refname,
77 const struct object_id *oid,
78 void *vcache)
79{
80 struct alternate_object_cache *cache = vcache;
81 struct object *obj = parse_object(oid->hash);
82
83 if (!obj || (obj->flags & ALTERNATE))
84 return;
85
86 obj->flags |= ALTERNATE;
87 ALLOC_GROW(cache->items, cache->nr + 1, cache->alloc);
88 cache->items[cache->nr++] = obj;
89}
90
91static void for_each_cached_alternate(void (*cb)(struct object *))
92{
93 static int initialized;
94 static struct alternate_object_cache cache;
95 size_t i;
96
97 if (!initialized) {
98 for_each_alternate_ref(cache_one_alternate, &cache);
99 initialized = 1;
100 }
101
102 for (i = 0; i < cache.nr; i++)
103 cb(cache.items[i]);
104}
105
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700106static void rev_list_push(struct commit *commit, int mark)
107{
108 if (!(commit->object.flags & mark)) {
109 commit->object.flags |= mark;
110
Jeff King00640532013-10-24 04:53:01 -0400111 if (parse_commit(commit))
112 return;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700113
Jeff King099327b2013-07-02 02:24:21 -0400114 prio_queue_put(&rev_list, commit);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700115
116 if (!(commit->object.flags & COMMON))
117 non_common_revs++;
118 }
119}
120
Michael Haggertyc38cd1c2015-05-25 18:39:19 +0000121static int rev_list_insert_ref(const char *refname, const unsigned char *sha1)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700122{
123 struct object *o = deref_tag(parse_object(sha1), refname, 0);
124
125 if (o && o->type == OBJ_COMMIT)
126 rev_list_push((struct commit *)o, SEEN);
127
128 return 0;
129}
130
Michael Haggertyb1b49c62015-05-25 18:39:18 +0000131static int rev_list_insert_ref_oid(const char *refname, const struct object_id *oid,
132 int flag, void *cb_data)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700133{
Michael Haggertyc38cd1c2015-05-25 18:39:19 +0000134 return rev_list_insert_ref(refname, oid->hash);
Michael Haggertyb1b49c62015-05-25 18:39:18 +0000135}
136
Michael Haggertyc50fb6c2015-05-25 18:39:15 +0000137static int clear_marks(const char *refname, const struct object_id *oid,
138 int flag, void *cb_data)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700139{
Michael Haggertyc50fb6c2015-05-25 18:39:15 +0000140 struct object *o = deref_tag(parse_object(oid->hash), refname, 0);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700141
142 if (o && o->type == OBJ_COMMIT)
143 clear_commit_marks((struct commit *)o,
144 COMMON | COMMON_REF | SEEN | POPPED);
145 return 0;
146}
147
148/*
149 This function marks a rev and its ancestors as common.
150 In some cases, it is desirable to mark only the ancestors (for example
151 when only the server does not yet know that they are common).
152*/
153
154static void mark_common(struct commit *commit,
155 int ancestors_only, int dont_parse)
156{
157 if (commit != NULL && !(commit->object.flags & COMMON)) {
158 struct object *o = (struct object *)commit;
159
160 if (!ancestors_only)
161 o->flags |= COMMON;
162
163 if (!(o->flags & SEEN))
164 rev_list_push(commit, SEEN);
165 else {
166 struct commit_list *parents;
167
168 if (!ancestors_only && !(o->flags & POPPED))
169 non_common_revs--;
170 if (!o->parsed && !dont_parse)
171 if (parse_commit(commit))
172 return;
173
174 for (parents = commit->parents;
175 parents;
176 parents = parents->next)
177 mark_common(parents->item, 0, dont_parse);
178 }
179 }
180}
181
182/*
183 Get the next rev to send, ignoring the common.
184*/
185
186static const unsigned char *get_rev(void)
187{
188 struct commit *commit = NULL;
189
190 while (commit == NULL) {
191 unsigned int mark;
192 struct commit_list *parents;
193
Jeff King099327b2013-07-02 02:24:21 -0400194 if (rev_list.nr == 0 || non_common_revs == 0)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700195 return NULL;
196
Jeff King099327b2013-07-02 02:24:21 -0400197 commit = prio_queue_get(&rev_list);
Jeff King00640532013-10-24 04:53:01 -0400198 parse_commit(commit);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700199 parents = commit->parents;
200
201 commit->object.flags |= POPPED;
202 if (!(commit->object.flags & COMMON))
203 non_common_revs--;
204
205 if (commit->object.flags & COMMON) {
206 /* do not send "have", and ignore ancestors */
207 commit = NULL;
208 mark = COMMON | SEEN;
209 } else if (commit->object.flags & COMMON_REF)
210 /* send "have", and ignore ancestors */
211 mark = COMMON | SEEN;
212 else
213 /* send "have", also for its ancestors */
214 mark = SEEN;
215
216 while (parents) {
217 if (!(parents->item->object.flags & SEEN))
218 rev_list_push(parents->item, mark);
219 if (mark & COMMON)
220 mark_common(parents->item, 1, 0);
221 parents = parents->next;
222 }
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700223 }
224
brian m. carlsoned1c9972015-11-10 02:22:29 +0000225 return commit->object.oid.hash;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700226}
227
228enum ack_type {
229 NAK = 0,
230 ACK,
231 ACK_continue,
232 ACK_common,
233 ACK_ready
234};
235
236static void consume_shallow_list(struct fetch_pack_args *args, int fd)
237{
Nguyễn Thái Ngọc Duy79891cb2016-06-12 17:53:56 +0700238 if (args->stateless_rpc && args->deepen) {
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700239 /* If we sent a depth we will get back "duplicate"
240 * shallow and unshallow commands every time there
241 * is a block of have lines exchanged.
242 */
Jeff King74543a02013-02-20 15:02:57 -0500243 char *line;
244 while ((line = packet_read_line(fd, NULL))) {
Christian Couder59556542013-11-30 21:55:40 +0100245 if (starts_with(line, "shallow "))
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700246 continue;
Christian Couder59556542013-11-30 21:55:40 +0100247 if (starts_with(line, "unshallow "))
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700248 continue;
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700249 die(_("git fetch-pack: expected shallow list"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700250 }
251 }
252}
253
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700254static enum ack_type get_ack(int fd, unsigned char *result_sha1)
255{
Jeff King74543a02013-02-20 15:02:57 -0500256 int len;
257 char *line = packet_read_line(fd, &len);
Jeff King82e56762014-06-18 15:56:03 -0400258 const char *arg;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700259
260 if (!len)
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700261 die(_("git fetch-pack: expected ACK/NAK, got EOF"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700262 if (!strcmp(line, "NAK"))
263 return NAK;
Jeff King82e56762014-06-18 15:56:03 -0400264 if (skip_prefix(line, "ACK ", &arg)) {
265 if (!get_sha1_hex(arg, result_sha1)) {
266 arg += 40;
267 len -= arg - line;
268 if (len < 1)
Jeff King030e9dd2013-02-20 15:00:28 -0500269 return ACK;
Jeff King82e56762014-06-18 15:56:03 -0400270 if (strstr(arg, "continue"))
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700271 return ACK_continue;
Jeff King82e56762014-06-18 15:56:03 -0400272 if (strstr(arg, "common"))
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700273 return ACK_common;
Jeff King82e56762014-06-18 15:56:03 -0400274 if (strstr(arg, "ready"))
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700275 return ACK_ready;
276 return ACK;
277 }
278 }
Ralf Thielowdfbfb9f2016-11-11 18:21:00 +0100279 die(_("git fetch-pack: expected ACK/NAK, got '%s'"), line);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700280}
281
282static void send_request(struct fetch_pack_args *args,
283 int fd, struct strbuf *buf)
284{
285 if (args->stateless_rpc) {
286 send_sideband(fd, -1, buf->buf, buf->len, LARGE_PACKET_MAX);
287 packet_flush(fd);
288 } else
Jeff Kingcdf4fb82013-02-20 15:01:56 -0500289 write_or_die(fd, buf->buf, buf->len);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700290}
291
Jeff King41a078c2017-02-08 15:53:03 -0500292static void insert_one_alternate_object(struct object *obj)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700293{
Jeff King41a078c2017-02-08 15:53:03 -0500294 rev_list_insert_ref(NULL, obj->oid.hash);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700295}
296
297#define INITIAL_FLUSH 16
298#define PIPESAFE_FLUSH 32
Jonathan Tanda470982016-07-18 15:21:38 -0700299#define LARGE_FLUSH 16384
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700300
301static int next_flush(struct fetch_pack_args *args, int count)
302{
Jonathan Tanda470982016-07-18 15:21:38 -0700303 if (args->stateless_rpc) {
304 if (count < LARGE_FLUSH)
305 count <<= 1;
306 else
307 count = count * 11 / 10;
308 } else {
309 if (count < PIPESAFE_FLUSH)
310 count <<= 1;
311 else
312 count += PIPESAFE_FLUSH;
313 }
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700314 return count;
315}
316
317static int find_common(struct fetch_pack_args *args,
318 int fd[2], unsigned char *result_sha1,
319 struct ref *refs)
320{
321 int fetching;
322 int count = 0, flushes = 0, flush_at = INITIAL_FLUSH, retval;
323 const unsigned char *sha1;
324 unsigned in_vain = 0;
325 int got_continue = 0;
326 int got_ready = 0;
327 struct strbuf req_buf = STRBUF_INIT;
328 size_t state_len = 0;
329
330 if (args->stateless_rpc && multi_ack == 1)
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700331 die(_("--stateless-rpc requires multi_ack_detailed"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700332 if (marked)
333 for_each_ref(clear_marks, NULL);
334 marked = 1;
335
Michael Haggertyb1b49c62015-05-25 18:39:18 +0000336 for_each_ref(rev_list_insert_ref_oid, NULL);
Jeff King41a078c2017-02-08 15:53:03 -0500337 for_each_cached_alternate(insert_one_alternate_object);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700338
339 fetching = 0;
340 for ( ; refs ; refs = refs->next) {
brian m. carlsonf4e54d02015-11-10 02:22:20 +0000341 unsigned char *remote = refs->old_oid.hash;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700342 const char *remote_hex;
343 struct object *o;
344
345 /*
346 * If that object is complete (i.e. it is an ancestor of a
347 * local ref), we tell them we have it but do not have to
348 * tell them about its ancestors, which they already know
349 * about.
350 *
351 * We use lookup_object here because we are only
352 * interested in the case we *know* the object is
353 * reachable and we have already scanned it.
354 */
355 if (((o = lookup_object(remote)) != NULL) &&
356 (o->flags & COMPLETE)) {
357 continue;
358 }
359
360 remote_hex = sha1_to_hex(remote);
361 if (!fetching) {
362 struct strbuf c = STRBUF_INIT;
363 if (multi_ack == 2) strbuf_addstr(&c, " multi_ack_detailed");
364 if (multi_ack == 1) strbuf_addstr(&c, " multi_ack");
365 if (no_done) strbuf_addstr(&c, " no-done");
366 if (use_sideband == 2) strbuf_addstr(&c, " side-band-64k");
367 if (use_sideband == 1) strbuf_addstr(&c, " side-band");
Nguyễn Thái Ngọc Duycccf74e2016-06-12 17:54:09 +0700368 if (args->deepen_relative) strbuf_addstr(&c, " deepen-relative");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700369 if (args->use_thin_pack) strbuf_addstr(&c, " thin-pack");
370 if (args->no_progress) strbuf_addstr(&c, " no-progress");
371 if (args->include_tag) strbuf_addstr(&c, " include-tag");
372 if (prefer_ofs_delta) strbuf_addstr(&c, " ofs-delta");
Nguyễn Thái Ngọc Duy508ea882016-06-12 17:53:59 +0700373 if (deepen_since_ok) strbuf_addstr(&c, " deepen-since");
Nguyễn Thái Ngọc Duya45a2602016-06-12 17:54:04 +0700374 if (deepen_not_ok) strbuf_addstr(&c, " deepen-not");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700375 if (agent_supported) strbuf_addf(&c, " agent=%s",
376 git_user_agent_sanitized());
377 packet_buf_write(&req_buf, "want %s%s\n", remote_hex, c.buf);
378 strbuf_release(&c);
379 } else
380 packet_buf_write(&req_buf, "want %s\n", remote_hex);
381 fetching++;
382 }
383
384 if (!fetching) {
385 strbuf_release(&req_buf);
386 packet_flush(fd[1]);
387 return 1;
388 }
389
390 if (is_repository_shallow())
Nguyễn Thái Ngọc Duy1a30f5a2013-12-05 20:02:34 +0700391 write_shallow_commits(&req_buf, 1, NULL);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700392 if (args->depth > 0)
393 packet_buf_write(&req_buf, "deepen %d", args->depth);
Nguyễn Thái Ngọc Duy508ea882016-06-12 17:53:59 +0700394 if (args->deepen_since) {
395 unsigned long max_age = approxidate(args->deepen_since);
396 packet_buf_write(&req_buf, "deepen-since %lu", max_age);
397 }
Nguyễn Thái Ngọc Duya45a2602016-06-12 17:54:04 +0700398 if (args->deepen_not) {
399 int i;
400 for (i = 0; i < args->deepen_not->nr; i++) {
401 struct string_list_item *s = args->deepen_not->items + i;
402 packet_buf_write(&req_buf, "deepen-not %s", s->string);
403 }
404 }
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700405 packet_buf_flush(&req_buf);
406 state_len = req_buf.len;
407
Nguyễn Thái Ngọc Duy79891cb2016-06-12 17:53:56 +0700408 if (args->deepen) {
Jeff King74543a02013-02-20 15:02:57 -0500409 char *line;
Jeff Kingae021d82014-06-18 15:47:50 -0400410 const char *arg;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700411 unsigned char sha1[20];
412
413 send_request(args, fd[1], &req_buf);
Jeff King74543a02013-02-20 15:02:57 -0500414 while ((line = packet_read_line(fd[0], NULL))) {
Jeff Kingae021d82014-06-18 15:47:50 -0400415 if (skip_prefix(line, "shallow ", &arg)) {
416 if (get_sha1_hex(arg, sha1))
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700417 die(_("invalid shallow line: %s"), line);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700418 register_shallow(sha1);
419 continue;
420 }
Jeff Kingae021d82014-06-18 15:47:50 -0400421 if (skip_prefix(line, "unshallow ", &arg)) {
422 if (get_sha1_hex(arg, sha1))
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700423 die(_("invalid unshallow line: %s"), line);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700424 if (!lookup_object(sha1))
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700425 die(_("object not found: %s"), line);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700426 /* make sure that it is parsed as shallow */
427 if (!parse_object(sha1))
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700428 die(_("error in object: %s"), line);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700429 if (unregister_shallow(sha1))
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700430 die(_("no shallow found: %s"), line);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700431 continue;
432 }
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700433 die(_("expected shallow/unshallow, got %s"), line);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700434 }
435 } else if (!args->stateless_rpc)
436 send_request(args, fd[1], &req_buf);
437
438 if (!args->stateless_rpc) {
439 /* If we aren't using the stateless-rpc interface
440 * we don't need to retain the headers.
441 */
442 strbuf_setlen(&req_buf, 0);
443 state_len = 0;
444 }
445
446 flushes = 0;
447 retval = -1;
448 while ((sha1 = get_rev())) {
449 packet_buf_write(&req_buf, "have %s\n", sha1_to_hex(sha1));
Nguyễn Thái Ngọc Duy0d789a52016-06-12 17:53:54 +0700450 print_verbose(args, "have %s", sha1_to_hex(sha1));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700451 in_vain++;
452 if (flush_at <= ++count) {
453 int ack;
454
455 packet_buf_flush(&req_buf);
456 send_request(args, fd[1], &req_buf);
457 strbuf_setlen(&req_buf, state_len);
458 flushes++;
459 flush_at = next_flush(args, count);
460
461 /*
462 * We keep one window "ahead" of the other side, and
463 * will wait for an ACK only on the next one
464 */
465 if (!args->stateless_rpc && count == INITIAL_FLUSH)
466 continue;
467
468 consume_shallow_list(args, fd[0]);
469 do {
470 ack = get_ack(fd[0], result_sha1);
Nguyễn Thái Ngọc Duy0d789a52016-06-12 17:53:54 +0700471 if (ack)
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700472 print_verbose(args, _("got %s %d %s"), "ack",
473 ack, sha1_to_hex(result_sha1));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700474 switch (ack) {
475 case ACK:
476 flushes = 0;
477 multi_ack = 0;
478 retval = 0;
479 goto done;
480 case ACK_common:
481 case ACK_ready:
482 case ACK_continue: {
483 struct commit *commit =
484 lookup_commit(result_sha1);
485 if (!commit)
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700486 die(_("invalid commit %s"), sha1_to_hex(result_sha1));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700487 if (args->stateless_rpc
488 && ack == ACK_common
489 && !(commit->object.flags & COMMON)) {
490 /* We need to replay the have for this object
491 * on the next RPC request so the peer knows
492 * it is in common with us.
493 */
494 const char *hex = sha1_to_hex(result_sha1);
495 packet_buf_write(&req_buf, "have %s\n", hex);
496 state_len = req_buf.len;
Jonathan Tan06b3d382016-09-23 10:41:35 -0700497 /*
498 * Reset in_vain because an ack
499 * for this commit has not been
500 * seen.
501 */
502 in_vain = 0;
503 } else if (!args->stateless_rpc
504 || ack != ACK_common)
505 in_vain = 0;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700506 mark_common(commit, 0, 1);
507 retval = 0;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700508 got_continue = 1;
509 if (ack == ACK_ready) {
Jeff King099327b2013-07-02 02:24:21 -0400510 clear_prio_queue(&rev_list);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700511 got_ready = 1;
512 }
513 break;
514 }
515 }
516 } while (ack);
517 flushes--;
518 if (got_continue && MAX_IN_VAIN < in_vain) {
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700519 print_verbose(args, _("giving up"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700520 break; /* give up */
521 }
522 }
523 }
524done:
525 if (!got_ready || !no_done) {
526 packet_buf_write(&req_buf, "done\n");
527 send_request(args, fd[1], &req_buf);
528 }
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700529 print_verbose(args, _("done"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700530 if (retval != 0) {
531 multi_ack = 0;
532 flushes++;
533 }
534 strbuf_release(&req_buf);
535
Nguyễn Thái Ngọc Duyff62eca2014-02-06 22:10:39 +0700536 if (!got_ready || !no_done)
537 consume_shallow_list(args, fd[0]);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700538 while (flushes || multi_ack) {
539 int ack = get_ack(fd[0], result_sha1);
540 if (ack) {
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700541 print_verbose(args, _("got %s (%d) %s"), "ack",
542 ack, sha1_to_hex(result_sha1));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700543 if (ack == ACK)
544 return 0;
545 multi_ack = 1;
546 continue;
547 }
548 flushes--;
549 }
550 /* it is no error to fetch into a completely empty repo */
551 return count ? retval : 0;
552}
553
554static struct commit_list *complete;
555
Michael Haggerty6e20a512015-05-25 18:39:17 +0000556static int mark_complete(const unsigned char *sha1)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700557{
558 struct object *o = parse_object(sha1);
559
560 while (o && o->type == OBJ_TAG) {
561 struct tag *t = (struct tag *) o;
562 if (!t->tagged)
563 break; /* broken repository */
564 o->flags |= COMPLETE;
brian m. carlsoned1c9972015-11-10 02:22:29 +0000565 o = parse_object(t->tagged->oid.hash);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700566 }
567 if (o && o->type == OBJ_COMMIT) {
568 struct commit *commit = (struct commit *)o;
569 if (!(commit->object.flags & COMPLETE)) {
570 commit->object.flags |= COMPLETE;
Jeff King16445242013-07-02 02:16:23 -0400571 commit_list_insert(commit, &complete);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700572 }
573 }
574 return 0;
575}
576
Michael Haggertyf8ee4d82015-05-25 18:39:16 +0000577static int mark_complete_oid(const char *refname, const struct object_id *oid,
578 int flag, void *cb_data)
579{
Michael Haggerty6e20a512015-05-25 18:39:17 +0000580 return mark_complete(oid->hash);
Michael Haggertyf8ee4d82015-05-25 18:39:16 +0000581}
582
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700583static void mark_recent_complete_commits(struct fetch_pack_args *args,
584 unsigned long cutoff)
585{
586 while (complete && cutoff <= complete->item->date) {
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700587 print_verbose(args, _("Marking %s as complete"),
Nguyễn Thái Ngọc Duy0d789a52016-06-12 17:53:54 +0700588 oid_to_hex(&complete->item->object.oid));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700589 pop_most_recent_commit(&complete, COMPLETE);
590 }
591}
592
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700593static void filter_refs(struct fetch_pack_args *args,
Junio C Hamanof2db8542013-01-29 14:02:15 -0800594 struct ref **refs,
595 struct ref **sought, int nr_sought)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700596{
597 struct ref *newlist = NULL;
598 struct ref **newtail = &newlist;
599 struct ref *ref, *next;
Junio C Hamanof2db8542013-01-29 14:02:15 -0800600 int i;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700601
Junio C Hamanof2db8542013-01-29 14:02:15 -0800602 i = 0;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700603 for (ref = *refs; ref; ref = next) {
604 int keep = 0;
605 next = ref->next;
Junio C Hamanof2db8542013-01-29 14:02:15 -0800606
René Scharfe50e19a82014-06-06 19:24:48 +0200607 if (starts_with(ref->name, "refs/") &&
Jeff King4c224082014-01-15 05:46:13 -0500608 check_refname_format(ref->name, 0))
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700609 ; /* trash */
610 else {
Junio C Hamanof2db8542013-01-29 14:02:15 -0800611 while (i < nr_sought) {
612 int cmp = strcmp(ref->name, sought[i]->name);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700613 if (cmp < 0)
614 break; /* definitely do not have it */
615 else if (cmp == 0) {
616 keep = 1; /* definitely have it */
Matt McCutchend56583d2017-02-22 11:05:57 -0500617 sought[i]->match_status = REF_MATCHED;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700618 }
Junio C Hamanof2db8542013-01-29 14:02:15 -0800619 i++;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700620 }
621 }
622
Junio C Hamanof2db8542013-01-29 14:02:15 -0800623 if (!keep && args->fetch_all &&
Nguyễn Thái Ngọc Duy79891cb2016-06-12 17:53:56 +0700624 (!args->deepen || !starts_with(ref->name, "refs/tags/")))
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700625 keep = 1;
626
627 if (keep) {
628 *newtail = ref;
629 ref->next = NULL;
630 newtail = &ref->next;
631 } else {
632 free(ref);
633 }
634 }
635
Junio C Hamano6e7b66e2013-01-29 14:02:15 -0800636 /* Append unmatched requests to the list */
Matt McCutchend56583d2017-02-22 11:05:57 -0500637 for (i = 0; i < nr_sought; i++) {
638 unsigned char sha1[20];
Jeff Kingb7916422015-03-19 16:34:51 -0400639
Matt McCutchend56583d2017-02-22 11:05:57 -0500640 ref = sought[i];
641 if (ref->match_status != REF_NOT_MATCHED)
642 continue;
643 if (get_sha1_hex(ref->name, sha1) ||
644 ref->name[40] != '\0' ||
645 hashcmp(sha1, ref->old_oid.hash))
646 continue;
Junio C Hamano6e7b66e2013-01-29 14:02:15 -0800647
Matt McCutchend56583d2017-02-22 11:05:57 -0500648 if ((allow_unadvertised_object_request &
649 (ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1))) {
650 ref->match_status = REF_MATCHED;
Jeff Kingc3c17bf2015-03-19 16:37:09 -0400651 *newtail = copy_ref(ref);
652 newtail = &(*newtail)->next;
Matt McCutchend56583d2017-02-22 11:05:57 -0500653 } else {
654 ref->match_status = REF_UNADVERTISED_NOT_ALLOWED;
Junio C Hamano6e7b66e2013-01-29 14:02:15 -0800655 }
656 }
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700657 *refs = newlist;
658}
659
Jeff King41a078c2017-02-08 15:53:03 -0500660static void mark_alternate_complete(struct object *obj)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700661{
Jeff King41a078c2017-02-08 15:53:03 -0500662 mark_complete(obj->oid.hash);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700663}
664
665static int everything_local(struct fetch_pack_args *args,
Junio C Hamanof2db8542013-01-29 14:02:15 -0800666 struct ref **refs,
667 struct ref **sought, int nr_sought)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700668{
669 struct ref *ref;
670 int retval;
671 unsigned long cutoff = 0;
672
673 save_commit_buffer = 0;
674
675 for (ref = *refs; ref; ref = ref->next) {
676 struct object *o;
677
brian m. carlsonf4e54d02015-11-10 02:22:20 +0000678 if (!has_object_file(&ref->old_oid))
Junio C Hamano012a1bb2013-01-26 19:42:09 -0800679 continue;
680
brian m. carlsonf4e54d02015-11-10 02:22:20 +0000681 o = parse_object(ref->old_oid.hash);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700682 if (!o)
683 continue;
684
685 /* We already have it -- which may mean that we were
686 * in sync with the other side at some time after
687 * that (it is OK if we guess wrong here).
688 */
689 if (o->type == OBJ_COMMIT) {
690 struct commit *commit = (struct commit *)o;
691 if (!cutoff || cutoff < commit->date)
692 cutoff = commit->date;
693 }
694 }
695
Nguyễn Thái Ngọc Duy79891cb2016-06-12 17:53:56 +0700696 if (!args->deepen) {
Michael Haggertyf8ee4d82015-05-25 18:39:16 +0000697 for_each_ref(mark_complete_oid, NULL);
Jeff King41a078c2017-02-08 15:53:03 -0500698 for_each_cached_alternate(mark_alternate_complete);
Jeff King16445242013-07-02 02:16:23 -0400699 commit_list_sort_by_date(&complete);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700700 if (cutoff)
701 mark_recent_complete_commits(args, cutoff);
702 }
703
704 /*
705 * Mark all complete remote refs as common refs.
706 * Don't mark them common yet; the server has to be told so first.
707 */
708 for (ref = *refs; ref; ref = ref->next) {
brian m. carlsonf4e54d02015-11-10 02:22:20 +0000709 struct object *o = deref_tag(lookup_object(ref->old_oid.hash),
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700710 NULL, 0);
711
712 if (!o || o->type != OBJ_COMMIT || !(o->flags & COMPLETE))
713 continue;
714
715 if (!(o->flags & SEEN)) {
716 rev_list_push((struct commit *)o, COMMON_REF | SEEN);
717
718 mark_common((struct commit *)o, 1, 1);
719 }
720 }
721
Junio C Hamanof2db8542013-01-29 14:02:15 -0800722 filter_refs(args, refs, sought, nr_sought);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700723
724 for (retval = 1, ref = *refs; ref ; ref = ref->next) {
brian m. carlsonf4e54d02015-11-10 02:22:20 +0000725 const unsigned char *remote = ref->old_oid.hash;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700726 struct object *o;
727
728 o = lookup_object(remote);
729 if (!o || !(o->flags & COMPLETE)) {
730 retval = 0;
Nguyễn Thái Ngọc Duy0d789a52016-06-12 17:53:54 +0700731 print_verbose(args, "want %s (%s)", sha1_to_hex(remote),
732 ref->name);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700733 continue;
734 }
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700735 print_verbose(args, _("already have %s (%s)"), sha1_to_hex(remote),
Nguyễn Thái Ngọc Duy0d789a52016-06-12 17:53:54 +0700736 ref->name);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700737 }
738 return retval;
739}
740
741static int sideband_demux(int in, int out, void *data)
742{
743 int *xd = data;
Jeff King9ff18fa2016-02-24 02:44:58 -0500744 int ret;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700745
Jeff King9ff18fa2016-02-24 02:44:58 -0500746 ret = recv_sideband("fetch-pack", xd[0], out);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700747 close(out);
748 return ret;
749}
750
751static int get_pack(struct fetch_pack_args *args,
752 int xd[2], char **pack_lockfile)
753{
754 struct async demux;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700755 int do_keep = args->keep_pack;
Jeff King984a43b2015-09-24 17:07:54 -0400756 const char *cmd_name;
757 struct pack_header header;
758 int pass_header = 0;
René Scharfed3180272014-08-19 21:09:35 +0200759 struct child_process cmd = CHILD_PROCESS_INIT;
Nguyễn Thái Ngọc Duyc6807a42013-05-26 08:16:17 +0700760 int ret;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700761
762 memset(&demux, 0, sizeof(demux));
763 if (use_sideband) {
764 /* xd[] is talking with upload-pack; subprocess reads from
765 * xd[0], spits out band#2 to stderr, and feeds us band#1
766 * through demux->out.
767 */
768 demux.proc = sideband_demux;
769 demux.data = xd;
770 demux.out = -1;
Jeff Kingdf857572016-04-19 18:50:29 -0400771 demux.isolate_sigpipe = 1;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700772 if (start_async(&demux))
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700773 die(_("fetch-pack: unable to fork off sideband demultiplexer"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700774 }
775 else
776 demux.out = xd[0];
777
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700778 if (!args->keep_pack && unpack_limit) {
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700779
780 if (read_pack_header(demux.out, &header))
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700781 die(_("protocol error: bad pack header"));
Jeff King984a43b2015-09-24 17:07:54 -0400782 pass_header = 1;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700783 if (ntohl(header.hdr_entries) < unpack_limit)
784 do_keep = 0;
785 else
786 do_keep = 1;
787 }
788
Nguyễn Thái Ngọc Duy6035d6a2013-05-26 08:16:15 +0700789 if (alternate_shallow_file) {
Jeff King984a43b2015-09-24 17:07:54 -0400790 argv_array_push(&cmd.args, "--shallow-file");
791 argv_array_push(&cmd.args, alternate_shallow_file);
Nguyễn Thái Ngọc Duy6035d6a2013-05-26 08:16:15 +0700792 }
793
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700794 if (do_keep) {
795 if (pack_lockfile)
796 cmd.out = -1;
Jeff King984a43b2015-09-24 17:07:54 -0400797 cmd_name = "index-pack";
798 argv_array_push(&cmd.args, cmd_name);
799 argv_array_push(&cmd.args, "--stdin");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700800 if (!args->quiet && !args->no_progress)
Jeff King984a43b2015-09-24 17:07:54 -0400801 argv_array_push(&cmd.args, "-v");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700802 if (args->use_thin_pack)
Jeff King984a43b2015-09-24 17:07:54 -0400803 argv_array_push(&cmd.args, "--fix-thin");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700804 if (args->lock_pack || unpack_limit) {
Jeff King984a43b2015-09-24 17:07:54 -0400805 char hostname[256];
806 if (gethostname(hostname, sizeof(hostname)))
807 xsnprintf(hostname, sizeof(hostname), "localhost");
808 argv_array_pushf(&cmd.args,
809 "--keep=fetch-pack %"PRIuMAX " on %s",
810 (uintmax_t)getpid(), hostname);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700811 }
Nguyễn Thái Ngọc Duyc6807a42013-05-26 08:16:17 +0700812 if (args->check_self_contained_and_connected)
Jeff King984a43b2015-09-24 17:07:54 -0400813 argv_array_push(&cmd.args, "--check-self-contained-and-connected");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700814 }
815 else {
Jeff King984a43b2015-09-24 17:07:54 -0400816 cmd_name = "unpack-objects";
817 argv_array_push(&cmd.args, cmd_name);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700818 if (args->quiet || args->no_progress)
Jeff King984a43b2015-09-24 17:07:54 -0400819 argv_array_push(&cmd.args, "-q");
Nguyễn Thái Ngọc Duyc6807a42013-05-26 08:16:17 +0700820 args->check_self_contained_and_connected = 0;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700821 }
Jeff King984a43b2015-09-24 17:07:54 -0400822
823 if (pass_header)
824 argv_array_pushf(&cmd.args, "--pack_header=%"PRIu32",%"PRIu32,
825 ntohl(header.hdr_version),
826 ntohl(header.hdr_entries));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700827 if (fetch_fsck_objects >= 0
828 ? fetch_fsck_objects
829 : transfer_fsck_objects >= 0
830 ? transfer_fsck_objects
831 : 0)
Jeff King984a43b2015-09-24 17:07:54 -0400832 argv_array_push(&cmd.args, "--strict");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700833
834 cmd.in = demux.out;
835 cmd.git_cmd = 1;
836 if (start_command(&cmd))
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700837 die(_("fetch-pack: unable to fork off %s"), cmd_name);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700838 if (do_keep && pack_lockfile) {
839 *pack_lockfile = index_pack_lockfile(cmd.out);
840 close(cmd.out);
841 }
842
Jens Lindstrom37cb1dd2013-10-22 15:36:02 +0200843 if (!use_sideband)
844 /* Closed by start_command() */
845 xd[0] = -1;
846
Nguyễn Thái Ngọc Duyc6807a42013-05-26 08:16:17 +0700847 ret = finish_command(&cmd);
848 if (!ret || (args->check_self_contained_and_connected && ret == 1))
849 args->self_contained_and_connected =
850 args->check_self_contained_and_connected &&
851 ret == 0;
852 else
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700853 die(_("%s failed"), cmd_name);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700854 if (use_sideband && finish_async(&demux))
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700855 die(_("error in sideband demultiplexer"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700856 return 0;
857}
858
Junio C Hamanof2db8542013-01-29 14:02:15 -0800859static int cmp_ref_by_name(const void *a_, const void *b_)
860{
861 const struct ref *a = *((const struct ref **)a_);
862 const struct ref *b = *((const struct ref **)b_);
863 return strcmp(a->name, b->name);
864}
865
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700866static struct ref *do_fetch_pack(struct fetch_pack_args *args,
867 int fd[2],
868 const struct ref *orig_ref,
Junio C Hamanof2db8542013-01-29 14:02:15 -0800869 struct ref **sought, int nr_sought,
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +0700870 struct shallow_info *si,
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700871 char **pack_lockfile)
872{
873 struct ref *ref = copy_ref_list(orig_ref);
874 unsigned char sha1[20];
875 const char *agent_feature;
876 int agent_len;
877
878 sort_ref_list(&ref, ref_compare_name);
René Scharfe9ed0d8d2016-09-29 17:27:31 +0200879 QSORT(sought, nr_sought, cmp_ref_by_name);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700880
Mike Edgareb86a502015-06-17 07:48:14 -0400881 if ((args->depth > 0 || is_repository_shallow()) && !server_supports("shallow"))
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700882 die(_("Server does not support shallow clients"));
Nguyễn Thái Ngọc Duya45a2602016-06-12 17:54:04 +0700883 if (args->depth > 0 || args->deepen_since || args->deepen_not)
Nguyễn Thái Ngọc Duy79891cb2016-06-12 17:53:56 +0700884 args->deepen = 1;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700885 if (server_supports("multi_ack_detailed")) {
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700886 print_verbose(args, _("Server supports multi_ack_detailed"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700887 multi_ack = 2;
888 if (server_supports("no-done")) {
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700889 print_verbose(args, _("Server supports no-done"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700890 if (args->stateless_rpc)
891 no_done = 1;
892 }
893 }
894 else if (server_supports("multi_ack")) {
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700895 print_verbose(args, _("Server supports multi_ack"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700896 multi_ack = 1;
897 }
898 if (server_supports("side-band-64k")) {
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700899 print_verbose(args, _("Server supports side-band-64k"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700900 use_sideband = 2;
901 }
902 else if (server_supports("side-band")) {
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700903 print_verbose(args, _("Server supports side-band"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700904 use_sideband = 1;
905 }
Junio C Hamano6e7b66e2013-01-29 14:02:15 -0800906 if (server_supports("allow-tip-sha1-in-want")) {
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700907 print_verbose(args, _("Server supports allow-tip-sha1-in-want"));
Fredrik Medley7199c092015-05-21 22:23:38 +0200908 allow_unadvertised_object_request |= ALLOW_TIP_SHA1;
Junio C Hamano6e7b66e2013-01-29 14:02:15 -0800909 }
Fredrik Medley68ee6282015-05-21 22:23:39 +0200910 if (server_supports("allow-reachable-sha1-in-want")) {
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700911 print_verbose(args, _("Server supports allow-reachable-sha1-in-want"));
Fredrik Medley68ee6282015-05-21 22:23:39 +0200912 allow_unadvertised_object_request |= ALLOW_REACHABLE_SHA1;
913 }
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700914 if (!server_supports("thin-pack"))
915 args->use_thin_pack = 0;
916 if (!server_supports("no-progress"))
917 args->no_progress = 0;
918 if (!server_supports("include-tag"))
919 args->include_tag = 0;
Nguyễn Thái Ngọc Duy0d789a52016-06-12 17:53:54 +0700920 if (server_supports("ofs-delta"))
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700921 print_verbose(args, _("Server supports ofs-delta"));
Nguyễn Thái Ngọc Duy0d789a52016-06-12 17:53:54 +0700922 else
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700923 prefer_ofs_delta = 0;
924
925 if ((agent_feature = server_feature_value("agent", &agent_len))) {
926 agent_supported = 1;
Nguyễn Thái Ngọc Duy0d789a52016-06-12 17:53:54 +0700927 if (agent_len)
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700928 print_verbose(args, _("Server version is %.*s"),
Nguyễn Thái Ngọc Duy0d789a52016-06-12 17:53:54 +0700929 agent_len, agent_feature);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700930 }
Nguyễn Thái Ngọc Duy508ea882016-06-12 17:53:59 +0700931 if (server_supports("deepen-since"))
932 deepen_since_ok = 1;
933 else if (args->deepen_since)
934 die(_("Server does not support --shallow-since"));
Nguyễn Thái Ngọc Duya45a2602016-06-12 17:54:04 +0700935 if (server_supports("deepen-not"))
936 deepen_not_ok = 1;
937 else if (args->deepen_not)
938 die(_("Server does not support --shallow-exclude"));
Nguyễn Thái Ngọc Duycccf74e2016-06-12 17:54:09 +0700939 if (!server_supports("deepen-relative") && args->deepen_relative)
940 die(_("Server does not support --deepen"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700941
Junio C Hamanof2db8542013-01-29 14:02:15 -0800942 if (everything_local(args, &ref, sought, nr_sought)) {
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700943 packet_flush(fd[1]);
944 goto all_done;
945 }
946 if (find_common(args, fd, sha1, ref) < 0)
947 if (!args->keep_pack)
948 /* When cloning, it is not unusual to have
949 * no common commit.
950 */
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700951 warning(_("no common commits"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700952
953 if (args->stateless_rpc)
954 packet_flush(fd[1]);
Nguyễn Thái Ngọc Duy79891cb2016-06-12 17:53:56 +0700955 if (args->deepen)
Nguyễn Thái Ngọc Duy1a30f5a2013-12-05 20:02:34 +0700956 setup_alternate_shallow(&shallow_lock, &alternate_shallow_file,
957 NULL);
Nguyễn Thái Ngọc Duy4820a332013-12-05 20:02:40 +0700958 else if (si->nr_ours || si->nr_theirs)
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +0700959 alternate_shallow_file = setup_temporary_shallow(si->shallow);
Nguyễn Thái Ngọc Duy6da8bdc2013-08-26 09:17:26 +0700960 else
961 alternate_shallow_file = NULL;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700962 if (get_pack(args, fd, pack_lockfile))
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700963 die(_("git fetch-pack: fetch failed."));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700964
965 all_done:
966 return ref;
967}
968
Tanay Abhraf44af512014-08-07 09:21:20 -0700969static void fetch_pack_config(void)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700970{
Tanay Abhraf44af512014-08-07 09:21:20 -0700971 git_config_get_int("fetch.unpacklimit", &fetch_unpack_limit);
972 git_config_get_int("transfer.unpacklimit", &transfer_unpack_limit);
973 git_config_get_bool("repack.usedeltabaseoffset", &prefer_ofs_delta);
974 git_config_get_bool("fetch.fsckobjects", &fetch_fsck_objects);
975 git_config_get_bool("transfer.fsckobjects", &transfer_fsck_objects);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700976
Tanay Abhraf44af512014-08-07 09:21:20 -0700977 git_config(git_default_config, NULL);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700978}
979
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700980static void fetch_pack_setup(void)
981{
982 static int did_setup;
983 if (did_setup)
984 return;
Tanay Abhraf44af512014-08-07 09:21:20 -0700985 fetch_pack_config();
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700986 if (0 <= transfer_unpack_limit)
987 unpack_limit = transfer_unpack_limit;
988 else if (0 <= fetch_unpack_limit)
989 unpack_limit = fetch_unpack_limit;
990 did_setup = 1;
991}
992
Junio C Hamanof2db8542013-01-29 14:02:15 -0800993static int remove_duplicates_in_refs(struct ref **ref, int nr)
994{
995 struct string_list names = STRING_LIST_INIT_NODUP;
996 int src, dst;
997
998 for (src = dst = 0; src < nr; src++) {
999 struct string_list_item *item;
1000 item = string_list_insert(&names, ref[src]->name);
1001 if (item->util)
1002 continue; /* already have it */
1003 item->util = ref[src];
1004 if (src != dst)
1005 ref[dst] = ref[src];
1006 dst++;
1007 }
1008 for (src = dst; src < nr; src++)
1009 ref[src] = NULL;
1010 string_list_clear(&names, 0);
1011 return dst;
1012}
1013
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001014static void update_shallow(struct fetch_pack_args *args,
Nguyễn Thái Ngọc Duy4820a332013-12-05 20:02:40 +07001015 struct ref **sought, int nr_sought,
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001016 struct shallow_info *si)
Nguyễn Thái Ngọc Duya796cce2013-12-05 20:02:37 +07001017{
Nguyễn Thái Ngọc Duy4820a332013-12-05 20:02:40 +07001018 struct sha1_array ref = SHA1_ARRAY_INIT;
1019 int *status;
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001020 int i;
1021
Nguyễn Thái Ngọc Duy79891cb2016-06-12 17:53:56 +07001022 if (args->deepen && alternate_shallow_file) {
Nguyễn Thái Ngọc Duya796cce2013-12-05 20:02:37 +07001023 if (*alternate_shallow_file == '\0') { /* --unshallow */
Jeff Kingf9327292015-08-10 05:38:57 -04001024 unlink_or_warn(git_path_shallow());
Nguyễn Thái Ngọc Duya796cce2013-12-05 20:02:37 +07001025 rollback_lock_file(&shallow_lock);
1026 } else
1027 commit_lock_file(&shallow_lock);
1028 return;
1029 }
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001030
1031 if (!si->shallow || !si->shallow->nr)
1032 return;
1033
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001034 if (args->cloning) {
1035 /*
1036 * remote is shallow, but this is a clone, there are
1037 * no objects in repo to worry about. Accept any
1038 * shallow points that exist in the pack (iow in repo
1039 * after get_pack() and reprepare_packed_git())
1040 */
1041 struct sha1_array extra = SHA1_ARRAY_INIT;
1042 unsigned char (*sha1)[20] = si->shallow->sha1;
1043 for (i = 0; i < si->shallow->nr; i++)
1044 if (has_sha1_file(sha1[i]))
1045 sha1_array_append(&extra, sha1[i]);
1046 if (extra.nr) {
1047 setup_alternate_shallow(&shallow_lock,
1048 &alternate_shallow_file,
1049 &extra);
1050 commit_lock_file(&shallow_lock);
1051 }
1052 sha1_array_clear(&extra);
1053 return;
1054 }
Nguyễn Thái Ngọc Duy4820a332013-12-05 20:02:40 +07001055
1056 if (!si->nr_ours && !si->nr_theirs)
1057 return;
1058
1059 remove_nonexistent_theirs_shallow(si);
Nguyễn Thái Ngọc Duy4820a332013-12-05 20:02:40 +07001060 if (!si->nr_ours && !si->nr_theirs)
1061 return;
1062 for (i = 0; i < nr_sought; i++)
brian m. carlsonf4e54d02015-11-10 02:22:20 +00001063 sha1_array_append(&ref, sought[i]->old_oid.hash);
Nguyễn Thái Ngọc Duy4820a332013-12-05 20:02:40 +07001064 si->ref = &ref;
1065
Nguyễn Thái Ngọc Duy48d25ca2013-12-05 20:02:42 +07001066 if (args->update_shallow) {
1067 /*
1068 * remote is also shallow, .git/shallow may be updated
1069 * so all refs can be accepted. Make sure we only add
1070 * shallow roots that are actually reachable from new
1071 * refs.
1072 */
1073 struct sha1_array extra = SHA1_ARRAY_INIT;
1074 unsigned char (*sha1)[20] = si->shallow->sha1;
1075 assign_shallow_commits_to_refs(si, NULL, NULL);
1076 if (!si->nr_ours && !si->nr_theirs) {
1077 sha1_array_clear(&ref);
1078 return;
1079 }
1080 for (i = 0; i < si->nr_ours; i++)
1081 sha1_array_append(&extra, sha1[si->ours[i]]);
1082 for (i = 0; i < si->nr_theirs; i++)
1083 sha1_array_append(&extra, sha1[si->theirs[i]]);
1084 setup_alternate_shallow(&shallow_lock,
1085 &alternate_shallow_file,
1086 &extra);
1087 commit_lock_file(&shallow_lock);
1088 sha1_array_clear(&extra);
1089 sha1_array_clear(&ref);
1090 return;
1091 }
1092
Nguyễn Thái Ngọc Duy4820a332013-12-05 20:02:40 +07001093 /*
1094 * remote is also shallow, check what ref is safe to update
1095 * without updating .git/shallow
1096 */
1097 status = xcalloc(nr_sought, sizeof(*status));
1098 assign_shallow_commits_to_refs(si, NULL, status);
1099 if (si->nr_ours || si->nr_theirs) {
1100 for (i = 0; i < nr_sought; i++)
1101 if (status[i])
1102 sought[i]->status = REF_STATUS_REJECT_SHALLOW;
1103 }
1104 free(status);
1105 sha1_array_clear(&ref);
Nguyễn Thái Ngọc Duya796cce2013-12-05 20:02:37 +07001106}
1107
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001108struct ref *fetch_pack(struct fetch_pack_args *args,
1109 int fd[], struct child_process *conn,
1110 const struct ref *ref,
1111 const char *dest,
Junio C Hamanof2db8542013-01-29 14:02:15 -08001112 struct ref **sought, int nr_sought,
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001113 struct sha1_array *shallow,
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001114 char **pack_lockfile)
1115{
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001116 struct ref *ref_cpy;
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001117 struct shallow_info si;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001118
1119 fetch_pack_setup();
Junio C Hamanof2db8542013-01-29 14:02:15 -08001120 if (nr_sought)
1121 nr_sought = remove_duplicates_in_refs(sought, nr_sought);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001122
1123 if (!ref) {
1124 packet_flush(fd[1]);
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +07001125 die(_("no matching remote head"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001126 }
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001127 prepare_shallow_info(&si, shallow);
1128 ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought,
1129 &si, pack_lockfile);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001130 reprepare_packed_git();
Nguyễn Thái Ngọc Duy4820a332013-12-05 20:02:40 +07001131 update_shallow(args, sought, nr_sought, &si);
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001132 clear_shallow_info(&si);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001133 return ref_cpy;
1134}
Matt McCutchene860d962017-02-22 11:01:22 -05001135
1136int report_unmatched_refs(struct ref **sought, int nr_sought)
1137{
1138 int i, ret = 0;
1139
1140 for (i = 0; i < nr_sought; i++) {
Matt McCutchend56583d2017-02-22 11:05:57 -05001141 if (!sought[i])
Matt McCutchene860d962017-02-22 11:01:22 -05001142 continue;
Matt McCutchend56583d2017-02-22 11:05:57 -05001143 switch (sought[i]->match_status) {
1144 case REF_MATCHED:
1145 continue;
1146 case REF_NOT_MATCHED:
1147 error(_("no such remote ref %s"), sought[i]->name);
1148 break;
1149 case REF_UNADVERTISED_NOT_ALLOWED:
1150 error(_("Server does not allow request for unadvertised object %s"),
1151 sought[i]->name);
1152 break;
1153 }
Matt McCutchene860d962017-02-22 11:01:22 -05001154 ret = 1;
1155 }
1156 return ret;
1157}