Skip to content

Commit 0bbc0bc

Browse files
jonathantanmygitster
authored andcommitted
{fetch,upload}-pack: sideband v2 fetch response
Currently, a response to a fetch request has sideband support only while the packfile is being sent, meaning that the server cannot send notices until the start of the packfile. Extend sideband support in protocol v2 fetch responses to the whole response. upload-pack will advertise it if the uploadpack.allowsidebandall configuration variable is set, and fetch-pack will automatically request it if advertised. If the sideband is to be used throughout the whole response, upload-pack will use it to send errors instead of prefixing a PKT-LINE payload with "ERR ". This will be tested in a subsequent patch. Signed-off-by: Jonathan Tan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent fbd76cd commit 0bbc0bc

File tree

7 files changed

+78
-13
lines changed

7 files changed

+78
-13
lines changed

Documentation/technical/protocol-v2.txt

+10
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,16 @@ the 'wanted-refs' section in the server's response as explained below.
307307
particular ref, where <ref> is the full name of a ref on the
308308
server.
309309

310+
If the 'sideband-all' feature is advertised, the following argument can be
311+
included in the client's request:
312+
313+
sideband-all
314+
Instruct the server to send the whole response multiplexed, not just
315+
the packfile section. All non-flush and non-delim PKT-LINE in the
316+
response (not only in the packfile section) will then start with a byte
317+
indicating its sideband (1, 2, or 3), and the server may send "0005\2"
318+
(a PKT-LINE of sideband 2 with no payload) as a keepalive packet.
319+
310320
The response of `fetch` is broken into a number of sections separated by
311321
delimiter packets (0001), with each section beginning with its section
312322
header.

fetch-pack.c

+10-2
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,8 @@ static int add_haves(struct fetch_negotiator *negotiator,
10901090
static int send_fetch_request(struct fetch_negotiator *negotiator, int fd_out,
10911091
const struct fetch_pack_args *args,
10921092
const struct ref *wants, struct oidset *common,
1093-
int *haves_to_send, int *in_vain)
1093+
int *haves_to_send, int *in_vain,
1094+
int sideband_all)
10941095
{
10951096
int ret = 0;
10961097
struct strbuf req_buf = STRBUF_INIT;
@@ -1116,6 +1117,8 @@ static int send_fetch_request(struct fetch_negotiator *negotiator, int fd_out,
11161117
packet_buf_write(&req_buf, "include-tag");
11171118
if (prefer_ofs_delta)
11181119
packet_buf_write(&req_buf, "ofs-delta");
1120+
if (sideband_all)
1121+
packet_buf_write(&req_buf, "sideband-all");
11191122

11201123
/* Add shallow-info and deepen request */
11211124
if (server_supports_feature("fetch", "shallow", 0))
@@ -1324,6 +1327,10 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
13241327
packet_reader_init(&reader, fd[0], NULL, 0,
13251328
PACKET_READ_CHOMP_NEWLINE |
13261329
PACKET_READ_DIE_ON_ERR_PACKET);
1330+
if (server_supports_feature("fetch", "sideband-all", 0)) {
1331+
reader.use_sideband = 1;
1332+
reader.me = "fetch-pack";
1333+
}
13271334

13281335
while (state != FETCH_DONE) {
13291336
switch (state) {
@@ -1357,7 +1364,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
13571364
case FETCH_SEND_REQUEST:
13581365
if (send_fetch_request(&negotiator, fd[1], args, ref,
13591366
&common,
1360-
&haves_to_send, &in_vain))
1367+
&haves_to_send, &in_vain,
1368+
reader.use_sideband))
13611369
state = FETCH_GET_PACK;
13621370
else
13631371
state = FETCH_PROCESS_ACKS;

pkt-line.c

+32-11
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ int recv_sideband(const char *me, int in_stream, int out)
449449
while (1) {
450450
len = packet_read(in_stream, NULL, NULL, buf, LARGE_PACKET_MAX,
451451
0);
452-
if (!demultiplex_sideband(me, buf, len, &scratch,
452+
if (!demultiplex_sideband(me, buf, len, 0, &scratch,
453453
&sideband_type))
454454
continue;
455455
switch (sideband_type) {
@@ -475,25 +475,43 @@ void packet_reader_init(struct packet_reader *reader, int fd,
475475
reader->buffer = packet_buffer;
476476
reader->buffer_size = sizeof(packet_buffer);
477477
reader->options = options;
478+
reader->me = "git";
478479
}
479480

480481
enum packet_read_status packet_reader_read(struct packet_reader *reader)
481482
{
483+
struct strbuf scratch = STRBUF_INIT;
484+
482485
if (reader->line_peeked) {
483486
reader->line_peeked = 0;
484487
return reader->status;
485488
}
486489

487-
reader->status = packet_read_with_status(reader->fd,
488-
&reader->src_buffer,
489-
&reader->src_len,
490-
reader->buffer,
491-
reader->buffer_size,
492-
&reader->pktlen,
493-
reader->options);
490+
/*
491+
* Consume all progress packets until a primary payload packet is
492+
* received
493+
*/
494+
while (1) {
495+
enum sideband_type sideband_type;
496+
reader->status = packet_read_with_status(reader->fd,
497+
&reader->src_buffer,
498+
&reader->src_len,
499+
reader->buffer,
500+
reader->buffer_size,
501+
&reader->pktlen,
502+
reader->options);
503+
if (!reader->use_sideband)
504+
break;
505+
if (demultiplex_sideband(reader->me, reader->buffer,
506+
reader->pktlen, 1, &scratch,
507+
&sideband_type))
508+
break;
509+
}
494510

495511
if (reader->status == PACKET_READ_NORMAL)
496-
reader->line = reader->buffer;
512+
/* Skip the sideband designator if sideband is used */
513+
reader->line = reader->use_sideband ?
514+
reader->buffer + 1 : reader->buffer;
497515
else
498516
reader->line = NULL;
499517

@@ -515,14 +533,16 @@ enum packet_read_status packet_reader_peek(struct packet_reader *reader)
515533
void packet_writer_init(struct packet_writer *writer, int dest_fd)
516534
{
517535
writer->dest_fd = dest_fd;
536+
writer->use_sideband = 0;
518537
}
519538

520539
void packet_writer_write(struct packet_writer *writer, const char *fmt, ...)
521540
{
522541
va_list args;
523542

524543
va_start(args, fmt);
525-
packet_write_fmt_1(writer->dest_fd, 0, "", fmt, args);
544+
packet_write_fmt_1(writer->dest_fd, 0,
545+
writer->use_sideband ? "\001" : "", fmt, args);
526546
va_end(args);
527547
}
528548

@@ -531,7 +551,8 @@ void packet_writer_error(struct packet_writer *writer, const char *fmt, ...)
531551
va_list args;
532552

533553
va_start(args, fmt);
534-
packet_write_fmt_1(writer->dest_fd, 0, "ERR ", fmt, args);
554+
packet_write_fmt_1(writer->dest_fd, 0,
555+
writer->use_sideband ? "\003" : "ERR ", fmt, args);
535556
va_end(args);
536557
}
537558

pkt-line.h

+4
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ struct packet_reader {
162162

163163
/* indicates if a line has been peeked */
164164
int line_peeked;
165+
166+
unsigned use_sideband : 1;
167+
const char *me;
165168
};
166169

167170
/*
@@ -201,6 +204,7 @@ extern char packet_buffer[LARGE_PACKET_MAX];
201204

202205
struct packet_writer {
203206
int dest_fd;
207+
unsigned use_sideband : 1;
204208
};
205209

206210
void packet_writer_init(struct packet_writer *writer, int dest_fd);

sideband.c

+5
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n)
114114
#define DUMB_SUFFIX " "
115115

116116
int demultiplex_sideband(const char *me, char *buf, int len,
117+
int die_on_error,
117118
struct strbuf *scratch,
118119
enum sideband_type *sideband_type)
119120
{
@@ -144,6 +145,8 @@ int demultiplex_sideband(const char *me, char *buf, int len,
144145
len--;
145146
switch (band) {
146147
case 3:
148+
if (die_on_error)
149+
die("remote error: %s", buf + 1);
147150
strbuf_addf(scratch, "%s%s", scratch->len ? "\n" : "",
148151
DISPLAY_PREFIX);
149152
maybe_colorize_sideband(scratch, buf + 1, len);
@@ -195,6 +198,8 @@ int demultiplex_sideband(const char *me, char *buf, int len,
195198
}
196199

197200
cleanup:
201+
if (die_on_error && *sideband_type == SIDEBAND_PROTOCOL_ERROR)
202+
die("%s", scratch->buf);
198203
if (scratch->len) {
199204
strbuf_addch(scratch, '\n');
200205
xwrite(2, scratch->buf, scratch->len);

sideband.h

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ enum sideband_type {
2020
* progress messages split across multiple packets.
2121
*/
2222
int demultiplex_sideband(const char *me, char *buf, int len,
23+
int die_on_error,
2324
struct strbuf *scratch,
2425
enum sideband_type *sideband_type);
2526

upload-pack.c

+16
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ static int allow_filter;
7171
static int allow_ref_in_want;
7272
static struct list_objects_filter_options filter_options;
7373

74+
static int allow_sideband_all;
75+
7476
static void reset_timeout(void)
7577
{
7678
alarm(timeout);
@@ -1046,6 +1048,8 @@ static int upload_pack_config(const char *var, const char *value, void *unused)
10461048
allow_filter = git_config_bool(var, value);
10471049
} else if (!strcmp("uploadpack.allowrefinwant", var)) {
10481050
allow_ref_in_want = git_config_bool(var, value);
1051+
} else if (!strcmp("uploadpack.allowsidebandall", var)) {
1052+
allow_sideband_all = git_config_bool(var, value);
10491053
}
10501054

10511055
if (current_config_scope() != CONFIG_SCOPE_REPO) {
@@ -1284,6 +1288,11 @@ static void process_args(struct packet_reader *request,
12841288
continue;
12851289
}
12861290

1291+
if (allow_sideband_all && !strcmp(arg, "sideband-all")) {
1292+
data->writer.use_sideband = 1;
1293+
continue;
1294+
}
1295+
12871296
/* ignore unknown lines maybe? */
12881297
die("unexpected line: '%s'", arg);
12891298
}
@@ -1496,6 +1505,7 @@ int upload_pack_advertise(struct repository *r,
14961505
if (value) {
14971506
int allow_filter_value;
14981507
int allow_ref_in_want;
1508+
int allow_sideband_all_value;
14991509

15001510
strbuf_addstr(value, "shallow");
15011511

@@ -1510,6 +1520,12 @@ int upload_pack_advertise(struct repository *r,
15101520
&allow_ref_in_want) &&
15111521
allow_ref_in_want)
15121522
strbuf_addstr(value, " ref-in-want");
1523+
1524+
if (!repo_config_get_bool(the_repository,
1525+
"uploadpack.allowsidebandall",
1526+
&allow_sideband_all_value) &&
1527+
allow_sideband_all_value)
1528+
strbuf_addstr(value, " sideband-all");
15131529
}
15141530

15151531
return 1;

0 commit comments

Comments
 (0)