transport-helper: factor out push_update_refs_status

The update ref status part of push is useful for the export command as well, factor it out into it's own function. Also factor out push_update_ref_status to avoid a long loop without an explicit condition with a non-trivial body. Signed-off-by: Sverre Rabbelier <srabbelier@gmail.com> Acked-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Sverre Rabbelier committed Jul 16, 2011 at 15:03 UTC d2e73c6f2ac3e2d32cd27afd80bfa7c1661a52d4
1 file changed +84 -69
transport-helper.c
+84 -69
@@ -559,6 +559,88 @@ static int fetch(struct transport *transport,
559 return -1;
560 }
561
562 +static void push_update_ref_status(struct strbuf *buf,
563 + struct ref **ref,
564 + struct ref *remote_refs)
565 +{
566 + char *refname, *msg;
567 + int status;
568 +
569 + if (!prefixcmp(buf->buf, "ok ")) {
570 + status = REF_STATUS_OK;
571 + refname = buf->buf + 3;
572 + } else if (!prefixcmp(buf->buf, "error ")) {
573 + status = REF_STATUS_REMOTE_REJECT;
574 + refname = buf->buf + 6;
575 + } else
576 + die("expected ok/error, helper said '%s'\n", buf->buf);
577 +
578 + msg = strchr(refname, ' ');
579 + if (msg) {
580 + struct strbuf msg_buf = STRBUF_INIT;
581 + const char *end;
582 +
583 + *msg++ = '\0';
584 + if (!unquote_c_style(&msg_buf, msg, &end))
585 + msg = strbuf_detach(&msg_buf, NULL);
586 + else
587 + msg = xstrdup(msg);
588 + strbuf_release(&msg_buf);
589 +
590 + if (!strcmp(msg, "no match")) {
591 + status = REF_STATUS_NONE;
592 + free(msg);
593 + msg = NULL;
594 + }
595 + else if (!strcmp(msg, "up to date")) {
596 + status = REF_STATUS_UPTODATE;
597 + free(msg);
598 + msg = NULL;
599 + }
600 + else if (!strcmp(msg, "non-fast forward")) {
601 + status = REF_STATUS_REJECT_NONFASTFORWARD;
602 + free(msg);
603 + msg = NULL;
604 + }
605 + }
606 +
607 + if (*ref)
608 + *ref = find_ref_by_name(*ref, refname);
609 + if (!*ref)
610 + *ref = find_ref_by_name(remote_refs, refname);
611 + if (!*ref) {
612 + warning("helper reported unexpected status of %s", refname);
613 + return;
614 + }
615 +
616 + if ((*ref)->status != REF_STATUS_NONE) {
617 + /*
618 + * Earlier, the ref was marked not to be pushed, so ignore the ref
619 + * status reported by the remote helper if the latter is 'no match'.
620 + */
621 + if (status == REF_STATUS_NONE)
622 + return;
623 + }
624 +
625 + (*ref)->status = status;
626 + (*ref)->remote_status = msg;
627 +}
628 +
629 +static void push_update_refs_status(struct helper_data *data,
630 + struct ref *remote_refs)
631 +{
632 + struct strbuf buf = STRBUF_INIT;
633 + struct ref *ref = remote_refs;
634 + for (;;) {
635 + recvline(data, &buf);
636 + if (!buf.len)
637 + break;
638 +
639 + push_update_ref_status(&buf, &ref, remote_refs);
640 + }
641 + strbuf_release(&buf);
642 +}
643 +
644 static int push_refs_with_push(struct transport *transport,
645 struct ref *remote_refs, int flags)
646 {
@@ -613,76 +695,9 @@ static int push_refs_with_push(struct transport *transport,
695
696 strbuf_addch(&buf, '\n');
697 sendline(data, &buf);
616 -
617 - ref = remote_refs;
618 - while (1) {
619 - char *refname, *msg;
620 - int status;
621 -
622 - recvline(data, &buf);
623 - if (!buf.len)
624 - break;
625 -
626 - if (!prefixcmp(buf.buf, "ok ")) {
627 - status = REF_STATUS_OK;
628 - refname = buf.buf + 3;
629 - } else if (!prefixcmp(buf.buf, "error ")) {
630 - status = REF_STATUS_REMOTE_REJECT;
631 - refname = buf.buf + 6;
632 - } else
633 - die("expected ok/error, helper said '%s'\n", buf.buf);
634 -
635 - msg = strchr(refname, ' ');
636 - if (msg) {
637 - struct strbuf msg_buf = STRBUF_INIT;
638 - const char *end;
639 -
640 - *msg++ = '\0';
641 - if (!unquote_c_style(&msg_buf, msg, &end))
642 - msg = strbuf_detach(&msg_buf, NULL);
643 - else
644 - msg = xstrdup(msg);
645 - strbuf_release(&msg_buf);
646 -
647 - if (!strcmp(msg, "no match")) {
648 - status = REF_STATUS_NONE;
649 - free(msg);
650 - msg = NULL;
651 - }
652 - else if (!strcmp(msg, "up to date")) {
653 - status = REF_STATUS_UPTODATE;
654 - free(msg);
655 - msg = NULL;
656 - }
657 - else if (!strcmp(msg, "non-fast forward")) {
658 - status = REF_STATUS_REJECT_NONFASTFORWARD;
659 - free(msg);
660 - msg = NULL;
661 - }
662 - }
663 -
664 - if (ref)
665 - ref = find_ref_by_name(ref, refname);
666 - if (!ref)
667 - ref = find_ref_by_name(remote_refs, refname);
668 - if (!ref) {
669 - warning("helper reported unexpected status of %s", refname);
670 - continue;
671 - }
672 -
673 - if (ref->status != REF_STATUS_NONE) {
674 - /*
675 - * Earlier, the ref was marked not to be pushed, so ignore the ref
676 - * status reported by the remote helper if the latter is 'no match'.
677 - */
678 - if (status == REF_STATUS_NONE)
679 - continue;
680 - }
681 -
682 - ref->status = status;
683 - ref->remote_status = msg;
684 - }
698 strbuf_release(&buf);
699 +
700 + push_update_refs_status(data, remote_refs);
701 return 0;
702 }
703