Git fork
at reftables-rust 1674 lines 44 kB view raw
1#define USE_THE_REPOSITORY_VARIABLE 2 3#include "git-compat-util.h" 4#include "transport.h" 5#include "quote.h" 6#include "run-command.h" 7#include "commit.h" 8#include "environment.h" 9#include "gettext.h" 10#include "hex.h" 11#include "object-name.h" 12#include "repository.h" 13#include "remote.h" 14#include "string-list.h" 15#include "thread-utils.h" 16#include "sigchain.h" 17#include "strvec.h" 18#include "refs.h" 19#include "refspec.h" 20#include "transport-internal.h" 21#include "protocol.h" 22#include "packfile.h" 23 24static int debug; 25 26struct helper_data { 27 char *name; 28 struct child_process *helper; 29 FILE *out; 30 unsigned fetch : 1, 31 import : 1, 32 bidi_import : 1, 33 export : 1, 34 option : 1, 35 push : 1, 36 connect : 1, 37 stateless_connect : 1, 38 signed_tags : 1, 39 check_connectivity : 1, 40 no_disconnect_req : 1, 41 no_private_update : 1, 42 object_format : 1; 43 44 /* 45 * As an optimization, the transport code may invoke fetch before 46 * get_refs_list. If this happens, and if the transport helper doesn't 47 * support connect or stateless_connect, we need to invoke 48 * get_refs_list ourselves if we haven't already done so. Keep track of 49 * whether we have invoked get_refs_list. 50 */ 51 unsigned get_refs_list_called : 1; 52 53 char *export_marks; 54 char *import_marks; 55 /* These go from remote name (as in "list") to private name */ 56 struct refspec rs; 57 /* Transport options for fetch-pack/send-pack (should one of 58 * those be invoked). 59 */ 60 struct git_transport_options transport_options; 61}; 62 63static void sendline(struct helper_data *helper, struct strbuf *buffer) 64{ 65 if (debug) 66 fprintf(stderr, "Debug: Remote helper: -> %s", buffer->buf); 67 if (write_in_full(helper->helper->in, buffer->buf, buffer->len) < 0) 68 die_errno(_("full write to remote helper failed")); 69} 70 71static int recvline_fh(FILE *helper, struct strbuf *buffer) 72{ 73 strbuf_reset(buffer); 74 if (debug) 75 fprintf(stderr, "Debug: Remote helper: Waiting...\n"); 76 if (strbuf_getline(buffer, helper) == EOF) { 77 if (debug) 78 fprintf(stderr, "Debug: Remote helper quit.\n"); 79 return 1; 80 } 81 82 if (debug) 83 fprintf(stderr, "Debug: Remote helper: <- %s\n", buffer->buf); 84 return 0; 85} 86 87static int recvline(struct helper_data *helper, struct strbuf *buffer) 88{ 89 return recvline_fh(helper->out, buffer); 90} 91 92static int write_constant_gently(int fd, const char *str) 93{ 94 if (debug) 95 fprintf(stderr, "Debug: Remote helper: -> %s", str); 96 if (write_in_full(fd, str, strlen(str)) < 0) 97 return -1; 98 return 0; 99} 100 101static void write_constant(int fd, const char *str) 102{ 103 if (write_constant_gently(fd, str) < 0) 104 die_errno(_("full write to remote helper failed")); 105} 106 107static const char *remove_ext_force(const char *url) 108{ 109 if (url) { 110 const char *colon = strchr(url, ':'); 111 if (colon && colon[1] == ':') 112 return colon + 2; 113 } 114 return url; 115} 116 117static void do_take_over(struct transport *transport) 118{ 119 struct helper_data *data; 120 data = (struct helper_data *)transport->data; 121 transport_take_over(transport, data->helper); 122 fclose(data->out); 123 free(data->name); 124 free(data); 125} 126 127static void standard_options(struct transport *t); 128 129static struct child_process *get_helper(struct transport *transport) 130{ 131 struct helper_data *data = transport->data; 132 struct strbuf buf = STRBUF_INIT; 133 struct child_process *helper; 134 int duped; 135 int code; 136 137 if (data->helper) 138 return data->helper; 139 140 helper = xmalloc(sizeof(*helper)); 141 child_process_init(helper); 142 helper->in = -1; 143 helper->out = -1; 144 helper->err = 0; 145 strvec_pushf(&helper->args, "remote-%s", data->name); 146 strvec_push(&helper->args, transport->remote->name); 147 strvec_push(&helper->args, remove_ext_force(transport->url)); 148 helper->git_cmd = 1; 149 helper->silent_exec_failure = 1; 150 151 if (have_git_dir()) 152 strvec_pushf(&helper->env, "%s=%s", 153 GIT_DIR_ENVIRONMENT, repo_get_git_dir(the_repository)); 154 155 helper->trace2_child_class = helper->args.v[0]; /* "remote-<name>" */ 156 157 code = start_command(helper); 158 if (code < 0 && errno == ENOENT) 159 die(_("unable to find remote helper for '%s'"), data->name); 160 else if (code != 0) 161 exit(code); 162 163 data->helper = helper; 164 data->no_disconnect_req = 0; 165 refspec_init_fetch(&data->rs); 166 167 /* 168 * Open the output as FILE* so strbuf_getline_*() family of 169 * functions can be used. 170 * Do this with duped fd because fclose() will close the fd, 171 * and stuff like taking over will require the fd to remain. 172 */ 173 duped = dup(helper->out); 174 if (duped < 0) 175 die_errno(_("can't dup helper output fd")); 176 data->out = xfdopen(duped, "r"); 177 178 sigchain_push(SIGPIPE, SIG_IGN); 179 if (write_constant_gently(helper->in, "capabilities\n") < 0) 180 die("remote helper '%s' aborted session", data->name); 181 sigchain_pop(SIGPIPE); 182 183 while (1) { 184 const char *capname, *arg; 185 int mandatory = 0; 186 if (recvline(data, &buf)) 187 die("remote helper '%s' aborted session", data->name); 188 189 if (!*buf.buf) 190 break; 191 192 if (*buf.buf == '*') { 193 capname = buf.buf + 1; 194 mandatory = 1; 195 } else 196 capname = buf.buf; 197 198 if (debug) 199 fprintf(stderr, "Debug: Got cap %s\n", capname); 200 if (!strcmp(capname, "fetch")) 201 data->fetch = 1; 202 else if (!strcmp(capname, "option")) 203 data->option = 1; 204 else if (!strcmp(capname, "push")) 205 data->push = 1; 206 else if (!strcmp(capname, "import")) 207 data->import = 1; 208 else if (!strcmp(capname, "bidi-import")) 209 data->bidi_import = 1; 210 else if (!strcmp(capname, "export")) 211 data->export = 1; 212 else if (!strcmp(capname, "check-connectivity")) 213 data->check_connectivity = 1; 214 else if (skip_prefix(capname, "refspec ", &arg)) { 215 refspec_append(&data->rs, arg); 216 } else if (!strcmp(capname, "connect")) { 217 data->connect = 1; 218 } else if (!strcmp(capname, "stateless-connect")) { 219 data->stateless_connect = 1; 220 } else if (!strcmp(capname, "signed-tags")) { 221 data->signed_tags = 1; 222 } else if (skip_prefix(capname, "export-marks ", &arg)) { 223 data->export_marks = xstrdup(arg); 224 } else if (skip_prefix(capname, "import-marks ", &arg)) { 225 data->import_marks = xstrdup(arg); 226 } else if (starts_with(capname, "no-private-update")) { 227 data->no_private_update = 1; 228 } else if (starts_with(capname, "object-format")) { 229 data->object_format = 1; 230 } else if (mandatory) { 231 die(_("unknown mandatory capability %s; this remote " 232 "helper probably needs newer version of Git"), 233 capname); 234 } 235 } 236 if (!data->rs.nr && (data->import || data->bidi_import || data->export)) { 237 warning(_("this remote helper should implement refspec capability")); 238 } 239 strbuf_release(&buf); 240 if (debug) 241 fprintf(stderr, "Debug: Capabilities complete.\n"); 242 standard_options(transport); 243 return data->helper; 244} 245 246static int disconnect_helper(struct transport *transport) 247{ 248 struct helper_data *data = transport->data; 249 int res = 0; 250 251 if (data->helper) { 252 if (debug) 253 fprintf(stderr, "Debug: Disconnecting.\n"); 254 if (!data->no_disconnect_req) { 255 /* 256 * Ignore write errors; there's nothing we can do, 257 * since we're about to close the pipe anyway. And the 258 * most likely error is EPIPE due to the helper dying 259 * to report an error itself. 260 */ 261 sigchain_push(SIGPIPE, SIG_IGN); 262 xwrite(data->helper->in, "\n", 1); 263 sigchain_pop(SIGPIPE); 264 } 265 close(data->helper->in); 266 close(data->helper->out); 267 fclose(data->out); 268 res = finish_command(data->helper); 269 FREE_AND_NULL(data->name); 270 FREE_AND_NULL(data->helper); 271 } 272 return res; 273} 274 275static const char *unsupported_options[] = { 276 TRANS_OPT_UPLOADPACK, 277 TRANS_OPT_RECEIVEPACK, 278 TRANS_OPT_THIN, 279 TRANS_OPT_KEEP 280 }; 281 282static const char *boolean_options[] = { 283 TRANS_OPT_THIN, 284 TRANS_OPT_KEEP, 285 TRANS_OPT_FOLLOWTAGS, 286 TRANS_OPT_DEEPEN_RELATIVE 287 }; 288 289static int strbuf_set_helper_option(struct helper_data *data, 290 struct strbuf *buf) 291{ 292 int ret; 293 294 sendline(data, buf); 295 if (recvline(data, buf)) 296 exit(128); 297 298 if (!strcmp(buf->buf, "ok")) 299 ret = 0; 300 else if (starts_with(buf->buf, "error")) 301 ret = -1; 302 else if (!strcmp(buf->buf, "unsupported")) 303 ret = 1; 304 else { 305 warning(_("%s unexpectedly said: '%s'"), data->name, buf->buf); 306 ret = 1; 307 } 308 return ret; 309} 310 311static int string_list_set_helper_option(struct helper_data *data, 312 const char *name, 313 struct string_list *list) 314{ 315 struct strbuf buf = STRBUF_INIT; 316 int ret = 0; 317 318 for (size_t i = 0; i < list->nr; i++) { 319 strbuf_addf(&buf, "option %s ", name); 320 quote_c_style(list->items[i].string, &buf, NULL, 0); 321 strbuf_addch(&buf, '\n'); 322 323 if ((ret = strbuf_set_helper_option(data, &buf))) 324 break; 325 strbuf_reset(&buf); 326 } 327 strbuf_release(&buf); 328 return ret; 329} 330 331static int set_helper_option(struct transport *transport, 332 const char *name, const char *value) 333{ 334 struct helper_data *data = transport->data; 335 struct strbuf buf = STRBUF_INIT; 336 int ret, is_bool = 0; 337 338 get_helper(transport); 339 340 if (!data->option) 341 return 1; 342 343 if (!strcmp(name, "deepen-not")) 344 return string_list_set_helper_option(data, name, 345 (struct string_list *)value); 346 347 for (size_t i = 0; i < ARRAY_SIZE(unsupported_options); i++) { 348 if (!strcmp(name, unsupported_options[i])) 349 return 1; 350 } 351 352 for (size_t i = 0; i < ARRAY_SIZE(boolean_options); i++) { 353 if (!strcmp(name, boolean_options[i])) { 354 is_bool = 1; 355 break; 356 } 357 } 358 359 strbuf_addf(&buf, "option %s ", name); 360 if (is_bool) 361 strbuf_addstr(&buf, value ? "true" : "false"); 362 else 363 quote_c_style(value, &buf, NULL, 0); 364 strbuf_addch(&buf, '\n'); 365 366 ret = strbuf_set_helper_option(data, &buf); 367 strbuf_release(&buf); 368 return ret; 369} 370 371static void standard_options(struct transport *t) 372{ 373 char buf[16]; 374 int v = t->verbose; 375 376 set_helper_option(t, "progress", t->progress ? "true" : "false"); 377 378 xsnprintf(buf, sizeof(buf), "%d", v + 1); 379 set_helper_option(t, "verbosity", buf); 380 381 switch (t->family) { 382 case TRANSPORT_FAMILY_ALL: 383 /* 384 * this is already the default, 385 * do not break old remote helpers by setting "all" here 386 */ 387 break; 388 case TRANSPORT_FAMILY_IPV4: 389 set_helper_option(t, "family", "ipv4"); 390 break; 391 case TRANSPORT_FAMILY_IPV6: 392 set_helper_option(t, "family", "ipv6"); 393 break; 394 } 395} 396 397static int release_helper(struct transport *transport) 398{ 399 int res = 0; 400 struct helper_data *data = transport->data; 401 refspec_clear(&data->rs); 402 free(data->import_marks); 403 free(data->export_marks); 404 res = disconnect_helper(transport); 405 free(transport->data); 406 return res; 407} 408 409static int fetch_with_fetch(struct transport *transport, 410 int nr_heads, struct ref **to_fetch) 411{ 412 struct helper_data *data = transport->data; 413 int i; 414 struct strbuf buf = STRBUF_INIT; 415 416 for (i = 0; i < nr_heads; i++) { 417 const struct ref *posn = to_fetch[i]; 418 if (posn->status & REF_STATUS_UPTODATE) 419 continue; 420 421 strbuf_addf(&buf, "fetch %s %s\n", 422 oid_to_hex(&posn->old_oid), 423 posn->symref ? posn->symref : posn->name); 424 } 425 426 strbuf_addch(&buf, '\n'); 427 sendline(data, &buf); 428 429 while (1) { 430 const char *name; 431 432 if (recvline(data, &buf)) 433 exit(128); 434 435 if (skip_prefix(buf.buf, "lock ", &name)) { 436 if (transport->pack_lockfiles.nr) 437 warning(_("%s also locked %s"), data->name, name); 438 else 439 string_list_append(&transport->pack_lockfiles, 440 name); 441 } 442 else if (data->check_connectivity && 443 data->transport_options.check_self_contained_and_connected && 444 !strcmp(buf.buf, "connectivity-ok")) 445 data->transport_options.self_contained_and_connected = 1; 446 else if (!buf.len) 447 break; 448 else 449 warning(_("%s unexpectedly said: '%s'"), data->name, buf.buf); 450 } 451 strbuf_release(&buf); 452 453 odb_reprepare(the_repository->objects); 454 return 0; 455} 456 457static int get_importer(struct transport *transport, struct child_process *fastimport) 458{ 459 struct child_process *helper = get_helper(transport); 460 struct helper_data *data = transport->data; 461 int cat_blob_fd, code; 462 child_process_init(fastimport); 463 fastimport->in = xdup(helper->out); 464 strvec_push(&fastimport->args, "fast-import"); 465 strvec_push(&fastimport->args, "--allow-unsafe-features"); 466 strvec_push(&fastimport->args, debug ? "--stats" : "--quiet"); 467 468 if (data->bidi_import) { 469 cat_blob_fd = xdup(helper->in); 470 strvec_pushf(&fastimport->args, "--cat-blob-fd=%d", cat_blob_fd); 471 } 472 fastimport->git_cmd = 1; 473 474 code = start_command(fastimport); 475 return code; 476} 477 478static int get_exporter(struct transport *transport, 479 struct child_process *fastexport, 480 struct string_list *revlist_args) 481{ 482 struct helper_data *data = transport->data; 483 struct child_process *helper = get_helper(transport); 484 485 child_process_init(fastexport); 486 487 /* we need to duplicate helper->in because we want to use it after 488 * fastexport is done with it. */ 489 fastexport->out = dup(helper->in); 490 strvec_push(&fastexport->args, "fast-export"); 491 strvec_push(&fastexport->args, "--use-done-feature"); 492 strvec_push(&fastexport->args, data->signed_tags ? 493 "--signed-tags=verbatim" : "--signed-tags=warn-strip"); 494 if (data->export_marks) 495 strvec_pushf(&fastexport->args, "--export-marks=%s.tmp", data->export_marks); 496 if (data->import_marks) 497 strvec_pushf(&fastexport->args, "--import-marks=%s", data->import_marks); 498 499 for (size_t i = 0; i < revlist_args->nr; i++) 500 strvec_push(&fastexport->args, revlist_args->items[i].string); 501 502 fastexport->git_cmd = 1; 503 return start_command(fastexport); 504} 505 506static int fetch_with_import(struct transport *transport, 507 int nr_heads, struct ref **to_fetch) 508{ 509 struct child_process fastimport; 510 struct helper_data *data = transport->data; 511 int i; 512 struct ref *posn; 513 struct strbuf buf = STRBUF_INIT; 514 515 get_helper(transport); 516 517 if (get_importer(transport, &fastimport)) 518 die(_("couldn't run fast-import")); 519 520 for (i = 0; i < nr_heads; i++) { 521 posn = to_fetch[i]; 522 if (posn->status & REF_STATUS_UPTODATE) 523 continue; 524 525 strbuf_addf(&buf, "import %s\n", 526 posn->symref ? posn->symref : posn->name); 527 sendline(data, &buf); 528 strbuf_reset(&buf); 529 } 530 531 write_constant(data->helper->in, "\n"); 532 /* 533 * remote-helpers that advertise the bidi-import capability are required to 534 * buffer the complete batch of import commands until this newline before 535 * sending data to fast-import. 536 * These helpers read back data from fast-import on their stdin, which could 537 * be mixed with import commands, otherwise. 538 */ 539 540 if (finish_command(&fastimport)) 541 die(_("error while running fast-import")); 542 543 /* 544 * The fast-import stream of a remote helper that advertises 545 * the "refspec" capability writes to the refs named after the 546 * right hand side of the first refspec matching each ref we 547 * were fetching. 548 * 549 * (If no "refspec" capability was specified, for historical 550 * reasons we default to the equivalent of *:*.) 551 * 552 * Store the result in to_fetch[i].old_sha1. Callers such 553 * as "git fetch" can use the value to write feedback to the 554 * terminal, populate FETCH_HEAD, and determine what new value 555 * should be written to peer_ref if the update is a 556 * fast-forward or this is a forced update. 557 */ 558 for (i = 0; i < nr_heads; i++) { 559 char *private, *name; 560 posn = to_fetch[i]; 561 if (posn->status & REF_STATUS_UPTODATE) 562 continue; 563 name = posn->symref ? posn->symref : posn->name; 564 if (data->rs.nr) 565 private = apply_refspecs(&data->rs, name); 566 else 567 private = xstrdup(name); 568 if (private) { 569 if (refs_read_ref(get_main_ref_store(the_repository), private, &posn->old_oid) < 0) 570 die(_("could not read ref %s"), private); 571 free(private); 572 } 573 } 574 strbuf_release(&buf); 575 return 0; 576} 577 578static int run_connect(struct transport *transport, struct strbuf *cmdbuf) 579{ 580 struct helper_data *data = transport->data; 581 int ret = 0; 582 int duped; 583 FILE *input; 584 struct child_process *helper; 585 586 helper = get_helper(transport); 587 588 /* 589 * Yes, dup the pipe another time, as we need unbuffered version 590 * of input pipe as FILE*. fclose() closes the underlying fd and 591 * stream buffering only can be changed before first I/O operation 592 * on it. 593 */ 594 duped = dup(helper->out); 595 if (duped < 0) 596 die_errno(_("can't dup helper output fd")); 597 input = xfdopen(duped, "r"); 598 setvbuf(input, NULL, _IONBF, 0); 599 600 sendline(data, cmdbuf); 601 if (recvline_fh(input, cmdbuf)) 602 exit(128); 603 604 if (!strcmp(cmdbuf->buf, "")) { 605 data->no_disconnect_req = 1; 606 if (debug) 607 fprintf(stderr, "Debug: Smart transport connection " 608 "ready.\n"); 609 ret = 1; 610 } else if (!strcmp(cmdbuf->buf, "fallback")) { 611 if (debug) 612 fprintf(stderr, "Debug: Falling back to dumb " 613 "transport.\n"); 614 } else { 615 die(_("unknown response to connect: %s"), 616 cmdbuf->buf); 617 } 618 619 fclose(input); 620 return ret; 621} 622 623static int process_connect_service(struct transport *transport, 624 const char *name, const char *exec) 625{ 626 struct helper_data *data = transport->data; 627 struct strbuf cmdbuf = STRBUF_INIT; 628 int ret = 0; 629 630 /* 631 * Handle --upload-pack and friends. This is fire and forget... 632 * just warn if it fails. 633 */ 634 if (strcmp(name, exec)) { 635 int r = set_helper_option(transport, "servpath", exec); 636 if (r > 0) 637 warning(_("setting remote service path not supported by protocol")); 638 else if (r < 0) 639 warning(_("invalid remote service path")); 640 } 641 642 if (data->connect) { 643 strbuf_addf(&cmdbuf, "connect %s\n", name); 644 ret = run_connect(transport, &cmdbuf); 645 } else if (data->stateless_connect && 646 (get_protocol_version_config() == protocol_v2) && 647 (!strcmp("git-upload-pack", name) || 648 !strcmp("git-upload-archive", name))) { 649 strbuf_addf(&cmdbuf, "stateless-connect %s\n", name); 650 ret = run_connect(transport, &cmdbuf); 651 if (ret) 652 transport->stateless_rpc = 1; 653 } 654 655 strbuf_release(&cmdbuf); 656 return ret; 657} 658 659static int process_connect(struct transport *transport, 660 int for_push) 661{ 662 struct helper_data *data = transport->data; 663 const char *name; 664 const char *exec; 665 int ret; 666 667 name = for_push ? "git-receive-pack" : "git-upload-pack"; 668 if (for_push) 669 exec = data->transport_options.receivepack; 670 else 671 exec = data->transport_options.uploadpack; 672 673 ret = process_connect_service(transport, name, exec); 674 if (ret) 675 do_take_over(transport); 676 return ret; 677} 678 679static int connect_helper(struct transport *transport, const char *name, 680 const char *exec, int fd[2]) 681{ 682 struct helper_data *data = transport->data; 683 684 /* Get_helper so connect is inited. */ 685 get_helper(transport); 686 687 if (!process_connect_service(transport, name, exec)) 688 die(_("can't connect to subservice %s"), name); 689 690 fd[0] = data->helper->out; 691 fd[1] = data->helper->in; 692 693 do_take_over(transport); 694 return 0; 695} 696 697static struct ref *get_refs_list_using_list(struct transport *transport, 698 int for_push); 699 700static int fetch_refs(struct transport *transport, 701 int nr_heads, struct ref **to_fetch) 702{ 703 struct helper_data *data = transport->data; 704 int i, count; 705 706 get_helper(transport); 707 708 if (process_connect(transport, 0)) 709 return transport->vtable->fetch_refs(transport, nr_heads, to_fetch); 710 711 /* 712 * If we reach here, then the server, the client, and/or the transport 713 * helper does not support protocol v2. --negotiate-only requires 714 * protocol v2. 715 */ 716 if (data->transport_options.acked_commits) { 717 warning(_("--negotiate-only requires protocol v2")); 718 return -1; 719 } 720 721 if (!data->get_refs_list_called) { 722 /* 723 * We do not care about the list of refs returned, but only 724 * that the "list" command was sent. 725 */ 726 struct ref *dummy = get_refs_list_using_list(transport, 0); 727 free_refs(dummy); 728 } 729 730 count = 0; 731 for (i = 0; i < nr_heads; i++) 732 if (!(to_fetch[i]->status & REF_STATUS_UPTODATE)) 733 count++; 734 735 if (!count) 736 return 0; 737 738 if (data->check_connectivity && 739 data->transport_options.check_self_contained_and_connected) 740 set_helper_option(transport, "check-connectivity", "true"); 741 742 if (transport->cloning) 743 set_helper_option(transport, "cloning", "true"); 744 745 if (data->transport_options.update_shallow) 746 set_helper_option(transport, "update-shallow", "true"); 747 748 if (data->transport_options.refetch) 749 set_helper_option(transport, "refetch", "true"); 750 751 if (data->transport_options.filter_options.choice) { 752 const char *spec = expand_list_objects_filter_spec( 753 &data->transport_options.filter_options); 754 set_helper_option(transport, "filter", spec); 755 } 756 757 if (data->transport_options.negotiation_tips) 758 warning("Ignoring --negotiation-tip because the protocol does not support it."); 759 760 if (data->fetch) 761 return fetch_with_fetch(transport, nr_heads, to_fetch); 762 763 if (data->import) 764 return fetch_with_import(transport, nr_heads, to_fetch); 765 766 return -1; 767} 768 769struct push_update_ref_state { 770 struct ref *hint; 771 struct ref_push_report *report; 772 int new_report; 773}; 774 775static int push_update_ref_status(struct strbuf *buf, 776 struct push_update_ref_state *state, 777 struct ref *remote_refs) 778{ 779 char *refname, *msg; 780 int status, forced = 0; 781 782 if (starts_with(buf->buf, "option ")) { 783 struct object_id old_oid, new_oid; 784 const char *key, *val; 785 char *p; 786 787 if (!state->hint || !(state->report || state->new_report)) 788 die(_("'option' without a matching 'ok/error' directive")); 789 if (state->new_report) { 790 if (!state->hint->report) { 791 CALLOC_ARRAY(state->hint->report, 1); 792 state->report = state->hint->report; 793 } else { 794 state->report = state->hint->report; 795 while (state->report->next) 796 state->report = state->report->next; 797 CALLOC_ARRAY(state->report->next, 1); 798 state->report = state->report->next; 799 } 800 state->new_report = 0; 801 } 802 key = buf->buf + 7; 803 p = strchr(key, ' '); 804 if (p) 805 *p++ = '\0'; 806 val = p; 807 if (!strcmp(key, "refname")) 808 state->report->ref_name = xstrdup_or_null(val); 809 else if (!strcmp(key, "old-oid") && val && 810 !parse_oid_hex(val, &old_oid, &val)) 811 state->report->old_oid = oiddup(&old_oid); 812 else if (!strcmp(key, "new-oid") && val && 813 !parse_oid_hex(val, &new_oid, &val)) 814 state->report->new_oid = oiddup(&new_oid); 815 else if (!strcmp(key, "forced-update")) 816 state->report->forced_update = 1; 817 /* Not update remote namespace again. */ 818 return 1; 819 } 820 821 state->report = NULL; 822 state->new_report = 0; 823 824 if (starts_with(buf->buf, "ok ")) { 825 status = REF_STATUS_OK; 826 refname = buf->buf + 3; 827 } else if (starts_with(buf->buf, "error ")) { 828 status = REF_STATUS_REMOTE_REJECT; 829 refname = buf->buf + 6; 830 } else 831 die(_("expected ok/error, helper said '%s'"), buf->buf); 832 833 msg = strchr(refname, ' '); 834 if (msg) { 835 struct strbuf msg_buf = STRBUF_INIT; 836 const char *end; 837 838 *msg++ = '\0'; 839 if (!unquote_c_style(&msg_buf, msg, &end)) 840 msg = strbuf_detach(&msg_buf, NULL); 841 else 842 msg = xstrdup(msg); 843 strbuf_release(&msg_buf); 844 845 if (!strcmp(msg, "no match")) { 846 status = REF_STATUS_NONE; 847 FREE_AND_NULL(msg); 848 } 849 else if (!strcmp(msg, "up to date")) { 850 status = REF_STATUS_UPTODATE; 851 FREE_AND_NULL(msg); 852 } 853 else if (!strcmp(msg, "non-fast forward")) { 854 status = REF_STATUS_REJECT_NONFASTFORWARD; 855 FREE_AND_NULL(msg); 856 } 857 else if (!strcmp(msg, "already exists")) { 858 status = REF_STATUS_REJECT_ALREADY_EXISTS; 859 FREE_AND_NULL(msg); 860 } 861 else if (!strcmp(msg, "fetch first")) { 862 status = REF_STATUS_REJECT_FETCH_FIRST; 863 FREE_AND_NULL(msg); 864 } 865 else if (!strcmp(msg, "needs force")) { 866 status = REF_STATUS_REJECT_NEEDS_FORCE; 867 FREE_AND_NULL(msg); 868 } 869 else if (!strcmp(msg, "stale info")) { 870 status = REF_STATUS_REJECT_STALE; 871 FREE_AND_NULL(msg); 872 } 873 else if (!strcmp(msg, "remote ref updated since checkout")) { 874 status = REF_STATUS_REJECT_REMOTE_UPDATED; 875 FREE_AND_NULL(msg); 876 } 877 else if (!strcmp(msg, "forced update")) { 878 forced = 1; 879 FREE_AND_NULL(msg); 880 } 881 else if (!strcmp(msg, "expecting report")) { 882 status = REF_STATUS_EXPECTING_REPORT; 883 FREE_AND_NULL(msg); 884 } 885 } 886 887 if (state->hint) 888 state->hint = find_ref_by_name(state->hint, refname); 889 if (!state->hint) 890 state->hint = find_ref_by_name(remote_refs, refname); 891 if (!state->hint) { 892 warning(_("helper reported unexpected status of %s"), refname); 893 return 1; 894 } 895 896 if (state->hint->status != REF_STATUS_NONE) { 897 /* 898 * Earlier, the ref was marked not to be pushed, so ignore the ref 899 * status reported by the remote helper if the latter is 'no match'. 900 */ 901 if (status == REF_STATUS_NONE) 902 return 1; 903 } 904 905 if (status == REF_STATUS_OK) 906 state->new_report = 1; 907 state->hint->status = status; 908 state->hint->forced_update |= forced; 909 state->hint->remote_status = msg; 910 return !(status == REF_STATUS_OK); 911} 912 913static int push_update_refs_status(struct helper_data *data, 914 struct ref *remote_refs, 915 int flags) 916{ 917 struct ref *ref; 918 struct ref_push_report *report; 919 struct strbuf buf = STRBUF_INIT; 920 struct push_update_ref_state state = { remote_refs, NULL, 0 }; 921 922 for (;;) { 923 if (recvline(data, &buf)) { 924 strbuf_release(&buf); 925 return 1; 926 } 927 if (!buf.len) 928 break; 929 push_update_ref_status(&buf, &state, remote_refs); 930 } 931 strbuf_release(&buf); 932 933 if (flags & TRANSPORT_PUSH_DRY_RUN || !data->rs.nr || data->no_private_update) 934 return 0; 935 936 /* propagate back the update to the remote namespace */ 937 for (ref = remote_refs; ref; ref = ref->next) { 938 char *private; 939 940 if (ref->status != REF_STATUS_OK) 941 continue; 942 943 if (!ref->report) { 944 private = apply_refspecs(&data->rs, ref->name); 945 if (!private) 946 continue; 947 refs_update_ref(get_main_ref_store(the_repository), 948 "update by helper", private, 949 &(ref->new_oid), 950 NULL, 0, 0); 951 free(private); 952 } else { 953 for (report = ref->report; report; report = report->next) { 954 private = apply_refspecs(&data->rs, 955 report->ref_name 956 ? report->ref_name 957 : ref->name); 958 if (!private) 959 continue; 960 refs_update_ref(get_main_ref_store(the_repository), 961 "update by helper", private, 962 report->new_oid 963 ? report->new_oid 964 : &(ref->new_oid), 965 NULL, 0, 0); 966 free(private); 967 } 968 } 969 } 970 return 0; 971} 972 973static void set_common_push_options(struct transport *transport, 974 const char *name, int flags) 975{ 976 if (flags & TRANSPORT_PUSH_DRY_RUN) { 977 if (set_helper_option(transport, "dry-run", "true") != 0) 978 die(_("helper %s does not support dry-run"), name); 979 } else if (flags & TRANSPORT_PUSH_CERT_ALWAYS) { 980 if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "true") != 0) 981 die(_("helper %s does not support --signed"), name); 982 } else if (flags & TRANSPORT_PUSH_CERT_IF_ASKED) { 983 if (set_helper_option(transport, TRANS_OPT_PUSH_CERT, "if-asked") != 0) 984 die(_("helper %s does not support --signed=if-asked"), name); 985 } 986 987 if (flags & TRANSPORT_PUSH_ATOMIC) 988 if (set_helper_option(transport, TRANS_OPT_ATOMIC, "true") != 0) 989 die(_("helper %s does not support --atomic"), name); 990 991 if (flags & TRANSPORT_PUSH_FORCE_IF_INCLUDES) 992 if (set_helper_option(transport, TRANS_OPT_FORCE_IF_INCLUDES, "true") != 0) 993 die(_("helper %s does not support --%s"), 994 name, TRANS_OPT_FORCE_IF_INCLUDES); 995 996 if (flags & TRANSPORT_PUSH_OPTIONS) { 997 struct string_list_item *item; 998 for_each_string_list_item(item, transport->push_options) 999 if (set_helper_option(transport, "push-option", item->string) != 0) 1000 die(_("helper %s does not support 'push-option'"), name); 1001 } 1002} 1003 1004static int push_refs_with_push(struct transport *transport, 1005 struct ref *remote_refs, int flags) 1006{ 1007 int force_all = flags & TRANSPORT_PUSH_FORCE; 1008 int mirror = flags & TRANSPORT_PUSH_MIRROR; 1009 int atomic = flags & TRANSPORT_PUSH_ATOMIC; 1010 struct helper_data *data = transport->data; 1011 struct strbuf buf = STRBUF_INIT; 1012 struct ref *ref; 1013 struct string_list cas_options = STRING_LIST_INIT_DUP; 1014 struct string_list_item *cas_option; 1015 1016 get_helper(transport); 1017 if (!data->push) 1018 return 1; 1019 1020 for (ref = remote_refs; ref; ref = ref->next) { 1021 if (!ref->peer_ref && !mirror) 1022 continue; 1023 1024 /* Check for statuses set by set_ref_status_for_push() */ 1025 switch (ref->status) { 1026 case REF_STATUS_REJECT_NONFASTFORWARD: 1027 case REF_STATUS_REJECT_STALE: 1028 case REF_STATUS_REJECT_ALREADY_EXISTS: 1029 case REF_STATUS_REJECT_REMOTE_UPDATED: 1030 if (atomic) { 1031 reject_atomic_push(remote_refs, mirror); 1032 string_list_clear(&cas_options, 0); 1033 strbuf_release(&buf); 1034 return 0; 1035 } else 1036 continue; 1037 case REF_STATUS_UPTODATE: 1038 continue; 1039 default: 1040 ; /* do nothing */ 1041 } 1042 1043 if (force_all) 1044 ref->force = 1; 1045 1046 strbuf_addstr(&buf, "push "); 1047 if (!ref->deletion) { 1048 if (ref->force) 1049 strbuf_addch(&buf, '+'); 1050 if (ref->peer_ref) 1051 strbuf_addstr(&buf, ref->peer_ref->name); 1052 else 1053 strbuf_addstr(&buf, oid_to_hex(&ref->new_oid)); 1054 } 1055 strbuf_addch(&buf, ':'); 1056 strbuf_addstr(&buf, ref->name); 1057 strbuf_addch(&buf, '\n'); 1058 1059 /* 1060 * The "--force-with-lease" options without explicit 1061 * values to expect have already been expanded into 1062 * the ref->old_oid_expect[] field; we can ignore 1063 * transport->smart_options->cas altogether and instead 1064 * can enumerate them from the refs. 1065 */ 1066 if (ref->expect_old_sha1) { 1067 struct strbuf cas = STRBUF_INIT; 1068 strbuf_addf(&cas, "%s:%s", 1069 ref->name, oid_to_hex(&ref->old_oid_expect)); 1070 string_list_append_nodup(&cas_options, 1071 strbuf_detach(&cas, NULL)); 1072 } 1073 } 1074 if (buf.len == 0) { 1075 string_list_clear(&cas_options, 0); 1076 return 0; 1077 } 1078 1079 for_each_string_list_item(cas_option, &cas_options) 1080 set_helper_option(transport, "cas", cas_option->string); 1081 set_common_push_options(transport, data->name, flags); 1082 1083 strbuf_addch(&buf, '\n'); 1084 sendline(data, &buf); 1085 strbuf_release(&buf); 1086 string_list_clear(&cas_options, 0); 1087 1088 return push_update_refs_status(data, remote_refs, flags); 1089} 1090 1091static int push_refs_with_export(struct transport *transport, 1092 struct ref *remote_refs, int flags) 1093{ 1094 struct ref *ref; 1095 struct child_process *helper, exporter; 1096 struct helper_data *data = transport->data; 1097 struct string_list revlist_args = STRING_LIST_INIT_DUP; 1098 struct strbuf buf = STRBUF_INIT; 1099 1100 if (!data->rs.nr) 1101 die(_("remote-helper doesn't support push; refspec needed")); 1102 1103 set_common_push_options(transport, data->name, flags); 1104 if (flags & TRANSPORT_PUSH_FORCE) { 1105 if (set_helper_option(transport, "force", "true") != 0) 1106 warning(_("helper %s does not support '--force'"), data->name); 1107 } 1108 1109 helper = get_helper(transport); 1110 1111 write_constant(helper->in, "export\n"); 1112 1113 for (ref = remote_refs; ref; ref = ref->next) { 1114 char *private; 1115 struct object_id oid; 1116 1117 private = apply_refspecs(&data->rs, ref->name); 1118 if (private && !repo_get_oid(the_repository, private, &oid)) { 1119 strbuf_addf(&buf, "^%s", private); 1120 string_list_append_nodup(&revlist_args, 1121 strbuf_detach(&buf, NULL)); 1122 oidcpy(&ref->old_oid, &oid); 1123 } 1124 free(private); 1125 1126 if (ref->peer_ref) { 1127 if (strcmp(ref->name, ref->peer_ref->name)) { 1128 if (!ref->deletion) { 1129 const char *name; 1130 int flag; 1131 1132 /* Follow symbolic refs (mainly for HEAD). */ 1133 name = refs_resolve_ref_unsafe(get_main_ref_store(the_repository), 1134 ref->peer_ref->name, 1135 RESOLVE_REF_READING, 1136 &oid, 1137 &flag); 1138 if (!name || !(flag & REF_ISSYMREF)) 1139 name = ref->peer_ref->name; 1140 1141 strbuf_addf(&buf, "%s:%s", name, ref->name); 1142 } else 1143 strbuf_addf(&buf, ":%s", ref->name); 1144 1145 string_list_append(&revlist_args, "--refspec"); 1146 string_list_append(&revlist_args, buf.buf); 1147 strbuf_release(&buf); 1148 } 1149 if (!ref->deletion) 1150 string_list_append(&revlist_args, ref->peer_ref->name); 1151 } 1152 } 1153 1154 if (get_exporter(transport, &exporter, &revlist_args)) 1155 die(_("couldn't run fast-export")); 1156 1157 string_list_clear(&revlist_args, 1); 1158 1159 if (finish_command(&exporter)) 1160 die(_("error while running fast-export")); 1161 if (push_update_refs_status(data, remote_refs, flags)) 1162 return 1; 1163 1164 if (data->export_marks) { 1165 strbuf_addf(&buf, "%s.tmp", data->export_marks); 1166 rename(buf.buf, data->export_marks); 1167 strbuf_release(&buf); 1168 } 1169 1170 return 0; 1171} 1172 1173static int push_refs(struct transport *transport, 1174 struct ref *remote_refs, int flags) 1175{ 1176 struct helper_data *data = transport->data; 1177 1178 if (process_connect(transport, 1)) 1179 return transport->vtable->push_refs(transport, remote_refs, flags); 1180 1181 if (!remote_refs) { 1182 fprintf(stderr, 1183 _("No refs in common and none specified; doing nothing.\n" 1184 "Perhaps you should specify a branch.\n")); 1185 return 0; 1186 } 1187 1188 if (data->push) 1189 return push_refs_with_push(transport, remote_refs, flags); 1190 1191 if (data->export) 1192 return push_refs_with_export(transport, remote_refs, flags); 1193 1194 return -1; 1195} 1196 1197 1198static int has_attribute(const char *attrs, const char *attr) 1199{ 1200 int len; 1201 if (!attrs) 1202 return 0; 1203 1204 len = strlen(attr); 1205 for (;;) { 1206 const char *space = strchrnul(attrs, ' '); 1207 if (len == space - attrs && !strncmp(attrs, attr, len)) 1208 return 1; 1209 if (!*space) 1210 return 0; 1211 attrs = space + 1; 1212 } 1213} 1214 1215static struct ref *get_refs_list(struct transport *transport, int for_push, 1216 struct transport_ls_refs_options *transport_options) 1217{ 1218 get_helper(transport); 1219 1220 if (process_connect(transport, for_push)) 1221 return transport->vtable->get_refs_list(transport, for_push, 1222 transport_options); 1223 1224 return get_refs_list_using_list(transport, for_push); 1225} 1226 1227static struct ref *get_refs_list_using_list(struct transport *transport, 1228 int for_push) 1229{ 1230 struct helper_data *data = transport->data; 1231 struct child_process *helper; 1232 struct ref *ret = NULL; 1233 struct ref **tail = &ret; 1234 struct ref *posn; 1235 struct strbuf buf = STRBUF_INIT; 1236 1237 data->get_refs_list_called = 1; 1238 helper = get_helper(transport); 1239 1240 if (data->object_format) 1241 set_helper_option(transport, "object-format", "true"); 1242 1243 if (data->push && for_push) 1244 write_constant(helper->in, "list for-push\n"); 1245 else 1246 write_constant(helper->in, "list\n"); 1247 1248 while (1) { 1249 char *eov, *eon; 1250 if (recvline(data, &buf)) 1251 exit(128); 1252 1253 if (!*buf.buf) 1254 break; 1255 else if (buf.buf[0] == ':') { 1256 const char *value; 1257 if (skip_prefix(buf.buf, ":object-format ", &value)) { 1258 int algo = hash_algo_by_name(value); 1259 if (algo == GIT_HASH_UNKNOWN) 1260 die(_("unsupported object format '%s'"), 1261 value); 1262 transport->hash_algo = &hash_algos[algo]; 1263 } 1264 continue; 1265 } 1266 1267 eov = strchr(buf.buf, ' '); 1268 if (!eov) 1269 die(_("malformed response in ref list: %s"), buf.buf); 1270 eon = strchr(eov + 1, ' '); 1271 *eov = '\0'; 1272 if (eon) 1273 *eon = '\0'; 1274 *tail = alloc_ref(eov + 1); 1275 if (buf.buf[0] == '@') 1276 (*tail)->symref = xstrdup(buf.buf + 1); 1277 else if (buf.buf[0] != '?') 1278 get_oid_hex_algop(buf.buf, &(*tail)->old_oid, transport->hash_algo); 1279 if (eon) { 1280 if (has_attribute(eon + 1, "unchanged")) { 1281 (*tail)->status |= REF_STATUS_UPTODATE; 1282 if (refs_read_ref(get_main_ref_store(the_repository), (*tail)->name, &(*tail)->old_oid) < 0) 1283 die(_("could not read ref %s"), 1284 (*tail)->name); 1285 } 1286 } 1287 tail = &((*tail)->next); 1288 } 1289 if (debug) 1290 fprintf(stderr, "Debug: Read ref listing.\n"); 1291 strbuf_release(&buf); 1292 1293 for (posn = ret; posn; posn = posn->next) 1294 resolve_remote_symref(posn, ret); 1295 1296 return ret; 1297} 1298 1299static int get_bundle_uri(struct transport *transport) 1300{ 1301 get_helper(transport); 1302 1303 if (process_connect(transport, 0)) 1304 return transport->vtable->get_bundle_uri(transport); 1305 1306 return -1; 1307} 1308 1309static struct transport_vtable vtable = { 1310 .set_option = set_helper_option, 1311 .get_refs_list = get_refs_list, 1312 .get_bundle_uri = get_bundle_uri, 1313 .fetch_refs = fetch_refs, 1314 .push_refs = push_refs, 1315 .connect = connect_helper, 1316 .disconnect = release_helper 1317}; 1318 1319int transport_helper_init(struct transport *transport, const char *name) 1320{ 1321 struct helper_data *data = xcalloc(1, sizeof(*data)); 1322 data->name = xstrdup(name); 1323 1324 transport_check_allowed(name); 1325 1326 if (getenv("GIT_TRANSPORT_HELPER_DEBUG")) 1327 debug = 1; 1328 1329 list_objects_filter_init(&data->transport_options.filter_options); 1330 1331 transport->data = data; 1332 transport->vtable = &vtable; 1333 transport->smart_options = &(data->transport_options); 1334 return 0; 1335} 1336 1337/* 1338 * Linux pipes can buffer 65536 bytes at once (and most platforms can 1339 * buffer less), so attempt reads and writes with up to that size. 1340 */ 1341#define BUFFERSIZE 65536 1342/* This should be enough to hold debugging message. */ 1343#define PBUFFERSIZE 8192 1344 1345/* Print bidirectional transfer loop debug message. */ 1346__attribute__((format (printf, 1, 2))) 1347static void transfer_debug(const char *fmt, ...) 1348{ 1349 /* 1350 * NEEDSWORK: This function is sometimes used from multiple threads, and 1351 * we end up using debug_enabled racily. That "should not matter" since 1352 * we always write the same value, but it's still wrong. This function 1353 * is listed in .tsan-suppressions for the time being. 1354 */ 1355 1356 va_list args; 1357 char msgbuf[PBUFFERSIZE]; 1358 static int debug_enabled = -1; 1359 1360 if (debug_enabled < 0) 1361 debug_enabled = getenv("GIT_TRANSLOOP_DEBUG") ? 1 : 0; 1362 if (!debug_enabled) 1363 return; 1364 1365 va_start(args, fmt); 1366 vsnprintf(msgbuf, PBUFFERSIZE, fmt, args); 1367 va_end(args); 1368 fprintf(stderr, "Transfer loop debugging: %s\n", msgbuf); 1369} 1370 1371/* Stream state: More data may be coming in this direction. */ 1372#define SSTATE_TRANSFERRING 0 1373/* 1374 * Stream state: No more data coming in this direction, flushing rest of 1375 * data. 1376 */ 1377#define SSTATE_FLUSHING 1 1378/* Stream state: Transfer in this direction finished. */ 1379#define SSTATE_FINISHED 2 1380 1381#define STATE_NEEDS_READING(state) ((state) <= SSTATE_TRANSFERRING) 1382#define STATE_NEEDS_WRITING(state) ((state) <= SSTATE_FLUSHING) 1383#define STATE_NEEDS_CLOSING(state) ((state) == SSTATE_FLUSHING) 1384 1385/* Unidirectional transfer. */ 1386struct unidirectional_transfer { 1387 /* Source */ 1388 int src; 1389 /* Destination */ 1390 int dest; 1391 /* Is source socket? */ 1392 int src_is_sock; 1393 /* Is destination socket? */ 1394 int dest_is_sock; 1395 /* Transfer state (TRANSFERRING/FLUSHING/FINISHED) */ 1396 int state; 1397 /* Buffer. */ 1398 char buf[BUFFERSIZE]; 1399 /* Buffer used. */ 1400 size_t bufuse; 1401 /* Name of source. */ 1402 const char *src_name; 1403 /* Name of destination. */ 1404 const char *dest_name; 1405}; 1406 1407/* Closes the target (for writing) if transfer has finished. */ 1408static void udt_close_if_finished(struct unidirectional_transfer *t) 1409{ 1410 if (STATE_NEEDS_CLOSING(t->state) && !t->bufuse) { 1411 t->state = SSTATE_FINISHED; 1412 if (t->dest_is_sock) 1413 shutdown(t->dest, SHUT_WR); 1414 else 1415 close(t->dest); 1416 transfer_debug("Closed %s.", t->dest_name); 1417 } 1418} 1419 1420/* 1421 * Tries to read data from source into buffer. If buffer is full, 1422 * no data is read. Returns 0 on success, -1 on error. 1423 */ 1424static int udt_do_read(struct unidirectional_transfer *t) 1425{ 1426 ssize_t bytes; 1427 1428 if (t->bufuse == BUFFERSIZE) 1429 return 0; /* No space for more. */ 1430 1431 transfer_debug("%s is readable", t->src_name); 1432 bytes = xread(t->src, t->buf + t->bufuse, BUFFERSIZE - t->bufuse); 1433 if (bytes < 0) { 1434 error_errno(_("read(%s) failed"), t->src_name); 1435 return -1; 1436 } else if (bytes == 0) { 1437 transfer_debug("%s EOF (with %i bytes in buffer)", 1438 t->src_name, (int)t->bufuse); 1439 t->state = SSTATE_FLUSHING; 1440 } else { 1441 t->bufuse += bytes; 1442 transfer_debug("Read %i bytes from %s (buffer now at %i)", 1443 (int)bytes, t->src_name, (int)t->bufuse); 1444 } 1445 return 0; 1446} 1447 1448/* Tries to write data from buffer into destination. If buffer is empty, 1449 * no data is written. Returns 0 on success, -1 on error. 1450 */ 1451static int udt_do_write(struct unidirectional_transfer *t) 1452{ 1453 ssize_t bytes; 1454 1455 if (t->bufuse == 0) 1456 return 0; /* Nothing to write. */ 1457 1458 transfer_debug("%s is writable", t->dest_name); 1459 bytes = xwrite(t->dest, t->buf, t->bufuse); 1460 if (bytes < 0) { 1461 error_errno(_("write(%s) failed"), t->dest_name); 1462 return -1; 1463 } else if (bytes > 0) { 1464 t->bufuse -= bytes; 1465 if (t->bufuse) 1466 memmove(t->buf, t->buf + bytes, t->bufuse); 1467 transfer_debug("Wrote %i bytes to %s (buffer now at %i)", 1468 (int)bytes, t->dest_name, (int)t->bufuse); 1469 } 1470 return 0; 1471} 1472 1473 1474/* State of bidirectional transfer loop. */ 1475struct bidirectional_transfer_state { 1476 /* Direction from program to git. */ 1477 struct unidirectional_transfer ptg; 1478 /* Direction from git to program. */ 1479 struct unidirectional_transfer gtp; 1480}; 1481 1482static void *udt_copy_task_routine(void *udt) 1483{ 1484 struct unidirectional_transfer *t = (struct unidirectional_transfer *)udt; 1485 while (t->state != SSTATE_FINISHED) { 1486 if (STATE_NEEDS_READING(t->state)) 1487 if (udt_do_read(t)) 1488 return NULL; 1489 if (STATE_NEEDS_WRITING(t->state)) 1490 if (udt_do_write(t)) 1491 return NULL; 1492 if (STATE_NEEDS_CLOSING(t->state)) 1493 udt_close_if_finished(t); 1494 } 1495 return udt; /* Just some non-NULL value. */ 1496} 1497 1498#ifndef NO_PTHREADS 1499 1500/* 1501 * Join thread, with appropriate errors on failure. Name is name for the 1502 * thread (for error messages). Returns 0 on success, 1 on failure. 1503 */ 1504static int tloop_join(pthread_t thread, const char *name) 1505{ 1506 int err; 1507 void *tret; 1508 err = pthread_join(thread, &tret); 1509 if (!tret) { 1510 error(_("%s thread failed"), name); 1511 return 1; 1512 } 1513 if (err) { 1514 error(_("%s thread failed to join: %s"), name, strerror(err)); 1515 return 1; 1516 } 1517 return 0; 1518} 1519 1520/* 1521 * Spawn the transfer tasks and then wait for them. Returns 0 on success, 1522 * -1 on failure. 1523 */ 1524static int tloop_spawnwait_tasks(struct bidirectional_transfer_state *s) 1525{ 1526 pthread_t gtp_thread; 1527 pthread_t ptg_thread; 1528 int err; 1529 int ret = 0; 1530 err = pthread_create(&gtp_thread, NULL, udt_copy_task_routine, 1531 &s->gtp); 1532 if (err) 1533 die(_("can't start thread for copying data: %s"), strerror(err)); 1534 err = pthread_create(&ptg_thread, NULL, udt_copy_task_routine, 1535 &s->ptg); 1536 if (err) 1537 die(_("can't start thread for copying data: %s"), strerror(err)); 1538 1539 ret |= tloop_join(gtp_thread, "Git to program copy"); 1540 ret |= tloop_join(ptg_thread, "Program to git copy"); 1541 return ret; 1542} 1543#else 1544 1545/* Close the source and target (for writing) for transfer. */ 1546static void udt_kill_transfer(struct unidirectional_transfer *t) 1547{ 1548 t->state = SSTATE_FINISHED; 1549 /* 1550 * Socket read end left open isn't a disaster if nobody 1551 * attempts to read from it (mingw compat headers do not 1552 * have SHUT_RD)... 1553 * 1554 * We can't fully close the socket since otherwise gtp 1555 * task would first close the socket it sends data to 1556 * while closing the ptg file descriptors. 1557 */ 1558 if (!t->src_is_sock) 1559 close(t->src); 1560 if (t->dest_is_sock) 1561 shutdown(t->dest, SHUT_WR); 1562 else 1563 close(t->dest); 1564} 1565 1566/* 1567 * Join process, with appropriate errors on failure. Name is name for the 1568 * process (for error messages). Returns 0 on success, 1 on failure. 1569 */ 1570static int tloop_join(pid_t pid, const char *name) 1571{ 1572 int tret; 1573 if (waitpid(pid, &tret, 0) < 0) { 1574 error_errno(_("%s process failed to wait"), name); 1575 return 1; 1576 } 1577 if (!WIFEXITED(tret) || WEXITSTATUS(tret)) { 1578 error(_("%s process failed"), name); 1579 return 1; 1580 } 1581 return 0; 1582} 1583 1584/* 1585 * Spawn the transfer tasks and then wait for them. Returns 0 on success, 1586 * -1 on failure. 1587 */ 1588static int tloop_spawnwait_tasks(struct bidirectional_transfer_state *s) 1589{ 1590 pid_t pid1, pid2; 1591 int ret = 0; 1592 1593 /* Fork thread #1: git to program. */ 1594 pid1 = fork(); 1595 if (pid1 < 0) 1596 die_errno(_("can't start thread for copying data")); 1597 else if (pid1 == 0) { 1598 udt_kill_transfer(&s->ptg); 1599 exit(udt_copy_task_routine(&s->gtp) ? 0 : 1); 1600 } 1601 1602 /* Fork thread #2: program to git. */ 1603 pid2 = fork(); 1604 if (pid2 < 0) 1605 die_errno(_("can't start thread for copying data")); 1606 else if (pid2 == 0) { 1607 udt_kill_transfer(&s->gtp); 1608 exit(udt_copy_task_routine(&s->ptg) ? 0 : 1); 1609 } 1610 1611 /* 1612 * Close both streams in parent as to not interfere with 1613 * end of file detection and wait for both tasks to finish. 1614 */ 1615 udt_kill_transfer(&s->gtp); 1616 udt_kill_transfer(&s->ptg); 1617 ret |= tloop_join(pid1, "Git to program copy"); 1618 ret |= tloop_join(pid2, "Program to git copy"); 1619 return ret; 1620} 1621#endif 1622 1623/* 1624 * Copies data from stdin to output and from input to stdout simultaneously. 1625 * Additionally filtering through given filter. If filter is NULL, uses 1626 * identity filter. 1627 */ 1628int bidirectional_transfer_loop(int input, int output) 1629{ 1630 struct bidirectional_transfer_state state; 1631 1632 /* Fill the state fields. */ 1633 state.ptg.src = input; 1634 state.ptg.dest = 1; 1635 state.ptg.src_is_sock = (input == output); 1636 state.ptg.dest_is_sock = 0; 1637 state.ptg.state = SSTATE_TRANSFERRING; 1638 state.ptg.bufuse = 0; 1639 state.ptg.src_name = "remote input"; 1640 state.ptg.dest_name = "stdout"; 1641 1642 state.gtp.src = 0; 1643 state.gtp.dest = output; 1644 state.gtp.src_is_sock = 0; 1645 state.gtp.dest_is_sock = (input == output); 1646 state.gtp.state = SSTATE_TRANSFERRING; 1647 state.gtp.bufuse = 0; 1648 state.gtp.src_name = "stdin"; 1649 state.gtp.dest_name = "remote output"; 1650 1651 return tloop_spawnwait_tasks(&state); 1652} 1653 1654void reject_atomic_push(struct ref *remote_refs, int mirror_mode) 1655{ 1656 struct ref *ref; 1657 1658 /* Mark other refs as failed */ 1659 for (ref = remote_refs; ref; ref = ref->next) { 1660 if (!ref->peer_ref && !mirror_mode) 1661 continue; 1662 1663 switch (ref->status) { 1664 case REF_STATUS_NONE: 1665 case REF_STATUS_OK: 1666 case REF_STATUS_EXPECTING_REPORT: 1667 ref->status = REF_STATUS_ATOMIC_PUSH_FAILED; 1668 continue; 1669 default: 1670 break; /* do nothing */ 1671 } 1672 } 1673 return; 1674}