send-pack: demultiplex a sideband stream with status data · msysgit/git@0c499ea

@@ -372,6 +372,14 @@ static void print_helper_status(struct ref *ref)

372372

strbuf_release(&buf);

373373

}

374374375+

static int sideband_demux(int in, int out, void *data)

376+

{

377+

int *fd = data;

378+

int ret = recv_sideband("send-pack", fd[0], out);

379+

close(out);

380+

return ret;

381+

}

382+375383

int send_pack(struct send_pack_args *args,

376384

int fd[], struct child_process *conn,

377385

struct ref *remote_refs,

@@ -382,18 +390,22 @@ int send_pack(struct send_pack_args *args,

382390

struct strbuf req_buf = STRBUF_INIT;

383391

struct ref *ref;

384392

int new_refs;

385-

int ask_for_status_report = 0;

386393

int allow_deleting_refs = 0;

387-

int expect_status_report = 0;

394+

int status_report = 0;

395+

int use_sideband = 0;

396+

unsigned cmds_sent = 0;

388397

int ret;

398+

struct async demux;

389399390400

/* Does the other end support the reporting? */

391401

if (server_supports("report-status"))

392-

ask_for_status_report = 1;

402+

status_report = 1;

393403

if (server_supports("delete-refs"))

394404

allow_deleting_refs = 1;

395405

if (server_supports("ofs-delta"))

396406

args->use_ofs_delta = 1;

407+

if (server_supports("side-band-64k"))

408+

use_sideband = 1;

397409398410

if (!remote_refs) {

399411

fprintf(stderr, "No refs in common and none specified; doing nothing.\n"

@@ -456,28 +468,30 @@ int send_pack(struct send_pack_args *args,

456468

if (!ref->deletion)

457469

new_refs++;

458470459-

if (!args->dry_run) {

471+

if (args->dry_run) {

472+

ref->status = REF_STATUS_OK;

473+

} else {

460474

char *old_hex = sha1_to_hex(ref->old_sha1);

461475

char *new_hex = sha1_to_hex(ref->new_sha1);

462476463-

if (ask_for_status_report) {

464-

packet_buf_write(&req_buf, "%s %s %s%c%s",

477+

if (!cmds_sent && (status_report || use_sideband)) {

478+

packet_buf_write(&req_buf, "%s %s %s%c%s%s",

465479

old_hex, new_hex, ref->name, 0,

466-

"report-status");

467-

ask_for_status_report = 0;

468-

expect_status_report = 1;

480+

status_report ? " report-status" : "",

481+

use_sideband ? " side-band-64k" : "");

469482

}

470483

else

471484

packet_buf_write(&req_buf, "%s %s %s",

472485

old_hex, new_hex, ref->name);

486+

ref->status = status_report ?

487+

REF_STATUS_EXPECTING_REPORT :

488+

REF_STATUS_OK;

489+

cmds_sent++;

473490

}

474-

ref->status = expect_status_report ?

475-

REF_STATUS_EXPECTING_REPORT :

476-

REF_STATUS_OK;

477491

}

478492479493

if (args->stateless_rpc) {

480-

if (!args->dry_run) {

494+

if (!args->dry_run && cmds_sent) {

481495

packet_buf_flush(&req_buf);

482496

send_sideband(out, -1, req_buf.buf, req_buf.len, LARGE_PACKET_MAX);

483497

}

@@ -487,23 +501,43 @@ int send_pack(struct send_pack_args *args,

487501

}

488502

strbuf_release(&req_buf);

489503490-

if (new_refs && !args->dry_run) {

504+

if (use_sideband && cmds_sent) {

505+

memset(&demux, 0, sizeof(demux));

506+

demux.proc = sideband_demux;

507+

demux.data = fd;

508+

demux.out = -1;

509+

if (start_async(&demux))

510+

die("receive-pack: unable to fork off sideband demultiplexer");

511+

in = demux.out;

512+

}

513+514+

if (new_refs && cmds_sent) {

491515

if (pack_objects(out, remote_refs, extra_have, args) < 0) {

492516

for (ref = remote_refs; ref; ref = ref->next)

493517

ref->status = REF_STATUS_NONE;

518+

if (use_sideband)

519+

finish_async(&demux);

494520

return -1;

495521

}

496522

}

497-

if (args->stateless_rpc && !args->dry_run)

523+

if (args->stateless_rpc && cmds_sent)

498524

packet_flush(out);

499525500-

if (expect_status_report)

526+

if (status_report && cmds_sent)

501527

ret = receive_status(in, remote_refs);

502528

else

503529

ret = 0;

504530

if (args->stateless_rpc)

505531

packet_flush(out);

506532533+

if (use_sideband && cmds_sent) {

534+

if (finish_async(&demux)) {

535+

error("error in sideband demultiplexer");

536+

ret = -1;

537+

}

538+

close(demux.out);

539+

}

540+507541

if (ret < 0)

508542

return ret;

509543

for (ref = remote_refs; ref; ref = ref->next) {