blob: 1734a573b010dd2f87541154cc70e5bb71b00463 [file] [log] [blame]
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001#include "cache.h"
Stefan Bellera49d2832018-03-23 18:45:21 +01002#include "repository.h"
Brandon Williamsb2141fc2017-06-14 11:07:36 -07003#include "config.h"
Michael Haggerty697cc8e2014-10-01 12:28:42 +02004#include "lockfile.h"
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07005#include "refs.h"
6#include "pkt-line.h"
7#include "commit.h"
8#include "tag.h"
Stefan Bellerd807c4a2018-04-10 14:26:18 -07009#include "exec-cmd.h"
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +070010#include "pack.h"
11#include "sideband.h"
12#include "fetch-pack.h"
13#include "remote.h"
14#include "run-command.h"
Junio C Hamano47a59182013-07-08 13:56:53 -070015#include "connect.h"
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +070016#include "transport.h"
17#include "version.h"
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +070018#include "sha1-array.h"
Jonathan Tanfdb69d32017-05-15 10:32:20 -070019#include "oidset.h"
Jonathan Tan0abe14f2017-08-18 15:20:26 -070020#include "packfile.h"
Stefan Bellercbd53a22018-05-15 16:42:15 -070021#include "object-store.h"
Jonathan Tancf1e7c02018-07-02 15:08:43 -070022#include "connected.h"
Jonathan Tanec062832018-06-14 15:54:28 -070023#include "fetch-negotiator.h"
Ævar Arnfjörð Bjarmason1362df02018-07-27 14:37:17 +000024#include "fsck.h"
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +070025
26static int transfer_unpack_limit = -1;
27static int fetch_unpack_limit = -1;
28static int unpack_limit = 100;
29static int prefer_ofs_delta = 1;
30static int no_done;
Nguyễn Thái Ngọc Duy508ea882016-06-12 17:53:59 +070031static int deepen_since_ok;
Nguyễn Thái Ngọc Duya45a2602016-06-12 17:54:04 +070032static int deepen_not_ok;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +070033static int fetch_fsck_objects = -1;
34static int transfer_fsck_objects = -1;
35static int agent_supported;
Jeff Hostetler640d8b72017-12-08 15:58:40 +000036static int server_supports_filtering;
Nguyễn Thái Ngọc Duy6035d6a2013-05-26 08:16:15 +070037static struct lock_file shallow_lock;
38static const char *alternate_shallow_file;
Ævar Arnfjörð Bjarmason1362df02018-07-27 14:37:17 +000039static struct strbuf fsck_msg_types = STRBUF_INIT;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +070040
Nguyễn Thái Ngọc Duy208acbf2014-03-25 20:23:26 +070041/* Remember to update object flag allocation in object.h */
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +070042#define COMPLETE (1U << 0)
Jonathan Tanec062832018-06-14 15:54:28 -070043#define ALTERNATE (1U << 1)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +070044
45/*
46 * After sending this many "have"s if we do not get any new ACK , we
47 * give up traversing our history.
48 */
49#define MAX_IN_VAIN 256
50
Jonathan Tand30fe892018-06-14 15:54:26 -070051static int multi_ack, use_sideband;
Fredrik Medley7199c092015-05-21 22:23:38 +020052/* Allow specifying sha1 if it is a ref tip. */
53#define ALLOW_TIP_SHA1 01
Fredrik Medley68ee6282015-05-21 22:23:39 +020054/* Allow request of a sha1 if it is reachable from a ref (possibly hidden ref). */
55#define ALLOW_REACHABLE_SHA1 02
Fredrik Medley7199c092015-05-21 22:23:38 +020056static unsigned int allow_unadvertised_object_request;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +070057
Nguyễn Thái Ngọc Duy0d789a52016-06-12 17:53:54 +070058__attribute__((format (printf, 2, 3)))
59static inline void print_verbose(const struct fetch_pack_args *args,
60 const char *fmt, ...)
61{
62 va_list params;
63
64 if (!args->verbose)
65 return;
66
67 va_start(params, fmt);
68 vfprintf(stderr, fmt, params);
69 va_end(params);
70 fputc('\n', stderr);
71}
72
Jeff King41a078c2017-02-08 15:53:03 -050073struct alternate_object_cache {
74 struct object **items;
75 size_t nr, alloc;
76};
77
Jeff Kingbdf42762018-10-08 11:09:23 -070078static void cache_one_alternate(const struct object_id *oid,
Jeff King41a078c2017-02-08 15:53:03 -050079 void *vcache)
80{
81 struct alternate_object_cache *cache = vcache;
Stefan Beller109cd762018-06-28 18:21:51 -070082 struct object *obj = parse_object(the_repository, oid);
Jeff King41a078c2017-02-08 15:53:03 -050083
84 if (!obj || (obj->flags & ALTERNATE))
85 return;
86
87 obj->flags |= ALTERNATE;
88 ALLOC_GROW(cache->items, cache->nr + 1, cache->alloc);
89 cache->items[cache->nr++] = obj;
90}
91
Jonathan Tanec062832018-06-14 15:54:28 -070092static void for_each_cached_alternate(struct fetch_negotiator *negotiator,
93 void (*cb)(struct fetch_negotiator *,
Jonathan Tand30fe892018-06-14 15:54:26 -070094 struct object *))
Jeff King41a078c2017-02-08 15:53:03 -050095{
96 static int initialized;
97 static struct alternate_object_cache cache;
98 size_t i;
99
100 if (!initialized) {
101 for_each_alternate_ref(cache_one_alternate, &cache);
102 initialized = 1;
103 }
104
105 for (i = 0; i < cache.nr; i++)
Jonathan Tanec062832018-06-14 15:54:28 -0700106 cb(negotiator, cache.items[i]);
Jeff King41a078c2017-02-08 15:53:03 -0500107}
108
Jonathan Tanec062832018-06-14 15:54:28 -0700109static int rev_list_insert_ref(struct fetch_negotiator *negotiator,
Jonathan Tand30fe892018-06-14 15:54:26 -0700110 const char *refname,
111 const struct object_id *oid)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700112{
Stefan Bellera74093d2018-06-28 18:22:05 -0700113 struct object *o = deref_tag(the_repository,
114 parse_object(the_repository, oid),
Stefan Beller109cd762018-06-28 18:21:51 -0700115 refname, 0);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700116
117 if (o && o->type == OBJ_COMMIT)
Jonathan Tanec062832018-06-14 15:54:28 -0700118 negotiator->add_tip(negotiator, (struct commit *)o);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700119
120 return 0;
121}
122
Michael Haggertyb1b49c62015-05-25 18:39:18 +0000123static int rev_list_insert_ref_oid(const char *refname, const struct object_id *oid,
124 int flag, void *cb_data)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700125{
Jonathan Tand30fe892018-06-14 15:54:26 -0700126 return rev_list_insert_ref(cb_data, refname, oid);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700127}
128
129enum ack_type {
130 NAK = 0,
131 ACK,
132 ACK_continue,
133 ACK_common,
134 ACK_ready
135};
136
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800137static void consume_shallow_list(struct fetch_pack_args *args,
138 struct packet_reader *reader)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700139{
Nguyễn Thái Ngọc Duy79891cb2016-06-12 17:53:56 +0700140 if (args->stateless_rpc && args->deepen) {
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700141 /* If we sent a depth we will get back "duplicate"
142 * shallow and unshallow commands every time there
143 * is a block of have lines exchanged.
144 */
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800145 while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
146 if (starts_with(reader->line, "shallow "))
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700147 continue;
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800148 if (starts_with(reader->line, "unshallow "))
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700149 continue;
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700150 die(_("git fetch-pack: expected shallow list"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700151 }
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800152 if (reader->status != PACKET_READ_FLUSH)
153 die(_("git fetch-pack: expected a flush packet after shallow list"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700154 }
155}
156
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800157static enum ack_type get_ack(struct packet_reader *reader,
158 struct object_id *result_oid)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700159{
Jeff King74543a02013-02-20 15:02:57 -0500160 int len;
Jeff King82e56762014-06-18 15:56:03 -0400161 const char *arg;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700162
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800163 if (packet_reader_read(reader) != PACKET_READ_NORMAL)
Jeff Kingbc9d4dc2018-02-08 13:47:49 -0500164 die(_("git fetch-pack: expected ACK/NAK, got a flush packet"));
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800165 len = reader->pktlen;
166
167 if (!strcmp(reader->line, "NAK"))
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700168 return NAK;
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800169 if (skip_prefix(reader->line, "ACK ", &arg)) {
brian m. carlsonf6af19a2019-08-18 20:04:04 +0000170 const char *p;
171 if (!parse_oid_hex(arg, result_oid, &p)) {
172 len -= p - reader->line;
Jeff King82e56762014-06-18 15:56:03 -0400173 if (len < 1)
Jeff King030e9dd2013-02-20 15:00:28 -0500174 return ACK;
brian m. carlsonf6af19a2019-08-18 20:04:04 +0000175 if (strstr(p, "continue"))
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700176 return ACK_continue;
brian m. carlsonf6af19a2019-08-18 20:04:04 +0000177 if (strstr(p, "common"))
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700178 return ACK_common;
brian m. carlsonf6af19a2019-08-18 20:04:04 +0000179 if (strstr(p, "ready"))
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700180 return ACK_ready;
181 return ACK;
182 }
183 }
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800184 die(_("git fetch-pack: expected ACK/NAK, got '%s'"), reader->line);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700185}
186
187static void send_request(struct fetch_pack_args *args,
188 int fd, struct strbuf *buf)
189{
190 if (args->stateless_rpc) {
191 send_sideband(fd, -1, buf->buf, buf->len, LARGE_PACKET_MAX);
192 packet_flush(fd);
Jeff King37c80012019-03-04 23:11:39 -0500193 } else {
194 if (write_in_full(fd, buf->buf, buf->len) < 0)
195 die_errno(_("unable to write to remote"));
196 }
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700197}
198
Jonathan Tanec062832018-06-14 15:54:28 -0700199static void insert_one_alternate_object(struct fetch_negotiator *negotiator,
Jonathan Tand30fe892018-06-14 15:54:26 -0700200 struct object *obj)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700201{
Jonathan Tanec062832018-06-14 15:54:28 -0700202 rev_list_insert_ref(negotiator, NULL, &obj->oid);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700203}
204
205#define INITIAL_FLUSH 16
206#define PIPESAFE_FLUSH 32
Jonathan Tanda470982016-07-18 15:21:38 -0700207#define LARGE_FLUSH 16384
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700208
Brandon Williams685fbd32018-03-15 10:31:28 -0700209static int next_flush(int stateless_rpc, int count)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700210{
Brandon Williams685fbd32018-03-15 10:31:28 -0700211 if (stateless_rpc) {
Jonathan Tanda470982016-07-18 15:21:38 -0700212 if (count < LARGE_FLUSH)
213 count <<= 1;
214 else
215 count = count * 11 / 10;
216 } else {
217 if (count < PIPESAFE_FLUSH)
218 count <<= 1;
219 else
220 count += PIPESAFE_FLUSH;
221 }
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700222 return count;
223}
224
Jonathan Tan3390e422018-07-02 15:39:44 -0700225static void mark_tips(struct fetch_negotiator *negotiator,
226 const struct oid_array *negotiation_tips)
227{
228 int i;
229
230 if (!negotiation_tips) {
231 for_each_ref(rev_list_insert_ref_oid, negotiator);
232 return;
233 }
234
235 for (i = 0; i < negotiation_tips->nr; i++)
236 rev_list_insert_ref(negotiator, NULL,
237 &negotiation_tips->oid[i]);
238 return;
239}
240
Jonathan Tanec062832018-06-14 15:54:28 -0700241static int find_common(struct fetch_negotiator *negotiator,
Jonathan Tand30fe892018-06-14 15:54:26 -0700242 struct fetch_pack_args *args,
brian m. carlson1b283372017-05-01 02:28:54 +0000243 int fd[2], struct object_id *result_oid,
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700244 struct ref *refs)
245{
246 int fetching;
247 int count = 0, flushes = 0, flush_at = INITIAL_FLUSH, retval;
brian m. carlson1b283372017-05-01 02:28:54 +0000248 const struct object_id *oid;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700249 unsigned in_vain = 0;
250 int got_continue = 0;
251 int got_ready = 0;
252 struct strbuf req_buf = STRBUF_INIT;
253 size_t state_len = 0;
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800254 struct packet_reader reader;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700255
256 if (args->stateless_rpc && multi_ack == 1)
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700257 die(_("--stateless-rpc requires multi_ack_detailed"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700258
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800259 packet_reader_init(&reader, fd[0], NULL, 0,
Masaya Suzuki2d103c32018-12-29 13:19:15 -0800260 PACKET_READ_CHOMP_NEWLINE |
261 PACKET_READ_DIE_ON_ERR_PACKET);
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800262
Jonathan Tan12f19a92018-10-03 16:04:52 -0700263 if (!args->no_dependents) {
264 mark_tips(negotiator, args->negotiation_tips);
265 for_each_cached_alternate(negotiator, insert_one_alternate_object);
266 }
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700267
268 fetching = 0;
269 for ( ; refs ; refs = refs->next) {
brian m. carlson1b283372017-05-01 02:28:54 +0000270 struct object_id *remote = &refs->old_oid;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700271 const char *remote_hex;
272 struct object *o;
273
274 /*
275 * If that object is complete (i.e. it is an ancestor of a
276 * local ref), we tell them we have it but do not have to
277 * tell them about its ancestors, which they already know
278 * about.
279 *
280 * We use lookup_object here because we are only
281 * interested in the case we *know* the object is
282 * reachable and we have already scanned it.
Jonathan Tan12f19a92018-10-03 16:04:52 -0700283 *
284 * Do this only if args->no_dependents is false (if it is true,
285 * we cannot trust the object flags).
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700286 */
Jonathan Tan12f19a92018-10-03 16:04:52 -0700287 if (!args->no_dependents &&
Jeff Kingd0229ab2019-06-20 03:41:14 -0400288 ((o = lookup_object(the_repository, remote)) != NULL) &&
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700289 (o->flags & COMPLETE)) {
290 continue;
291 }
292
brian m. carlson1b283372017-05-01 02:28:54 +0000293 remote_hex = oid_to_hex(remote);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700294 if (!fetching) {
295 struct strbuf c = STRBUF_INIT;
296 if (multi_ack == 2) strbuf_addstr(&c, " multi_ack_detailed");
297 if (multi_ack == 1) strbuf_addstr(&c, " multi_ack");
298 if (no_done) strbuf_addstr(&c, " no-done");
299 if (use_sideband == 2) strbuf_addstr(&c, " side-band-64k");
300 if (use_sideband == 1) strbuf_addstr(&c, " side-band");
Nguyễn Thái Ngọc Duycccf74e2016-06-12 17:54:09 +0700301 if (args->deepen_relative) strbuf_addstr(&c, " deepen-relative");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700302 if (args->use_thin_pack) strbuf_addstr(&c, " thin-pack");
303 if (args->no_progress) strbuf_addstr(&c, " no-progress");
304 if (args->include_tag) strbuf_addstr(&c, " include-tag");
305 if (prefer_ofs_delta) strbuf_addstr(&c, " ofs-delta");
Nguyễn Thái Ngọc Duy508ea882016-06-12 17:53:59 +0700306 if (deepen_since_ok) strbuf_addstr(&c, " deepen-since");
Nguyễn Thái Ngọc Duya45a2602016-06-12 17:54:04 +0700307 if (deepen_not_ok) strbuf_addstr(&c, " deepen-not");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700308 if (agent_supported) strbuf_addf(&c, " agent=%s",
309 git_user_agent_sanitized());
Jeff Hostetler640d8b72017-12-08 15:58:40 +0000310 if (args->filter_options.choice)
311 strbuf_addstr(&c, " filter");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700312 packet_buf_write(&req_buf, "want %s%s\n", remote_hex, c.buf);
313 strbuf_release(&c);
314 } else
315 packet_buf_write(&req_buf, "want %s\n", remote_hex);
316 fetching++;
317 }
318
319 if (!fetching) {
320 strbuf_release(&req_buf);
321 packet_flush(fd[1]);
322 return 1;
323 }
324
Stefan Bellerc8813482018-05-17 15:51:46 -0700325 if (is_repository_shallow(the_repository))
Nguyễn Thái Ngọc Duy1a30f5a2013-12-05 20:02:34 +0700326 write_shallow_commits(&req_buf, 1, NULL);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700327 if (args->depth > 0)
328 packet_buf_write(&req_buf, "deepen %d", args->depth);
Nguyễn Thái Ngọc Duy508ea882016-06-12 17:53:59 +0700329 if (args->deepen_since) {
Johannes Schindelindddbad72017-04-26 21:29:31 +0200330 timestamp_t max_age = approxidate(args->deepen_since);
Johannes Schindelincb71f8b2017-04-21 12:45:48 +0200331 packet_buf_write(&req_buf, "deepen-since %"PRItime, max_age);
Nguyễn Thái Ngọc Duy508ea882016-06-12 17:53:59 +0700332 }
Nguyễn Thái Ngọc Duya45a2602016-06-12 17:54:04 +0700333 if (args->deepen_not) {
334 int i;
335 for (i = 0; i < args->deepen_not->nr; i++) {
336 struct string_list_item *s = args->deepen_not->items + i;
337 packet_buf_write(&req_buf, "deepen-not %s", s->string);
338 }
339 }
Josh Steadmon87c2d9d2019-01-07 16:17:09 -0800340 if (server_supports_filtering && args->filter_options.choice) {
Matthew DeVorecf9ceb52019-06-27 15:54:10 -0700341 const char *spec =
342 expand_list_objects_filter_spec(&args->filter_options);
343 packet_buf_write(&req_buf, "filter %s", spec);
Josh Steadmon87c2d9d2019-01-07 16:17:09 -0800344 }
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700345 packet_buf_flush(&req_buf);
346 state_len = req_buf.len;
347
Nguyễn Thái Ngọc Duy79891cb2016-06-12 17:53:56 +0700348 if (args->deepen) {
Jeff Kingae021d82014-06-18 15:47:50 -0400349 const char *arg;
brian m. carlson1b283372017-05-01 02:28:54 +0000350 struct object_id oid;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700351
352 send_request(args, fd[1], &req_buf);
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800353 while (packet_reader_read(&reader) == PACKET_READ_NORMAL) {
354 if (skip_prefix(reader.line, "shallow ", &arg)) {
brian m. carlson1b283372017-05-01 02:28:54 +0000355 if (get_oid_hex(arg, &oid))
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800356 die(_("invalid shallow line: %s"), reader.line);
Stefan Beller19143f12018-05-17 15:51:44 -0700357 register_shallow(the_repository, &oid);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700358 continue;
359 }
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800360 if (skip_prefix(reader.line, "unshallow ", &arg)) {
brian m. carlson1b283372017-05-01 02:28:54 +0000361 if (get_oid_hex(arg, &oid))
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800362 die(_("invalid unshallow line: %s"), reader.line);
Jeff Kingd0229ab2019-06-20 03:41:14 -0400363 if (!lookup_object(the_repository, &oid))
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800364 die(_("object not found: %s"), reader.line);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700365 /* make sure that it is parsed as shallow */
Stefan Beller109cd762018-06-28 18:21:51 -0700366 if (!parse_object(the_repository, &oid))
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800367 die(_("error in object: %s"), reader.line);
brian m. carlsone92b8482017-05-06 22:10:06 +0000368 if (unregister_shallow(&oid))
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800369 die(_("no shallow found: %s"), reader.line);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700370 continue;
371 }
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800372 die(_("expected shallow/unshallow, got %s"), reader.line);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700373 }
374 } else if (!args->stateless_rpc)
375 send_request(args, fd[1], &req_buf);
376
377 if (!args->stateless_rpc) {
378 /* If we aren't using the stateless-rpc interface
379 * we don't need to retain the headers.
380 */
381 strbuf_setlen(&req_buf, 0);
382 state_len = 0;
383 }
384
Josh Steadmon5fc31182019-10-02 16:49:28 -0700385 trace2_region_enter("fetch-pack", "negotiation_v0_v1", the_repository);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700386 flushes = 0;
387 retval = -1;
Jonathan Tan88e2f9e2017-12-05 16:58:49 +0000388 if (args->no_dependents)
389 goto done;
Jonathan Tanec062832018-06-14 15:54:28 -0700390 while ((oid = negotiator->next(negotiator))) {
brian m. carlson1b283372017-05-01 02:28:54 +0000391 packet_buf_write(&req_buf, "have %s\n", oid_to_hex(oid));
392 print_verbose(args, "have %s", oid_to_hex(oid));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700393 in_vain++;
394 if (flush_at <= ++count) {
395 int ack;
396
397 packet_buf_flush(&req_buf);
398 send_request(args, fd[1], &req_buf);
399 strbuf_setlen(&req_buf, state_len);
400 flushes++;
Brandon Williams685fbd32018-03-15 10:31:28 -0700401 flush_at = next_flush(args->stateless_rpc, count);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700402
403 /*
404 * We keep one window "ahead" of the other side, and
405 * will wait for an ACK only on the next one
406 */
407 if (!args->stateless_rpc && count == INITIAL_FLUSH)
408 continue;
409
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800410 consume_shallow_list(args, &reader);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700411 do {
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800412 ack = get_ack(&reader, result_oid);
Nguyễn Thái Ngọc Duy0d789a52016-06-12 17:53:54 +0700413 if (ack)
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700414 print_verbose(args, _("got %s %d %s"), "ack",
brian m. carlson1b283372017-05-01 02:28:54 +0000415 ack, oid_to_hex(result_oid));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700416 switch (ack) {
417 case ACK:
418 flushes = 0;
419 multi_ack = 0;
420 retval = 0;
421 goto done;
422 case ACK_common:
423 case ACK_ready:
424 case ACK_continue: {
425 struct commit *commit =
Stefan Bellerc1f5eb42018-06-28 18:21:59 -0700426 lookup_commit(the_repository,
427 result_oid);
Jonathan Tand093bc72018-06-14 15:54:27 -0700428 int was_common;
Junio C Hamano3a2a1dc2018-08-02 15:30:42 -0700429
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700430 if (!commit)
brian m. carlson1b283372017-05-01 02:28:54 +0000431 die(_("invalid commit %s"), oid_to_hex(result_oid));
Jonathan Tanec062832018-06-14 15:54:28 -0700432 was_common = negotiator->ack(negotiator, commit);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700433 if (args->stateless_rpc
434 && ack == ACK_common
Jonathan Tand093bc72018-06-14 15:54:27 -0700435 && !was_common) {
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700436 /* We need to replay the have for this object
437 * on the next RPC request so the peer knows
438 * it is in common with us.
439 */
brian m. carlson1b283372017-05-01 02:28:54 +0000440 const char *hex = oid_to_hex(result_oid);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700441 packet_buf_write(&req_buf, "have %s\n", hex);
442 state_len = req_buf.len;
Jonathan Tan06b3d382016-09-23 10:41:35 -0700443 /*
444 * Reset in_vain because an ack
445 * for this commit has not been
446 * seen.
447 */
448 in_vain = 0;
449 } else if (!args->stateless_rpc
450 || ack != ACK_common)
451 in_vain = 0;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700452 retval = 0;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700453 got_continue = 1;
Jonathan Tan21bcf6e2018-06-14 15:54:24 -0700454 if (ack == ACK_ready)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700455 got_ready = 1;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700456 break;
457 }
458 }
459 } while (ack);
460 flushes--;
461 if (got_continue && MAX_IN_VAIN < in_vain) {
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700462 print_verbose(args, _("giving up"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700463 break; /* give up */
464 }
Jonathan Tan21bcf6e2018-06-14 15:54:24 -0700465 if (got_ready)
466 break;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700467 }
468 }
469done:
Josh Steadmon5fc31182019-10-02 16:49:28 -0700470 trace2_region_leave("fetch-pack", "negotiation_v0_v1", the_repository);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700471 if (!got_ready || !no_done) {
472 packet_buf_write(&req_buf, "done\n");
473 send_request(args, fd[1], &req_buf);
474 }
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700475 print_verbose(args, _("done"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700476 if (retval != 0) {
477 multi_ack = 0;
478 flushes++;
479 }
480 strbuf_release(&req_buf);
481
Nguyễn Thái Ngọc Duyff62eca2014-02-06 22:10:39 +0700482 if (!got_ready || !no_done)
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800483 consume_shallow_list(args, &reader);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700484 while (flushes || multi_ack) {
Masaya Suzuki01f9ec62018-12-29 13:19:14 -0800485 int ack = get_ack(&reader, result_oid);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700486 if (ack) {
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700487 print_verbose(args, _("got %s (%d) %s"), "ack",
brian m. carlson1b283372017-05-01 02:28:54 +0000488 ack, oid_to_hex(result_oid));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700489 if (ack == ACK)
490 return 0;
491 multi_ack = 1;
492 continue;
493 }
494 flushes--;
495 }
496 /* it is no error to fetch into a completely empty repo */
497 return count ? retval : 0;
498}
499
500static struct commit_list *complete;
501
brian m. carlson1b283372017-05-01 02:28:54 +0000502static int mark_complete(const struct object_id *oid)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700503{
Stefan Beller109cd762018-06-28 18:21:51 -0700504 struct object *o = parse_object(the_repository, oid);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700505
506 while (o && o->type == OBJ_TAG) {
507 struct tag *t = (struct tag *) o;
508 if (!t->tagged)
509 break; /* broken repository */
510 o->flags |= COMPLETE;
Stefan Beller109cd762018-06-28 18:21:51 -0700511 o = parse_object(the_repository, &t->tagged->oid);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700512 }
513 if (o && o->type == OBJ_COMMIT) {
514 struct commit *commit = (struct commit *)o;
515 if (!(commit->object.flags & COMPLETE)) {
516 commit->object.flags |= COMPLETE;
Jeff King16445242013-07-02 02:16:23 -0400517 commit_list_insert(commit, &complete);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700518 }
519 }
520 return 0;
521}
522
Michael Haggertyf8ee4d82015-05-25 18:39:16 +0000523static int mark_complete_oid(const char *refname, const struct object_id *oid,
524 int flag, void *cb_data)
525{
brian m. carlson1b283372017-05-01 02:28:54 +0000526 return mark_complete(oid);
Michael Haggertyf8ee4d82015-05-25 18:39:16 +0000527}
528
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700529static void mark_recent_complete_commits(struct fetch_pack_args *args,
Johannes Schindelindddbad72017-04-26 21:29:31 +0200530 timestamp_t cutoff)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700531{
532 while (complete && cutoff <= complete->item->date) {
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700533 print_verbose(args, _("Marking %s as complete"),
Nguyễn Thái Ngọc Duy0d789a52016-06-12 17:53:54 +0700534 oid_to_hex(&complete->item->object.oid));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700535 pop_most_recent_commit(&complete, COMPLETE);
536 }
537}
538
Jonathan Tanfdb69d32017-05-15 10:32:20 -0700539static void add_refs_to_oidset(struct oidset *oids, struct ref *refs)
540{
541 for (; refs; refs = refs->next)
542 oidset_insert(oids, &refs->old_oid);
543}
544
René Scharfebf732822018-10-04 17:09:06 +0200545static int is_unmatched_ref(const struct ref *ref)
546{
547 struct object_id oid;
548 const char *p;
549 return ref->match_status == REF_NOT_MATCHED &&
550 !parse_oid_hex(ref->name, &oid, &p) &&
551 *p == '\0' &&
552 oideq(&oid, &ref->old_oid);
553}
554
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700555static void filter_refs(struct fetch_pack_args *args,
Junio C Hamanof2db8542013-01-29 14:02:15 -0800556 struct ref **refs,
557 struct ref **sought, int nr_sought)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700558{
559 struct ref *newlist = NULL;
560 struct ref **newtail = &newlist;
Jonathan Tanfdb69d32017-05-15 10:32:20 -0700561 struct ref *unmatched = NULL;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700562 struct ref *ref, *next;
Jonathan Tanfdb69d32017-05-15 10:32:20 -0700563 struct oidset tip_oids = OIDSET_INIT;
Junio C Hamanof2db8542013-01-29 14:02:15 -0800564 int i;
René Scharfe22a16462018-10-04 17:09:39 +0200565 int strict = !(allow_unadvertised_object_request &
566 (ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700567
Junio C Hamanof2db8542013-01-29 14:02:15 -0800568 i = 0;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700569 for (ref = *refs; ref; ref = next) {
570 int keep = 0;
571 next = ref->next;
Junio C Hamanof2db8542013-01-29 14:02:15 -0800572
René Scharfe50e19a82014-06-06 19:24:48 +0200573 if (starts_with(ref->name, "refs/") &&
Jeff King34066f02019-04-13 01:57:37 -0400574 check_refname_format(ref->name, 0)) {
575 /*
576 * trash or a peeled value; do not even add it to
577 * unmatched list
578 */
579 free_one_ref(ref);
580 continue;
581 } else {
Junio C Hamanof2db8542013-01-29 14:02:15 -0800582 while (i < nr_sought) {
583 int cmp = strcmp(ref->name, sought[i]->name);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700584 if (cmp < 0)
585 break; /* definitely do not have it */
586 else if (cmp == 0) {
587 keep = 1; /* definitely have it */
Matt McCutchend56583d2017-02-22 11:05:57 -0500588 sought[i]->match_status = REF_MATCHED;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700589 }
Junio C Hamanof2db8542013-01-29 14:02:15 -0800590 i++;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700591 }
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700592
Jeff Kinge9502c02018-06-11 01:53:57 -0400593 if (!keep && args->fetch_all &&
594 (!args->deepen || !starts_with(ref->name, "refs/tags/")))
595 keep = 1;
596 }
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700597
598 if (keep) {
599 *newtail = ref;
600 ref->next = NULL;
601 newtail = &ref->next;
602 } else {
Jonathan Tanfdb69d32017-05-15 10:32:20 -0700603 ref->next = unmatched;
604 unmatched = ref;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700605 }
606 }
607
René Scharfe22a16462018-10-04 17:09:39 +0200608 if (strict) {
609 for (i = 0; i < nr_sought; i++) {
610 ref = sought[i];
611 if (!is_unmatched_ref(ref))
612 continue;
613
614 add_refs_to_oidset(&tip_oids, unmatched);
615 add_refs_to_oidset(&tip_oids, newlist);
616 break;
617 }
618 }
619
Junio C Hamano6e7b66e2013-01-29 14:02:15 -0800620 /* Append unmatched requests to the list */
Matt McCutchend56583d2017-02-22 11:05:57 -0500621 for (i = 0; i < nr_sought; i++) {
Matt McCutchend56583d2017-02-22 11:05:57 -0500622 ref = sought[i];
René Scharfebf732822018-10-04 17:09:06 +0200623 if (!is_unmatched_ref(ref))
Matt McCutchend56583d2017-02-22 11:05:57 -0500624 continue;
Junio C Hamano6e7b66e2013-01-29 14:02:15 -0800625
René Scharfe22a16462018-10-04 17:09:39 +0200626 if (!strict || oidset_contains(&tip_oids, &ref->old_oid)) {
Matt McCutchend56583d2017-02-22 11:05:57 -0500627 ref->match_status = REF_MATCHED;
Jeff Kingc3c17bf2015-03-19 16:37:09 -0400628 *newtail = copy_ref(ref);
629 newtail = &(*newtail)->next;
Matt McCutchend56583d2017-02-22 11:05:57 -0500630 } else {
631 ref->match_status = REF_UNADVERTISED_NOT_ALLOWED;
Junio C Hamano6e7b66e2013-01-29 14:02:15 -0800632 }
633 }
Jonathan Tanfdb69d32017-05-15 10:32:20 -0700634
635 oidset_clear(&tip_oids);
Jeff King259eddd2019-04-13 01:54:09 -0400636 free_refs(unmatched);
Jonathan Tanfdb69d32017-05-15 10:32:20 -0700637
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700638 *refs = newlist;
639}
640
Jonathan Tanec062832018-06-14 15:54:28 -0700641static void mark_alternate_complete(struct fetch_negotiator *unused,
Jonathan Tand30fe892018-06-14 15:54:26 -0700642 struct object *obj)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700643{
brian m. carlson1b283372017-05-01 02:28:54 +0000644 mark_complete(&obj->oid);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700645}
646
Takuto Ikuta024aa462018-03-14 15:32:42 +0900647struct loose_object_iter {
648 struct oidset *loose_object_set;
649 struct ref *refs;
650};
651
652/*
Jonathan Tan34c29032018-06-06 13:47:07 -0700653 * Mark recent commits available locally and reachable from a local ref as
654 * COMPLETE. If args->no_dependents is false, also mark COMPLETE remote refs as
655 * COMMON_REF (otherwise, we are not planning to participate in negotiation, and
656 * thus do not need COMMON_REF marks).
657 *
658 * The cutoff time for recency is determined by this heuristic: it is the
659 * earliest commit time of the objects in refs that are commits and that we know
660 * the commit time of.
661 */
Jonathan Tanec062832018-06-14 15:54:28 -0700662static void mark_complete_and_common_ref(struct fetch_negotiator *negotiator,
Jonathan Tand30fe892018-06-14 15:54:26 -0700663 struct fetch_pack_args *args,
Jonathan Tan34c29032018-06-06 13:47:07 -0700664 struct ref **refs)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700665{
666 struct ref *ref;
Jonathan Tana1c6d7c2017-12-08 15:58:48 +0000667 int old_save_commit_buffer = save_commit_buffer;
Johannes Schindelindddbad72017-04-26 21:29:31 +0200668 timestamp_t cutoff = 0;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700669
670 save_commit_buffer = 0;
671
Erik Chen9e5afdf2019-11-19 23:02:09 +0000672 trace2_region_enter("fetch-pack", "parse_remote_refs_and_find_cutoff", NULL);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700673 for (ref = *refs; ref; ref = ref->next) {
674 struct object *o;
675
Jeff King97b2fa02018-11-12 09:55:58 -0500676 if (!has_object_file_with_flags(&ref->old_oid,
Jonathan Tan6462d5e2019-11-05 10:56:19 -0800677 OBJECT_INFO_QUICK |
678 OBJECT_INFO_SKIP_FETCH_OBJECT))
Junio C Hamano012a1bb2013-01-26 19:42:09 -0800679 continue;
Stefan Beller109cd762018-06-28 18:21:51 -0700680 o = parse_object(the_repository, &ref->old_oid);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700681 if (!o)
682 continue;
683
Erik Chen9e5afdf2019-11-19 23:02:09 +0000684 /*
685 * We already have it -- which may mean that we were
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700686 * 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 }
Erik Chen9e5afdf2019-11-19 23:02:09 +0000695 trace2_region_leave("fetch-pack", "parse_remote_refs_and_find_cutoff", NULL);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700696
Erik Chen9e5afdf2019-11-19 23:02:09 +0000697 /*
698 * This block marks all local refs as COMPLETE, and then recursively marks all
699 * parents of those refs as COMPLETE.
700 */
701 trace2_region_enter("fetch-pack", "mark_complete_local_refs", NULL);
Jonathan Tan12f19a92018-10-03 16:04:52 -0700702 if (!args->deepen) {
703 for_each_ref(mark_complete_oid, NULL);
704 for_each_cached_alternate(NULL, mark_alternate_complete);
705 commit_list_sort_by_date(&complete);
706 if (cutoff)
707 mark_recent_complete_commits(args, cutoff);
708 }
Erik Chen9e5afdf2019-11-19 23:02:09 +0000709 trace2_region_leave("fetch-pack", "mark_complete_local_refs", NULL);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700710
Jonathan Tan12f19a92018-10-03 16:04:52 -0700711 /*
712 * Mark all complete remote refs as common refs.
713 * Don't mark them common yet; the server has to be told so first.
714 */
Erik Chen9e5afdf2019-11-19 23:02:09 +0000715 trace2_region_enter("fetch-pack", "mark_common_remote_refs", NULL);
Jonathan Tan12f19a92018-10-03 16:04:52 -0700716 for (ref = *refs; ref; ref = ref->next) {
717 struct object *o = deref_tag(the_repository,
718 lookup_object(the_repository,
Jeff Kingd0229ab2019-06-20 03:41:14 -0400719 &ref->old_oid),
Jonathan Tan12f19a92018-10-03 16:04:52 -0700720 NULL, 0);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700721
Jonathan Tan12f19a92018-10-03 16:04:52 -0700722 if (!o || o->type != OBJ_COMMIT || !(o->flags & COMPLETE))
723 continue;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700724
Jonathan Tan12f19a92018-10-03 16:04:52 -0700725 negotiator->known_common(negotiator,
726 (struct commit *)o);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700727 }
Erik Chen9e5afdf2019-11-19 23:02:09 +0000728 trace2_region_leave("fetch-pack", "mark_common_remote_refs", NULL);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700729
Jonathan Tan34c29032018-06-06 13:47:07 -0700730 save_commit_buffer = old_save_commit_buffer;
731}
732
733/*
734 * Returns 1 if every object pointed to by the given remote refs is available
735 * locally and reachable from a local ref, and 0 otherwise.
736 */
737static int everything_local(struct fetch_pack_args *args,
738 struct ref **refs)
739{
740 struct ref *ref;
741 int retval;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700742
743 for (retval = 1, ref = *refs; ref ; ref = ref->next) {
brian m. carlson1b283372017-05-01 02:28:54 +0000744 const struct object_id *remote = &ref->old_oid;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700745 struct object *o;
746
Jeff Kingd0229ab2019-06-20 03:41:14 -0400747 o = lookup_object(the_repository, remote);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700748 if (!o || !(o->flags & COMPLETE)) {
749 retval = 0;
brian m. carlson1b283372017-05-01 02:28:54 +0000750 print_verbose(args, "want %s (%s)", oid_to_hex(remote),
Nguyễn Thái Ngọc Duy0d789a52016-06-12 17:53:54 +0700751 ref->name);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700752 continue;
753 }
brian m. carlson1b283372017-05-01 02:28:54 +0000754 print_verbose(args, _("already have %s (%s)"), oid_to_hex(remote),
Nguyễn Thái Ngọc Duy0d789a52016-06-12 17:53:54 +0700755 ref->name);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700756 }
Jonathan Tana1c6d7c2017-12-08 15:58:48 +0000757
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700758 return retval;
759}
760
761static int sideband_demux(int in, int out, void *data)
762{
763 int *xd = data;
Jeff King9ff18fa2016-02-24 02:44:58 -0500764 int ret;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700765
Jeff King9ff18fa2016-02-24 02:44:58 -0500766 ret = recv_sideband("fetch-pack", xd[0], out);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700767 close(out);
768 return ret;
769}
770
Jonathan Tan5374a292019-10-14 17:12:31 -0700771static void write_promisor_file(const char *keep_name,
772 struct ref **sought, int nr_sought)
773{
774 struct strbuf promisor_name = STRBUF_INIT;
775 int suffix_stripped;
776 FILE *output;
777 int i;
778
779 strbuf_addstr(&promisor_name, keep_name);
780 suffix_stripped = strbuf_strip_suffix(&promisor_name, ".keep");
781 if (!suffix_stripped)
782 BUG("name of pack lockfile should end with .keep (was '%s')",
783 keep_name);
784 strbuf_addstr(&promisor_name, ".promisor");
785
786 output = xfopen(promisor_name.buf, "w");
787 for (i = 0; i < nr_sought; i++)
788 fprintf(output, "%s %s\n", oid_to_hex(&sought[i]->old_oid),
789 sought[i]->name);
790 fclose(output);
791
792 strbuf_release(&promisor_name);
793}
794
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700795static int get_pack(struct fetch_pack_args *args,
Jonathan Tan5374a292019-10-14 17:12:31 -0700796 int xd[2], char **pack_lockfile,
797 struct ref **sought, int nr_sought)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700798{
799 struct async demux;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700800 int do_keep = args->keep_pack;
Jeff King984a43b2015-09-24 17:07:54 -0400801 const char *cmd_name;
802 struct pack_header header;
803 int pass_header = 0;
René Scharfed3180272014-08-19 21:09:35 +0200804 struct child_process cmd = CHILD_PROCESS_INIT;
Nguyễn Thái Ngọc Duyc6807a42013-05-26 08:16:17 +0700805 int ret;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700806
807 memset(&demux, 0, sizeof(demux));
808 if (use_sideband) {
809 /* xd[] is talking with upload-pack; subprocess reads from
810 * xd[0], spits out band#2 to stderr, and feeds us band#1
811 * through demux->out.
812 */
813 demux.proc = sideband_demux;
814 demux.data = xd;
815 demux.out = -1;
Jeff Kingdf857572016-04-19 18:50:29 -0400816 demux.isolate_sigpipe = 1;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700817 if (start_async(&demux))
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700818 die(_("fetch-pack: unable to fork off sideband demultiplexer"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700819 }
820 else
821 demux.out = xd[0];
822
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700823 if (!args->keep_pack && unpack_limit) {
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700824
825 if (read_pack_header(demux.out, &header))
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700826 die(_("protocol error: bad pack header"));
Jeff King984a43b2015-09-24 17:07:54 -0400827 pass_header = 1;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700828 if (ntohl(header.hdr_entries) < unpack_limit)
829 do_keep = 0;
830 else
831 do_keep = 1;
832 }
833
Nguyễn Thái Ngọc Duy6035d6a2013-05-26 08:16:15 +0700834 if (alternate_shallow_file) {
Jeff King984a43b2015-09-24 17:07:54 -0400835 argv_array_push(&cmd.args, "--shallow-file");
836 argv_array_push(&cmd.args, alternate_shallow_file);
Nguyễn Thái Ngọc Duy6035d6a2013-05-26 08:16:15 +0700837 }
838
Jonathan Tan88e2f9e2017-12-05 16:58:49 +0000839 if (do_keep || args->from_promisor) {
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700840 if (pack_lockfile)
841 cmd.out = -1;
Jeff King984a43b2015-09-24 17:07:54 -0400842 cmd_name = "index-pack";
843 argv_array_push(&cmd.args, cmd_name);
844 argv_array_push(&cmd.args, "--stdin");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700845 if (!args->quiet && !args->no_progress)
Jeff King984a43b2015-09-24 17:07:54 -0400846 argv_array_push(&cmd.args, "-v");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700847 if (args->use_thin_pack)
Jeff King984a43b2015-09-24 17:07:54 -0400848 argv_array_push(&cmd.args, "--fix-thin");
Jonathan Tan88e2f9e2017-12-05 16:58:49 +0000849 if (do_keep && (args->lock_pack || unpack_limit)) {
René Scharfeda25bdb2017-04-18 17:57:42 -0400850 char hostname[HOST_NAME_MAX + 1];
David Turner5781a9a2017-04-18 17:57:43 -0400851 if (xgethostname(hostname, sizeof(hostname)))
Jeff King984a43b2015-09-24 17:07:54 -0400852 xsnprintf(hostname, sizeof(hostname), "localhost");
853 argv_array_pushf(&cmd.args,
854 "--keep=fetch-pack %"PRIuMAX " on %s",
855 (uintmax_t)getpid(), hostname);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700856 }
Nguyễn Thái Ngọc Duyc6807a42013-05-26 08:16:17 +0700857 if (args->check_self_contained_and_connected)
Jeff King984a43b2015-09-24 17:07:54 -0400858 argv_array_push(&cmd.args, "--check-self-contained-and-connected");
Jonathan Tan5374a292019-10-14 17:12:31 -0700859 /*
860 * If we're obtaining the filename of a lockfile, we'll use
861 * that filename to write a .promisor file with more
862 * information below. If not, we need index-pack to do it for
863 * us.
864 */
865 if (!(do_keep && pack_lockfile) && args->from_promisor)
Jonathan Tan88e2f9e2017-12-05 16:58:49 +0000866 argv_array_push(&cmd.args, "--promisor");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700867 }
868 else {
Jeff King984a43b2015-09-24 17:07:54 -0400869 cmd_name = "unpack-objects";
870 argv_array_push(&cmd.args, cmd_name);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700871 if (args->quiet || args->no_progress)
Jeff King984a43b2015-09-24 17:07:54 -0400872 argv_array_push(&cmd.args, "-q");
Nguyễn Thái Ngọc Duyc6807a42013-05-26 08:16:17 +0700873 args->check_self_contained_and_connected = 0;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700874 }
Jeff King984a43b2015-09-24 17:07:54 -0400875
876 if (pass_header)
877 argv_array_pushf(&cmd.args, "--pack_header=%"PRIu32",%"PRIu32,
878 ntohl(header.hdr_version),
879 ntohl(header.hdr_entries));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700880 if (fetch_fsck_objects >= 0
881 ? fetch_fsck_objects
882 : transfer_fsck_objects >= 0
883 ? transfer_fsck_objects
Jonathan Tan98a2ea42018-03-14 11:42:41 -0700884 : 0) {
885 if (args->from_promisor)
886 /*
887 * We cannot use --strict in index-pack because it
888 * checks both broken objects and links, but we only
889 * want to check for broken objects.
890 */
891 argv_array_push(&cmd.args, "--fsck-objects");
892 else
Ævar Arnfjörð Bjarmason1362df02018-07-27 14:37:17 +0000893 argv_array_pushf(&cmd.args, "--strict%s",
894 fsck_msg_types.buf);
Jonathan Tan98a2ea42018-03-14 11:42:41 -0700895 }
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700896
897 cmd.in = demux.out;
898 cmd.git_cmd = 1;
899 if (start_command(&cmd))
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700900 die(_("fetch-pack: unable to fork off %s"), cmd_name);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700901 if (do_keep && pack_lockfile) {
902 *pack_lockfile = index_pack_lockfile(cmd.out);
903 close(cmd.out);
904 }
905
Jens Lindstrom37cb1dd2013-10-22 15:36:02 +0200906 if (!use_sideband)
907 /* Closed by start_command() */
908 xd[0] = -1;
909
Nguyễn Thái Ngọc Duyc6807a42013-05-26 08:16:17 +0700910 ret = finish_command(&cmd);
911 if (!ret || (args->check_self_contained_and_connected && ret == 1))
912 args->self_contained_and_connected =
913 args->check_self_contained_and_connected &&
914 ret == 0;
915 else
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700916 die(_("%s failed"), cmd_name);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700917 if (use_sideband && finish_async(&demux))
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700918 die(_("error in sideband demultiplexer"));
Jonathan Tan5374a292019-10-14 17:12:31 -0700919
920 /*
921 * Now that index-pack has succeeded, write the promisor file using the
922 * obtained .keep filename if necessary
923 */
924 if (do_keep && pack_lockfile && args->from_promisor)
925 write_promisor_file(*pack_lockfile, sought, nr_sought);
926
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700927 return 0;
928}
929
Junio C Hamanof2db8542013-01-29 14:02:15 -0800930static int cmp_ref_by_name(const void *a_, const void *b_)
931{
932 const struct ref *a = *((const struct ref **)a_);
933 const struct ref *b = *((const struct ref **)b_);
934 return strcmp(a->name, b->name);
935}
936
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700937static struct ref *do_fetch_pack(struct fetch_pack_args *args,
938 int fd[2],
939 const struct ref *orig_ref,
Junio C Hamanof2db8542013-01-29 14:02:15 -0800940 struct ref **sought, int nr_sought,
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +0700941 struct shallow_info *si,
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700942 char **pack_lockfile)
943{
Derrick Stoleeaaf633c2019-08-13 11:37:48 -0700944 struct repository *r = the_repository;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700945 struct ref *ref = copy_ref_list(orig_ref);
brian m. carlson1b283372017-05-01 02:28:54 +0000946 struct object_id oid;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700947 const char *agent_feature;
948 int agent_len;
Jonathan Tan603960b2019-11-12 16:34:20 -0800949 struct fetch_negotiator negotiator_alloc;
950 struct fetch_negotiator *negotiator;
951
952 if (args->no_dependents) {
953 negotiator = NULL;
954 } else {
955 negotiator = &negotiator_alloc;
956 fetch_negotiator_init(r, negotiator);
957 }
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700958
959 sort_ref_list(&ref, ref_compare_name);
René Scharfe9ed0d8d2016-09-29 17:27:31 +0200960 QSORT(sought, nr_sought, cmp_ref_by_name);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700961
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700962 if ((agent_feature = server_feature_value("agent", &agent_len))) {
963 agent_supported = 1;
Nguyễn Thái Ngọc Duy0d789a52016-06-12 17:53:54 +0700964 if (agent_len)
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +0700965 print_verbose(args, _("Server version is %.*s"),
Nguyễn Thái Ngọc Duy0d789a52016-06-12 17:53:54 +0700966 agent_len, agent_feature);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700967 }
Nguyễn Thái Ngọc Duy0e042972019-06-20 18:59:51 +0700968
Nguyễn Thái Ngọc Duy5a885832019-06-20 18:59:50 +0700969 if (server_supports("shallow"))
970 print_verbose(args, _("Server supports %s"), "shallow");
Derrick Stoleeaaf633c2019-08-13 11:37:48 -0700971 else if (args->depth > 0 || is_repository_shallow(r))
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700972 die(_("Server does not support shallow clients"));
973 if (args->depth > 0 || args->deepen_since || args->deepen_not)
974 args->deepen = 1;
975 if (server_supports("multi_ack_detailed")) {
Nguyễn Thái Ngọc Duy0778b292019-06-20 18:59:49 +0700976 print_verbose(args, _("Server supports %s"), "multi_ack_detailed");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700977 multi_ack = 2;
978 if (server_supports("no-done")) {
Nguyễn Thái Ngọc Duy0778b292019-06-20 18:59:49 +0700979 print_verbose(args, _("Server supports %s"), "no-done");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700980 if (args->stateless_rpc)
981 no_done = 1;
982 }
983 }
984 else if (server_supports("multi_ack")) {
Nguyễn Thái Ngọc Duy0778b292019-06-20 18:59:49 +0700985 print_verbose(args, _("Server supports %s"), "multi_ack");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700986 multi_ack = 1;
987 }
988 if (server_supports("side-band-64k")) {
Nguyễn Thái Ngọc Duy0778b292019-06-20 18:59:49 +0700989 print_verbose(args, _("Server supports %s"), "side-band-64k");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700990 use_sideband = 2;
991 }
992 else if (server_supports("side-band")) {
Nguyễn Thái Ngọc Duy0778b292019-06-20 18:59:49 +0700993 print_verbose(args, _("Server supports %s"), "side-band");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700994 use_sideband = 1;
995 }
996 if (server_supports("allow-tip-sha1-in-want")) {
Nguyễn Thái Ngọc Duy0778b292019-06-20 18:59:49 +0700997 print_verbose(args, _("Server supports %s"), "allow-tip-sha1-in-want");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +0700998 allow_unadvertised_object_request |= ALLOW_TIP_SHA1;
999 }
1000 if (server_supports("allow-reachable-sha1-in-want")) {
Nguyễn Thái Ngọc Duy0778b292019-06-20 18:59:49 +07001001 print_verbose(args, _("Server supports %s"), "allow-reachable-sha1-in-want");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001002 allow_unadvertised_object_request |= ALLOW_REACHABLE_SHA1;
1003 }
Nguyễn Thái Ngọc Duy5a885832019-06-20 18:59:50 +07001004 if (server_supports("thin-pack"))
1005 print_verbose(args, _("Server supports %s"), "thin-pack");
1006 else
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001007 args->use_thin_pack = 0;
Nguyễn Thái Ngọc Duy5a885832019-06-20 18:59:50 +07001008 if (server_supports("no-progress"))
1009 print_verbose(args, _("Server supports %s"), "no-progress");
1010 else
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001011 args->no_progress = 0;
Nguyễn Thái Ngọc Duy5a885832019-06-20 18:59:50 +07001012 if (server_supports("include-tag"))
1013 print_verbose(args, _("Server supports %s"), "include-tag");
1014 else
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001015 args->include_tag = 0;
1016 if (server_supports("ofs-delta"))
Nguyễn Thái Ngọc Duy0778b292019-06-20 18:59:49 +07001017 print_verbose(args, _("Server supports %s"), "ofs-delta");
Nguyễn Thái Ngọc Duy508ea882016-06-12 17:53:59 +07001018 else
1019 prefer_ofs_delta = 0;
1020
Nguyễn Thái Ngọc Duya45a2602016-06-12 17:54:04 +07001021 if (server_supports("filter")) {
1022 server_supports_filtering = 1;
Nguyễn Thái Ngọc Duy0778b292019-06-20 18:59:49 +07001023 print_verbose(args, _("Server supports %s"), "filter");
Nguyễn Thái Ngọc Duya45a2602016-06-12 17:54:04 +07001024 } else if (args->filter_options.choice) {
Nguyễn Thái Ngọc Duycccf74e2016-06-12 17:54:09 +07001025 warning("filtering not recognized by server, ignoring");
1026 }
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001027
Nguyễn Thái Ngọc Duy5a885832019-06-20 18:59:50 +07001028 if (server_supports("deepen-since")) {
1029 print_verbose(args, _("Server supports %s"), "deepen-since");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001030 deepen_since_ok = 1;
Nguyễn Thái Ngọc Duy5a885832019-06-20 18:59:50 +07001031 } else if (args->deepen_since)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001032 die(_("Server does not support --shallow-since"));
Nguyễn Thái Ngọc Duy5a885832019-06-20 18:59:50 +07001033 if (server_supports("deepen-not")) {
1034 print_verbose(args, _("Server supports %s"), "deepen-not");
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001035 deepen_not_ok = 1;
Nguyễn Thái Ngọc Duy5a885832019-06-20 18:59:50 +07001036 } else if (args->deepen_not)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001037 die(_("Server does not support --shallow-exclude"));
Nguyễn Thái Ngọc Duy5a885832019-06-20 18:59:50 +07001038 if (server_supports("deepen-relative"))
1039 print_verbose(args, _("Server supports %s"), "deepen-relative");
1040 else if (args->deepen_relative)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001041 die(_("Server does not support --deepen"));
1042
Jonathan Tan12f19a92018-10-03 16:04:52 -07001043 if (!args->no_dependents) {
Jonathan Tan603960b2019-11-12 16:34:20 -08001044 mark_complete_and_common_ref(negotiator, args, &ref);
Jonathan Tan12f19a92018-10-03 16:04:52 -07001045 filter_refs(args, &ref, sought, nr_sought);
1046 if (everything_local(args, &ref)) {
1047 packet_flush(fd[1]);
1048 goto all_done;
1049 }
1050 } else {
1051 filter_refs(args, &ref, sought, nr_sought);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001052 }
Jonathan Tan603960b2019-11-12 16:34:20 -08001053 if (find_common(negotiator, args, fd, &oid, ref) < 0)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001054 if (!args->keep_pack)
1055 /* When cloning, it is not unusual to have
1056 * no common commit.
1057 */
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +07001058 warning(_("no common commits"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001059
1060 if (args->stateless_rpc)
1061 packet_flush(fd[1]);
Nguyễn Thái Ngọc Duy79891cb2016-06-12 17:53:56 +07001062 if (args->deepen)
Nguyễn Thái Ngọc Duy1a30f5a2013-12-05 20:02:34 +07001063 setup_alternate_shallow(&shallow_lock, &alternate_shallow_file,
1064 NULL);
Nguyễn Thái Ngọc Duy4820a332013-12-05 20:02:40 +07001065 else if (si->nr_ours || si->nr_theirs)
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001066 alternate_shallow_file = setup_temporary_shallow(si->shallow);
Nguyễn Thái Ngọc Duy6da8bdc2013-08-26 09:17:26 +07001067 else
1068 alternate_shallow_file = NULL;
Jonathan Tan5374a292019-10-14 17:12:31 -07001069 if (get_pack(args, fd, pack_lockfile, sought, nr_sought))
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +07001070 die(_("git fetch-pack: fetch failed."));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001071
1072 all_done:
Jonathan Tan603960b2019-11-12 16:34:20 -08001073 if (negotiator)
1074 negotiator->release(negotiator);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001075 return ref;
1076}
1077
Brandon Williamsf7e20502018-03-15 10:31:29 -07001078static void add_shallow_requests(struct strbuf *req_buf,
1079 const struct fetch_pack_args *args)
1080{
Junio C Hamano00624d62018-07-18 12:20:27 -07001081 if (is_repository_shallow(the_repository))
Brandon Williamsf7e20502018-03-15 10:31:29 -07001082 write_shallow_commits(req_buf, 1, NULL);
1083 if (args->depth > 0)
1084 packet_buf_write(req_buf, "deepen %d", args->depth);
1085 if (args->deepen_since) {
1086 timestamp_t max_age = approxidate(args->deepen_since);
1087 packet_buf_write(req_buf, "deepen-since %"PRItime, max_age);
1088 }
1089 if (args->deepen_not) {
1090 int i;
1091 for (i = 0; i < args->deepen_not->nr; i++) {
1092 struct string_list_item *s = args->deepen_not->items + i;
1093 packet_buf_write(req_buf, "deepen-not %s", s->string);
1094 }
1095 }
Jonathan Tan5056cf42018-12-18 13:24:35 -08001096 if (args->deepen_relative)
1097 packet_buf_write(req_buf, "deepen-relative\n");
Brandon Williamsf7e20502018-03-15 10:31:29 -07001098}
1099
Jonathan Tan12f19a92018-10-03 16:04:52 -07001100static void add_wants(int no_dependents, const struct ref *wants, struct strbuf *req_buf)
Brandon Williams685fbd32018-03-15 10:31:28 -07001101{
Brandon Williams73302052018-06-27 15:30:23 -07001102 int use_ref_in_want = server_supports_feature("fetch", "ref-in-want", 0);
1103
Brandon Williams685fbd32018-03-15 10:31:28 -07001104 for ( ; wants ; wants = wants->next) {
1105 const struct object_id *remote = &wants->old_oid;
Brandon Williams685fbd32018-03-15 10:31:28 -07001106 struct object *o;
1107
1108 /*
1109 * If that object is complete (i.e. it is an ancestor of a
1110 * local ref), we tell them we have it but do not have to
1111 * tell them about its ancestors, which they already know
1112 * about.
1113 *
1114 * We use lookup_object here because we are only
1115 * interested in the case we *know* the object is
1116 * reachable and we have already scanned it.
Jonathan Tan12f19a92018-10-03 16:04:52 -07001117 *
1118 * Do this only if args->no_dependents is false (if it is true,
1119 * we cannot trust the object flags).
Brandon Williams685fbd32018-03-15 10:31:28 -07001120 */
Jonathan Tan12f19a92018-10-03 16:04:52 -07001121 if (!no_dependents &&
Jeff Kingd0229ab2019-06-20 03:41:14 -04001122 ((o = lookup_object(the_repository, remote)) != NULL) &&
Brandon Williams685fbd32018-03-15 10:31:28 -07001123 (o->flags & COMPLETE)) {
1124 continue;
1125 }
1126
Brandon Williams73302052018-06-27 15:30:23 -07001127 if (!use_ref_in_want || wants->exact_oid)
1128 packet_buf_write(req_buf, "want %s\n", oid_to_hex(remote));
1129 else
1130 packet_buf_write(req_buf, "want-ref %s\n", wants->name);
Brandon Williams685fbd32018-03-15 10:31:28 -07001131 }
1132}
1133
1134static void add_common(struct strbuf *req_buf, struct oidset *common)
1135{
1136 struct oidset_iter iter;
1137 const struct object_id *oid;
1138 oidset_iter_init(common, &iter);
1139
1140 while ((oid = oidset_iter_next(&iter))) {
1141 packet_buf_write(req_buf, "have %s\n", oid_to_hex(oid));
1142 }
1143}
1144
Jonathan Tanec062832018-06-14 15:54:28 -07001145static int add_haves(struct fetch_negotiator *negotiator,
1146 struct strbuf *req_buf,
Jonathan Tand30fe892018-06-14 15:54:26 -07001147 int *haves_to_send, int *in_vain)
Brandon Williams685fbd32018-03-15 10:31:28 -07001148{
1149 int ret = 0;
1150 int haves_added = 0;
1151 const struct object_id *oid;
1152
Jonathan Tanec062832018-06-14 15:54:28 -07001153 while ((oid = negotiator->next(negotiator))) {
Brandon Williams685fbd32018-03-15 10:31:28 -07001154 packet_buf_write(req_buf, "have %s\n", oid_to_hex(oid));
1155 if (++haves_added >= *haves_to_send)
1156 break;
1157 }
1158
1159 *in_vain += haves_added;
1160 if (!haves_added || *in_vain >= MAX_IN_VAIN) {
1161 /* Send Done */
1162 packet_buf_write(req_buf, "done\n");
1163 ret = 1;
1164 }
1165
1166 /* Increase haves to send on next round */
1167 *haves_to_send = next_flush(1, *haves_to_send);
1168
1169 return ret;
1170}
1171
Jonathan Tanec062832018-06-14 15:54:28 -07001172static int send_fetch_request(struct fetch_negotiator *negotiator, int fd_out,
Matthew DeVorecf9ceb52019-06-27 15:54:10 -07001173 struct fetch_pack_args *args,
Brandon Williams685fbd32018-03-15 10:31:28 -07001174 const struct ref *wants, struct oidset *common,
Jonathan Tan0bbc0bc2019-01-16 11:28:14 -08001175 int *haves_to_send, int *in_vain,
1176 int sideband_all)
Brandon Williams685fbd32018-03-15 10:31:28 -07001177{
1178 int ret = 0;
1179 struct strbuf req_buf = STRBUF_INIT;
1180
1181 if (server_supports_v2("fetch", 1))
1182 packet_buf_write(&req_buf, "command=fetch");
1183 if (server_supports_v2("agent", 0))
1184 packet_buf_write(&req_buf, "agent=%s", git_user_agent_sanitized());
Brandon Williams5e3548e2018-04-23 15:46:24 -07001185 if (args->server_options && args->server_options->nr &&
1186 server_supports_v2("server-option", 1)) {
1187 int i;
1188 for (i = 0; i < args->server_options->nr; i++)
Jonathan Tan5b204b72019-05-22 13:08:22 -07001189 packet_buf_write(&req_buf, "server-option=%s",
Brandon Williams5e3548e2018-04-23 15:46:24 -07001190 args->server_options->items[i].string);
1191 }
Brandon Williams685fbd32018-03-15 10:31:28 -07001192
1193 packet_buf_delim(&req_buf);
1194 if (args->use_thin_pack)
1195 packet_buf_write(&req_buf, "thin-pack");
1196 if (args->no_progress)
1197 packet_buf_write(&req_buf, "no-progress");
1198 if (args->include_tag)
1199 packet_buf_write(&req_buf, "include-tag");
1200 if (prefer_ofs_delta)
1201 packet_buf_write(&req_buf, "ofs-delta");
Jonathan Tan0bbc0bc2019-01-16 11:28:14 -08001202 if (sideband_all)
1203 packet_buf_write(&req_buf, "sideband-all");
Brandon Williams685fbd32018-03-15 10:31:28 -07001204
Brandon Williamsf7e20502018-03-15 10:31:29 -07001205 /* Add shallow-info and deepen request */
1206 if (server_supports_feature("fetch", "shallow", 0))
1207 add_shallow_requests(&req_buf, args);
Junio C Hamano00624d62018-07-18 12:20:27 -07001208 else if (is_repository_shallow(the_repository) || args->deepen)
Brandon Williamsf7e20502018-03-15 10:31:29 -07001209 die(_("Server does not support shallow requests"));
1210
Jonathan Tanba957102018-05-03 16:46:56 -07001211 /* Add filter */
1212 if (server_supports_feature("fetch", "filter", 0) &&
1213 args->filter_options.choice) {
Matthew DeVorecf9ceb52019-06-27 15:54:10 -07001214 const char *spec =
1215 expand_list_objects_filter_spec(&args->filter_options);
Jonathan Tanba957102018-05-03 16:46:56 -07001216 print_verbose(args, _("Server supports filter"));
Matthew DeVorecf9ceb52019-06-27 15:54:10 -07001217 packet_buf_write(&req_buf, "filter %s", spec);
Jonathan Tanba957102018-05-03 16:46:56 -07001218 } else if (args->filter_options.choice) {
1219 warning("filtering not recognized by server, ignoring");
1220 }
1221
Brandon Williams685fbd32018-03-15 10:31:28 -07001222 /* add wants */
Jonathan Tan12f19a92018-10-03 16:04:52 -07001223 add_wants(args->no_dependents, wants, &req_buf);
Brandon Williams685fbd32018-03-15 10:31:28 -07001224
Jonathan Tanba957102018-05-03 16:46:56 -07001225 if (args->no_dependents) {
1226 packet_buf_write(&req_buf, "done");
1227 ret = 1;
1228 } else {
1229 /* Add all of the common commits we've found in previous rounds */
1230 add_common(&req_buf, common);
Brandon Williams685fbd32018-03-15 10:31:28 -07001231
Jonathan Tanba957102018-05-03 16:46:56 -07001232 /* Add initial haves */
Jonathan Tanec062832018-06-14 15:54:28 -07001233 ret = add_haves(negotiator, &req_buf, haves_to_send, in_vain);
Jonathan Tanba957102018-05-03 16:46:56 -07001234 }
Brandon Williams685fbd32018-03-15 10:31:28 -07001235
1236 /* Send request */
1237 packet_buf_flush(&req_buf);
Jeff King37c80012019-03-04 23:11:39 -05001238 if (write_in_full(fd_out, req_buf.buf, req_buf.len) < 0)
1239 die_errno(_("unable to write request to remote"));
Brandon Williams685fbd32018-03-15 10:31:28 -07001240
1241 strbuf_release(&req_buf);
1242 return ret;
1243}
1244
1245/*
1246 * Processes a section header in a server's response and checks if it matches
1247 * `section`. If the value of `peek` is 1, the header line will be peeked (and
1248 * not consumed); if 0, the line will be consumed and the function will die if
1249 * the section header doesn't match what was expected.
1250 */
1251static int process_section_header(struct packet_reader *reader,
1252 const char *section, int peek)
1253{
1254 int ret;
1255
1256 if (packet_reader_peek(reader) != PACKET_READ_NORMAL)
Brandon Williamsbbb19a82018-07-23 10:56:35 -07001257 die(_("error reading section header '%s'"), section);
Brandon Williams685fbd32018-03-15 10:31:28 -07001258
1259 ret = !strcmp(reader->line, section);
1260
1261 if (!peek) {
1262 if (!ret)
Brandon Williamsbbb19a82018-07-23 10:56:35 -07001263 die(_("expected '%s', received '%s'"),
Brandon Williams685fbd32018-03-15 10:31:28 -07001264 section, reader->line);
1265 packet_reader_read(reader);
1266 }
1267
1268 return ret;
1269}
1270
Jonathan Tanec062832018-06-14 15:54:28 -07001271static int process_acks(struct fetch_negotiator *negotiator,
Jonathan Tand30fe892018-06-14 15:54:26 -07001272 struct packet_reader *reader,
1273 struct oidset *common)
Brandon Williams685fbd32018-03-15 10:31:28 -07001274{
1275 /* received */
1276 int received_ready = 0;
1277 int received_ack = 0;
1278
1279 process_section_header(reader, "acknowledgments", 0);
1280 while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
1281 const char *arg;
1282
1283 if (!strcmp(reader->line, "NAK"))
1284 continue;
1285
1286 if (skip_prefix(reader->line, "ACK ", &arg)) {
1287 struct object_id oid;
1288 if (!get_oid_hex(arg, &oid)) {
1289 struct commit *commit;
1290 oidset_insert(common, &oid);
Stefan Bellerc1f5eb42018-06-28 18:21:59 -07001291 commit = lookup_commit(the_repository, &oid);
Jonathan Tan603960b2019-11-12 16:34:20 -08001292 if (negotiator)
1293 negotiator->ack(negotiator, commit);
Brandon Williams685fbd32018-03-15 10:31:28 -07001294 }
1295 continue;
1296 }
1297
1298 if (!strcmp(reader->line, "ready")) {
Brandon Williams685fbd32018-03-15 10:31:28 -07001299 received_ready = 1;
1300 continue;
1301 }
1302
Brandon Williamsbbb19a82018-07-23 10:56:35 -07001303 die(_("unexpected acknowledgment line: '%s'"), reader->line);
Brandon Williams685fbd32018-03-15 10:31:28 -07001304 }
1305
1306 if (reader->status != PACKET_READ_FLUSH &&
1307 reader->status != PACKET_READ_DELIM)
Brandon Williamsbbb19a82018-07-23 10:56:35 -07001308 die(_("error processing acks: %d"), reader->status);
Brandon Williams685fbd32018-03-15 10:31:28 -07001309
Jonathan Tan5400b2a2018-10-19 15:54:04 -07001310 /*
1311 * If an "acknowledgments" section is sent, a packfile is sent if and
1312 * only if "ready" was sent in this section. The other sections
1313 * ("shallow-info" and "wanted-refs") are sent only if a packfile is
1314 * sent. Therefore, a DELIM is expected if "ready" is sent, and a FLUSH
1315 * otherwise.
1316 */
1317 if (received_ready && reader->status != PACKET_READ_DELIM)
1318 die(_("expected packfile to be sent after 'ready'"));
1319 if (!received_ready && reader->status != PACKET_READ_FLUSH)
1320 die(_("expected no other sections to be sent after no 'ready'"));
1321
Brandon Williams685fbd32018-03-15 10:31:28 -07001322 /* return 0 if no common, 1 if there are common, or 2 if ready */
1323 return received_ready ? 2 : (received_ack ? 1 : 0);
1324}
1325
Brandon Williamsf7e20502018-03-15 10:31:29 -07001326static void receive_shallow_info(struct fetch_pack_args *args,
Jonathan Tan13390782019-03-26 12:31:21 -07001327 struct packet_reader *reader,
1328 struct oid_array *shallows,
1329 struct shallow_info *si)
Brandon Williamsf7e20502018-03-15 10:31:29 -07001330{
Jonathan Tan13390782019-03-26 12:31:21 -07001331 int unshallow_received = 0;
Jonathan Tanbd0b42a2019-01-10 11:36:45 -08001332
Brandon Williamsf7e20502018-03-15 10:31:29 -07001333 process_section_header(reader, "shallow-info", 0);
1334 while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
1335 const char *arg;
1336 struct object_id oid;
1337
1338 if (skip_prefix(reader->line, "shallow ", &arg)) {
1339 if (get_oid_hex(arg, &oid))
1340 die(_("invalid shallow line: %s"), reader->line);
Jonathan Tan13390782019-03-26 12:31:21 -07001341 oid_array_append(shallows, &oid);
Brandon Williamsf7e20502018-03-15 10:31:29 -07001342 continue;
1343 }
1344 if (skip_prefix(reader->line, "unshallow ", &arg)) {
1345 if (get_oid_hex(arg, &oid))
1346 die(_("invalid unshallow line: %s"), reader->line);
Jeff Kingd0229ab2019-06-20 03:41:14 -04001347 if (!lookup_object(the_repository, &oid))
Brandon Williamsf7e20502018-03-15 10:31:29 -07001348 die(_("object not found: %s"), reader->line);
1349 /* make sure that it is parsed as shallow */
Stefan Beller109cd762018-06-28 18:21:51 -07001350 if (!parse_object(the_repository, &oid))
Brandon Williamsf7e20502018-03-15 10:31:29 -07001351 die(_("error in object: %s"), reader->line);
1352 if (unregister_shallow(&oid))
1353 die(_("no shallow found: %s"), reader->line);
Jonathan Tan13390782019-03-26 12:31:21 -07001354 unshallow_received = 1;
Brandon Williamsf7e20502018-03-15 10:31:29 -07001355 continue;
1356 }
1357 die(_("expected shallow/unshallow, got %s"), reader->line);
1358 }
1359
1360 if (reader->status != PACKET_READ_FLUSH &&
1361 reader->status != PACKET_READ_DELIM)
Brandon Williamsbbb19a82018-07-23 10:56:35 -07001362 die(_("error processing shallow info: %d"), reader->status);
Brandon Williamsf7e20502018-03-15 10:31:29 -07001363
Jonathan Tan13390782019-03-26 12:31:21 -07001364 if (args->deepen || unshallow_received) {
1365 /*
1366 * Treat these as shallow lines caused by our depth settings.
1367 * In v0, these lines cannot cause refs to be rejected; do the
1368 * same.
1369 */
1370 int i;
1371
1372 for (i = 0; i < shallows->nr; i++)
1373 register_shallow(the_repository, &shallows->oid[i]);
Jonathan Tanbd0b42a2019-01-10 11:36:45 -08001374 setup_alternate_shallow(&shallow_lock, &alternate_shallow_file,
1375 NULL);
1376 args->deepen = 1;
Jonathan Tan13390782019-03-26 12:31:21 -07001377 } else if (shallows->nr) {
1378 /*
1379 * Treat these as shallow lines caused by the remote being
1380 * shallow. In v0, remote refs that reach these objects are
1381 * rejected (unless --update-shallow is set); do the same.
1382 */
1383 prepare_shallow_info(si, shallows);
1384 if (si->nr_ours || si->nr_theirs)
1385 alternate_shallow_file =
1386 setup_temporary_shallow(si->shallow);
1387 else
1388 alternate_shallow_file = NULL;
brian m. carlson380ebab2019-02-06 23:59:37 +00001389 } else {
1390 alternate_shallow_file = NULL;
Jonathan Tanbd0b42a2019-01-10 11:36:45 -08001391 }
Brandon Williamsf7e20502018-03-15 10:31:29 -07001392}
1393
Jonathan Tanb7643002019-03-27 14:11:10 -07001394static int cmp_name_ref(const void *name, const void *ref)
1395{
1396 return strcmp(name, (*(struct ref **)ref)->name);
1397}
1398
Jonathan Tane2842b32018-08-01 13:13:20 -07001399static void receive_wanted_refs(struct packet_reader *reader,
1400 struct ref **sought, int nr_sought)
Brandon Williams73302052018-06-27 15:30:23 -07001401{
1402 process_section_header(reader, "wanted-refs", 0);
1403 while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
1404 struct object_id oid;
1405 const char *end;
Jonathan Tanb7643002019-03-27 14:11:10 -07001406 struct ref **found;
Brandon Williams73302052018-06-27 15:30:23 -07001407
1408 if (parse_oid_hex(reader->line, &oid, &end) || *end++ != ' ')
Brandon Williamsbbb19a82018-07-23 10:56:35 -07001409 die(_("expected wanted-ref, got '%s'"), reader->line);
Brandon Williams73302052018-06-27 15:30:23 -07001410
Jonathan Tanb7643002019-03-27 14:11:10 -07001411 found = bsearch(end, sought, nr_sought, sizeof(*sought),
1412 cmp_name_ref);
1413 if (!found)
Brandon Williamsbbb19a82018-07-23 10:56:35 -07001414 die(_("unexpected wanted-ref: '%s'"), reader->line);
Jonathan Tanb7643002019-03-27 14:11:10 -07001415 oidcpy(&(*found)->old_oid, &oid);
Brandon Williams73302052018-06-27 15:30:23 -07001416 }
1417
1418 if (reader->status != PACKET_READ_DELIM)
Brandon Williamsbbb19a82018-07-23 10:56:35 -07001419 die(_("error processing wanted refs: %d"), reader->status);
Brandon Williams73302052018-06-27 15:30:23 -07001420}
1421
Brandon Williams685fbd32018-03-15 10:31:28 -07001422enum fetch_state {
1423 FETCH_CHECK_LOCAL = 0,
1424 FETCH_SEND_REQUEST,
1425 FETCH_PROCESS_ACKS,
1426 FETCH_GET_PACK,
1427 FETCH_DONE,
1428};
1429
1430static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1431 int fd[2],
1432 const struct ref *orig_ref,
1433 struct ref **sought, int nr_sought,
Jonathan Tan13390782019-03-26 12:31:21 -07001434 struct oid_array *shallows,
1435 struct shallow_info *si,
Brandon Williams685fbd32018-03-15 10:31:28 -07001436 char **pack_lockfile)
1437{
Derrick Stoleeaaf633c2019-08-13 11:37:48 -07001438 struct repository *r = the_repository;
Brandon Williams685fbd32018-03-15 10:31:28 -07001439 struct ref *ref = copy_ref_list(orig_ref);
1440 enum fetch_state state = FETCH_CHECK_LOCAL;
1441 struct oidset common = OIDSET_INIT;
1442 struct packet_reader reader;
Josh Steadmon5fc31182019-10-02 16:49:28 -07001443 int in_vain = 0, negotiation_started = 0;
Brandon Williams685fbd32018-03-15 10:31:28 -07001444 int haves_to_send = INITIAL_FLUSH;
Jonathan Tan603960b2019-11-12 16:34:20 -08001445 struct fetch_negotiator negotiator_alloc;
1446 struct fetch_negotiator *negotiator;
1447
1448 if (args->no_dependents) {
1449 negotiator = NULL;
1450 } else {
1451 negotiator = &negotiator_alloc;
1452 fetch_negotiator_init(r, negotiator);
1453 }
1454
Brandon Williams685fbd32018-03-15 10:31:28 -07001455 packet_reader_init(&reader, fd[0], NULL, 0,
Masaya Suzuki2d103c32018-12-29 13:19:15 -08001456 PACKET_READ_CHOMP_NEWLINE |
1457 PACKET_READ_DIE_ON_ERR_PACKET);
Jonathan Tan07c3c2a2019-01-16 11:28:15 -08001458 if (git_env_bool("GIT_TEST_SIDEBAND_ALL", 1) &&
1459 server_supports_feature("fetch", "sideband-all", 0)) {
Jonathan Tan0bbc0bc2019-01-16 11:28:14 -08001460 reader.use_sideband = 1;
1461 reader.me = "fetch-pack";
1462 }
Brandon Williams685fbd32018-03-15 10:31:28 -07001463
1464 while (state != FETCH_DONE) {
1465 switch (state) {
1466 case FETCH_CHECK_LOCAL:
1467 sort_ref_list(&ref, ref_compare_name);
1468 QSORT(sought, nr_sought, cmp_ref_by_name);
1469
1470 /* v2 supports these by default */
1471 allow_unadvertised_object_request |= ALLOW_REACHABLE_SHA1;
1472 use_sideband = 2;
Brandon Williamsf7e20502018-03-15 10:31:29 -07001473 if (args->depth > 0 || args->deepen_since || args->deepen_not)
1474 args->deepen = 1;
Brandon Williams685fbd32018-03-15 10:31:28 -07001475
Brandon Williams685fbd32018-03-15 10:31:28 -07001476 /* Filter 'ref' by 'sought' and those that aren't local */
Jonathan Tan12f19a92018-10-03 16:04:52 -07001477 if (!args->no_dependents) {
Jonathan Tan603960b2019-11-12 16:34:20 -08001478 mark_complete_and_common_ref(negotiator, args, &ref);
Jonathan Tan12f19a92018-10-03 16:04:52 -07001479 filter_refs(args, &ref, sought, nr_sought);
1480 if (everything_local(args, &ref))
1481 state = FETCH_DONE;
1482 else
1483 state = FETCH_SEND_REQUEST;
Jonathan Tanaf1c90d2018-06-14 15:54:25 -07001484
Jonathan Tan603960b2019-11-12 16:34:20 -08001485 mark_tips(negotiator, args->negotiation_tips);
1486 for_each_cached_alternate(negotiator,
Jonathan Tan12f19a92018-10-03 16:04:52 -07001487 insert_one_alternate_object);
1488 } else {
1489 filter_refs(args, &ref, sought, nr_sought);
1490 state = FETCH_SEND_REQUEST;
1491 }
Brandon Williams685fbd32018-03-15 10:31:28 -07001492 break;
1493 case FETCH_SEND_REQUEST:
Josh Steadmon5fc31182019-10-02 16:49:28 -07001494 if (!negotiation_started) {
1495 negotiation_started = 1;
1496 trace2_region_enter("fetch-pack",
1497 "negotiation_v2",
1498 the_repository);
1499 }
Jonathan Tan603960b2019-11-12 16:34:20 -08001500 if (send_fetch_request(negotiator, fd[1], args, ref,
Jonathan Tanec062832018-06-14 15:54:28 -07001501 &common,
Jonathan Tan0bbc0bc2019-01-16 11:28:14 -08001502 &haves_to_send, &in_vain,
1503 reader.use_sideband))
Brandon Williams685fbd32018-03-15 10:31:28 -07001504 state = FETCH_GET_PACK;
1505 else
1506 state = FETCH_PROCESS_ACKS;
1507 break;
1508 case FETCH_PROCESS_ACKS:
1509 /* Process ACKs/NAKs */
Jonathan Tan603960b2019-11-12 16:34:20 -08001510 switch (process_acks(negotiator, &reader, &common)) {
Brandon Williams685fbd32018-03-15 10:31:28 -07001511 case 2:
1512 state = FETCH_GET_PACK;
1513 break;
1514 case 1:
1515 in_vain = 0;
1516 /* fallthrough */
1517 default:
1518 state = FETCH_SEND_REQUEST;
1519 break;
1520 }
1521 break;
1522 case FETCH_GET_PACK:
Josh Steadmon5fc31182019-10-02 16:49:28 -07001523 trace2_region_leave("fetch-pack",
1524 "negotiation_v2",
1525 the_repository);
Brandon Williamsf7e20502018-03-15 10:31:29 -07001526 /* Check for shallow-info section */
1527 if (process_section_header(&reader, "shallow-info", 1))
Jonathan Tan13390782019-03-26 12:31:21 -07001528 receive_shallow_info(args, &reader, shallows, si);
Brandon Williamsf7e20502018-03-15 10:31:29 -07001529
Brandon Williams73302052018-06-27 15:30:23 -07001530 if (process_section_header(&reader, "wanted-refs", 1))
Jonathan Tane2842b32018-08-01 13:13:20 -07001531 receive_wanted_refs(&reader, sought, nr_sought);
Brandon Williams73302052018-06-27 15:30:23 -07001532
Brandon Williams685fbd32018-03-15 10:31:28 -07001533 /* get the pack */
1534 process_section_header(&reader, "packfile", 0);
Jonathan Tan5374a292019-10-14 17:12:31 -07001535 if (get_pack(args, fd, pack_lockfile, sought, nr_sought))
Brandon Williams685fbd32018-03-15 10:31:28 -07001536 die(_("git fetch-pack: fetch failed."));
1537
1538 state = FETCH_DONE;
1539 break;
1540 case FETCH_DONE:
1541 continue;
1542 }
1543 }
1544
Jonathan Tan603960b2019-11-12 16:34:20 -08001545 if (negotiator)
1546 negotiator->release(negotiator);
Brandon Williams685fbd32018-03-15 10:31:28 -07001547 oidset_clear(&common);
1548 return ref;
1549}
1550
Ævar Arnfjörð Bjarmason1362df02018-07-27 14:37:17 +00001551static int fetch_pack_config_cb(const char *var, const char *value, void *cb)
1552{
1553 if (strcmp(var, "fetch.fsck.skiplist") == 0) {
1554 const char *path;
1555
1556 if (git_config_pathname(&path, var, value))
1557 return 1;
1558 strbuf_addf(&fsck_msg_types, "%cskiplist=%s",
1559 fsck_msg_types.len ? ',' : '=', path);
1560 free((char *)path);
1561 return 0;
1562 }
1563
1564 if (skip_prefix(var, "fetch.fsck.", &var)) {
1565 if (is_valid_msg_type(var, value))
1566 strbuf_addf(&fsck_msg_types, "%c%s=%s",
1567 fsck_msg_types.len ? ',' : '=', var, value);
1568 else
1569 warning("Skipping unknown msg id '%s'", var);
1570 return 0;
1571 }
1572
1573 return git_default_config(var, value, cb);
1574}
1575
Tanay Abhraf44af512014-08-07 09:21:20 -07001576static void fetch_pack_config(void)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001577{
Tanay Abhraf44af512014-08-07 09:21:20 -07001578 git_config_get_int("fetch.unpacklimit", &fetch_unpack_limit);
1579 git_config_get_int("transfer.unpacklimit", &transfer_unpack_limit);
1580 git_config_get_bool("repack.usedeltabaseoffset", &prefer_ofs_delta);
1581 git_config_get_bool("fetch.fsckobjects", &fetch_fsck_objects);
1582 git_config_get_bool("transfer.fsckobjects", &transfer_fsck_objects);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001583
Ævar Arnfjörð Bjarmason1362df02018-07-27 14:37:17 +00001584 git_config(fetch_pack_config_cb, NULL);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001585}
1586
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001587static void fetch_pack_setup(void)
1588{
1589 static int did_setup;
1590 if (did_setup)
1591 return;
Tanay Abhraf44af512014-08-07 09:21:20 -07001592 fetch_pack_config();
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001593 if (0 <= transfer_unpack_limit)
1594 unpack_limit = transfer_unpack_limit;
1595 else if (0 <= fetch_unpack_limit)
1596 unpack_limit = fetch_unpack_limit;
1597 did_setup = 1;
1598}
1599
Junio C Hamanof2db8542013-01-29 14:02:15 -08001600static int remove_duplicates_in_refs(struct ref **ref, int nr)
1601{
1602 struct string_list names = STRING_LIST_INIT_NODUP;
1603 int src, dst;
1604
1605 for (src = dst = 0; src < nr; src++) {
1606 struct string_list_item *item;
1607 item = string_list_insert(&names, ref[src]->name);
1608 if (item->util)
1609 continue; /* already have it */
1610 item->util = ref[src];
1611 if (src != dst)
1612 ref[dst] = ref[src];
1613 dst++;
1614 }
1615 for (src = dst; src < nr; src++)
1616 ref[src] = NULL;
1617 string_list_clear(&names, 0);
1618 return dst;
1619}
1620
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001621static void update_shallow(struct fetch_pack_args *args,
Jonathan Tane2842b32018-08-01 13:13:20 -07001622 struct ref **sought, int nr_sought,
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001623 struct shallow_info *si)
Nguyễn Thái Ngọc Duya796cce2013-12-05 20:02:37 +07001624{
brian m. carlson910650d2017-03-31 01:40:00 +00001625 struct oid_array ref = OID_ARRAY_INIT;
Nguyễn Thái Ngọc Duy4820a332013-12-05 20:02:40 +07001626 int *status;
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001627 int i;
1628
Nguyễn Thái Ngọc Duy79891cb2016-06-12 17:53:56 +07001629 if (args->deepen && alternate_shallow_file) {
Nguyễn Thái Ngọc Duya796cce2013-12-05 20:02:37 +07001630 if (*alternate_shallow_file == '\0') { /* --unshallow */
Stefan Beller102de882018-05-17 15:51:51 -07001631 unlink_or_warn(git_path_shallow(the_repository));
Nguyễn Thái Ngọc Duya796cce2013-12-05 20:02:37 +07001632 rollback_lock_file(&shallow_lock);
1633 } else
1634 commit_lock_file(&shallow_lock);
brian m. carlson23311f32019-02-04 00:06:50 +00001635 alternate_shallow_file = NULL;
Nguyễn Thái Ngọc Duya796cce2013-12-05 20:02:37 +07001636 return;
1637 }
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001638
1639 if (!si->shallow || !si->shallow->nr)
1640 return;
1641
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001642 if (args->cloning) {
1643 /*
1644 * remote is shallow, but this is a clone, there are
1645 * no objects in repo to worry about. Accept any
1646 * shallow points that exist in the pack (iow in repo
1647 * after get_pack() and reprepare_packed_git())
1648 */
brian m. carlson910650d2017-03-31 01:40:00 +00001649 struct oid_array extra = OID_ARRAY_INIT;
brian m. carlsonee3051b2017-03-26 16:01:37 +00001650 struct object_id *oid = si->shallow->oid;
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001651 for (i = 0; i < si->shallow->nr; i++)
brian m. carlsonee3051b2017-03-26 16:01:37 +00001652 if (has_object_file(&oid[i]))
brian m. carlson910650d2017-03-31 01:40:00 +00001653 oid_array_append(&extra, &oid[i]);
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001654 if (extra.nr) {
1655 setup_alternate_shallow(&shallow_lock,
1656 &alternate_shallow_file,
1657 &extra);
1658 commit_lock_file(&shallow_lock);
brian m. carlson23311f32019-02-04 00:06:50 +00001659 alternate_shallow_file = NULL;
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001660 }
brian m. carlson910650d2017-03-31 01:40:00 +00001661 oid_array_clear(&extra);
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001662 return;
1663 }
Nguyễn Thái Ngọc Duy4820a332013-12-05 20:02:40 +07001664
1665 if (!si->nr_ours && !si->nr_theirs)
1666 return;
1667
1668 remove_nonexistent_theirs_shallow(si);
Nguyễn Thái Ngọc Duy4820a332013-12-05 20:02:40 +07001669 if (!si->nr_ours && !si->nr_theirs)
1670 return;
Jonathan Tane2842b32018-08-01 13:13:20 -07001671 for (i = 0; i < nr_sought; i++)
1672 oid_array_append(&ref, &sought[i]->old_oid);
Nguyễn Thái Ngọc Duy4820a332013-12-05 20:02:40 +07001673 si->ref = &ref;
1674
Nguyễn Thái Ngọc Duy48d25ca2013-12-05 20:02:42 +07001675 if (args->update_shallow) {
1676 /*
1677 * remote is also shallow, .git/shallow may be updated
1678 * so all refs can be accepted. Make sure we only add
1679 * shallow roots that are actually reachable from new
1680 * refs.
1681 */
brian m. carlson910650d2017-03-31 01:40:00 +00001682 struct oid_array extra = OID_ARRAY_INIT;
brian m. carlsonee3051b2017-03-26 16:01:37 +00001683 struct object_id *oid = si->shallow->oid;
Nguyễn Thái Ngọc Duy48d25ca2013-12-05 20:02:42 +07001684 assign_shallow_commits_to_refs(si, NULL, NULL);
1685 if (!si->nr_ours && !si->nr_theirs) {
brian m. carlson910650d2017-03-31 01:40:00 +00001686 oid_array_clear(&ref);
Nguyễn Thái Ngọc Duy48d25ca2013-12-05 20:02:42 +07001687 return;
1688 }
1689 for (i = 0; i < si->nr_ours; i++)
brian m. carlson910650d2017-03-31 01:40:00 +00001690 oid_array_append(&extra, &oid[si->ours[i]]);
Nguyễn Thái Ngọc Duy48d25ca2013-12-05 20:02:42 +07001691 for (i = 0; i < si->nr_theirs; i++)
brian m. carlson910650d2017-03-31 01:40:00 +00001692 oid_array_append(&extra, &oid[si->theirs[i]]);
Nguyễn Thái Ngọc Duy48d25ca2013-12-05 20:02:42 +07001693 setup_alternate_shallow(&shallow_lock,
1694 &alternate_shallow_file,
1695 &extra);
1696 commit_lock_file(&shallow_lock);
brian m. carlson910650d2017-03-31 01:40:00 +00001697 oid_array_clear(&extra);
1698 oid_array_clear(&ref);
brian m. carlson23311f32019-02-04 00:06:50 +00001699 alternate_shallow_file = NULL;
Nguyễn Thái Ngọc Duy48d25ca2013-12-05 20:02:42 +07001700 return;
1701 }
1702
Nguyễn Thái Ngọc Duy4820a332013-12-05 20:02:40 +07001703 /*
1704 * remote is also shallow, check what ref is safe to update
1705 * without updating .git/shallow
1706 */
Jonathan Tane2842b32018-08-01 13:13:20 -07001707 status = xcalloc(nr_sought, sizeof(*status));
Nguyễn Thái Ngọc Duy4820a332013-12-05 20:02:40 +07001708 assign_shallow_commits_to_refs(si, NULL, status);
1709 if (si->nr_ours || si->nr_theirs) {
Jonathan Tane2842b32018-08-01 13:13:20 -07001710 for (i = 0; i < nr_sought; i++)
Nguyễn Thái Ngọc Duy4820a332013-12-05 20:02:40 +07001711 if (status[i])
Jonathan Tane2842b32018-08-01 13:13:20 -07001712 sought[i]->status = REF_STATUS_REJECT_SHALLOW;
Nguyễn Thái Ngọc Duy4820a332013-12-05 20:02:40 +07001713 }
1714 free(status);
brian m. carlson910650d2017-03-31 01:40:00 +00001715 oid_array_clear(&ref);
Nguyễn Thái Ngọc Duya796cce2013-12-05 20:02:37 +07001716}
1717
Jonathan Tancf1e7c02018-07-02 15:08:43 -07001718static int iterate_ref_map(void *cb_data, struct object_id *oid)
1719{
1720 struct ref **rm = cb_data;
1721 struct ref *ref = *rm;
1722
1723 if (!ref)
1724 return -1; /* end of the list */
1725 *rm = ref->next;
1726 oidcpy(oid, &ref->old_oid);
1727 return 0;
1728}
1729
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001730struct ref *fetch_pack(struct fetch_pack_args *args,
Jeff King0f804b02019-03-20 04:16:14 -04001731 int fd[],
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001732 const struct ref *ref,
Junio C Hamanof2db8542013-01-29 14:02:15 -08001733 struct ref **sought, int nr_sought,
brian m. carlson910650d2017-03-31 01:40:00 +00001734 struct oid_array *shallow,
Brandon Williams685fbd32018-03-15 10:31:28 -07001735 char **pack_lockfile,
1736 enum protocol_version version)
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001737{
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001738 struct ref *ref_cpy;
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001739 struct shallow_info si;
Jonathan Tan13390782019-03-26 12:31:21 -07001740 struct oid_array shallows_scratch = OID_ARRAY_INIT;
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001741
1742 fetch_pack_setup();
Junio C Hamanof2db8542013-01-29 14:02:15 -08001743 if (nr_sought)
1744 nr_sought = remove_duplicates_in_refs(sought, nr_sought);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001745
Jonathan Tan4c7f9562018-10-03 16:04:53 -07001746 if (args->no_dependents && !args->filter_options.choice) {
1747 /*
1748 * The protocol does not support requesting that only the
1749 * wanted objects be sent, so approximate this by setting a
1750 * "blob:none" filter if no filter is already set. This works
1751 * for all object types: note that wanted blobs will still be
1752 * sent because they are directly specified as a "want".
1753 *
1754 * NEEDSWORK: Add an option in the protocol to request that
1755 * only the wanted objects be sent, and implement it.
1756 */
1757 parse_list_objects_filter(&args->filter_options, "blob:none");
1758 }
1759
Jonathan Tan01775652018-09-27 12:24:05 -07001760 if (version != protocol_v2 && !ref) {
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001761 packet_flush(fd[1]);
Nguyễn Thái Ngọc Duy1dd73e22016-06-12 17:53:55 +07001762 die(_("no matching remote head"));
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001763 }
Jonathan Tan1e7d4402019-03-26 12:31:20 -07001764 if (version == protocol_v2) {
1765 if (shallow->nr)
1766 BUG("Protocol V2 does not provide shallows at this point in the fetch");
1767 memset(&si, 0, sizeof(si));
Brandon Williams685fbd32018-03-15 10:31:28 -07001768 ref_cpy = do_fetch_pack_v2(args, fd, ref, sought, nr_sought,
Jonathan Tan13390782019-03-26 12:31:21 -07001769 &shallows_scratch, &si,
Brandon Williams685fbd32018-03-15 10:31:28 -07001770 pack_lockfile);
Jonathan Tan1e7d4402019-03-26 12:31:20 -07001771 } else {
1772 prepare_shallow_info(&si, shallow);
Brandon Williams685fbd32018-03-15 10:31:28 -07001773 ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought,
1774 &si, pack_lockfile);
Jonathan Tan1e7d4402019-03-26 12:31:20 -07001775 }
Stefan Bellera49d2832018-03-23 18:45:21 +01001776 reprepare_packed_git(the_repository);
Jonathan Tancf1e7c02018-07-02 15:08:43 -07001777
1778 if (!args->cloning && args->deepen) {
1779 struct check_connected_options opt = CHECK_CONNECTED_INIT;
1780 struct ref *iterator = ref_cpy;
1781 opt.shallow_file = alternate_shallow_file;
1782 if (args->deepen)
1783 opt.is_deepening_fetch = 1;
1784 if (check_connected(iterate_ref_map, &iterator, &opt)) {
1785 error(_("remote did not send all necessary objects"));
1786 free_refs(ref_cpy);
1787 ref_cpy = NULL;
1788 rollback_lock_file(&shallow_lock);
1789 goto cleanup;
1790 }
1791 args->connectivity_checked = 1;
1792 }
1793
Jonathan Tane2842b32018-08-01 13:13:20 -07001794 update_shallow(args, sought, nr_sought, &si);
Jonathan Tancf1e7c02018-07-02 15:08:43 -07001795cleanup:
Nguyễn Thái Ngọc Duybeea4152013-12-05 20:02:39 +07001796 clear_shallow_info(&si);
Jonathan Tan13390782019-03-26 12:31:21 -07001797 oid_array_clear(&shallows_scratch);
Nguyễn Thái Ngọc Duy745f7a82012-10-26 22:53:55 +07001798 return ref_cpy;
1799}
Matt McCutchene860d962017-02-22 11:01:22 -05001800
1801int report_unmatched_refs(struct ref **sought, int nr_sought)
1802{
1803 int i, ret = 0;
1804
1805 for (i = 0; i < nr_sought; i++) {
Matt McCutchend56583d2017-02-22 11:05:57 -05001806 if (!sought[i])
Matt McCutchene860d962017-02-22 11:01:22 -05001807 continue;
Matt McCutchend56583d2017-02-22 11:05:57 -05001808 switch (sought[i]->match_status) {
1809 case REF_MATCHED:
1810 continue;
1811 case REF_NOT_MATCHED:
1812 error(_("no such remote ref %s"), sought[i]->name);
1813 break;
1814 case REF_UNADVERTISED_NOT_ALLOWED:
1815 error(_("Server does not allow request for unadvertised object %s"),
1816 sought[i]->name);
1817 break;
1818 }
Matt McCutchene860d962017-02-22 11:01:22 -05001819 ret = 1;
1820 }
1821 return ret;
1822}