2 * Copyright (C) the libgit2 contributors. All rights reserved.
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
8 #include "git2/odb_backend.h"
12 #include "repository.h"
14 #include "pack-objects.h"
18 #define NETWORK_XFER_THRESHOLD (100*1024)
19 /* The minimal interval between progress updates (in seconds). */
20 #define MIN_PROGRESS_UPDATE_INTERVAL 0.5
22 int git_smart__store_refs(transport_smart
*t
, int flushes
)
24 gitno_buffer
*buf
= &t
->buffer
;
25 git_vector
*refs
= &t
->refs
;
26 int error
, flush
= 0, recvd
;
27 const char *line_end
= NULL
;
31 /* Clear existing refs in case git_remote_connect() is called again
32 * after git_remote_disconnect().
34 git_vector_foreach(refs
, i
, pkt
) {
37 git_vector_clear(refs
);
42 error
= git_pkt_parse_line(&pkt
, buf
->data
, &line_end
, buf
->offset
);
46 if (error
< 0 && error
!= GIT_EBUFS
)
49 if (error
== GIT_EBUFS
) {
50 if ((recvd
= gitno_recv(buf
)) < 0)
53 if (recvd
== 0 && !flush
) {
54 giterr_set(GITERR_NET
, "Early EOF");
61 gitno_consume(buf
, line_end
);
62 if (pkt
->type
== GIT_PKT_ERR
) {
63 giterr_set(GITERR_NET
, "Remote error: %s", ((git_pkt_err
*)pkt
)->error
);
68 if (pkt
->type
!= GIT_PKT_FLUSH
&& git_vector_insert(refs
, pkt
) < 0)
71 if (pkt
->type
== GIT_PKT_FLUSH
) {
75 } while (flush
< flushes
);
80 static int append_symref(const char **out
, git_vector
*symrefs
, const char *ptr
)
84 git_buf buf
= GIT_BUF_INIT
;
85 git_refspec
*mapping
= NULL
;
87 ptr
+= strlen(GIT_CAP_SYMREF
);
92 if (!(end
= strchr(ptr
, ' ')) &&
93 !(end
= strchr(ptr
, '\0')))
96 if ((error
= git_buf_put(&buf
, ptr
, end
- ptr
)) < 0)
99 /* symref mapping has refspec format */
100 mapping
= git__calloc(1, sizeof(git_refspec
));
101 GITERR_CHECK_ALLOC(mapping
);
103 error
= git_refspec__parse(mapping
, git_buf_cstr(&buf
), true);
106 /* if the error isn't OOM, then it's a parse error; let's use a nicer message */
108 if (giterr_last()->klass
!= GITERR_NOMEMORY
)
114 if ((error
= git_vector_insert(symrefs
, mapping
)) < 0)
121 giterr_set(GITERR_NET
, "remote sent invalid symref");
122 git_refspec__free(mapping
);
126 int git_smart__detect_caps(git_pkt_ref
*pkt
, transport_smart_caps
*caps
, git_vector
*symrefs
)
130 /* No refs or capabilites, odd but not a problem */
131 if (pkt
== NULL
|| pkt
->capabilities
== NULL
)
134 ptr
= pkt
->capabilities
;
135 while (ptr
!= NULL
&& *ptr
!= '\0') {
139 if (!git__prefixcmp(ptr
, GIT_CAP_OFS_DELTA
)) {
140 caps
->common
= caps
->ofs_delta
= 1;
141 ptr
+= strlen(GIT_CAP_OFS_DELTA
);
145 /* Keep multi_ack_detailed before multi_ack */
146 if (!git__prefixcmp(ptr
, GIT_CAP_MULTI_ACK_DETAILED
)) {
147 caps
->common
= caps
->multi_ack_detailed
= 1;
148 ptr
+= strlen(GIT_CAP_MULTI_ACK_DETAILED
);
152 if (!git__prefixcmp(ptr
, GIT_CAP_MULTI_ACK
)) {
153 caps
->common
= caps
->multi_ack
= 1;
154 ptr
+= strlen(GIT_CAP_MULTI_ACK
);
158 if (!git__prefixcmp(ptr
, GIT_CAP_INCLUDE_TAG
)) {
159 caps
->common
= caps
->include_tag
= 1;
160 ptr
+= strlen(GIT_CAP_INCLUDE_TAG
);
164 /* Keep side-band check after side-band-64k */
165 if (!git__prefixcmp(ptr
, GIT_CAP_SIDE_BAND_64K
)) {
166 caps
->common
= caps
->side_band_64k
= 1;
167 ptr
+= strlen(GIT_CAP_SIDE_BAND_64K
);
171 if (!git__prefixcmp(ptr
, GIT_CAP_SIDE_BAND
)) {
172 caps
->common
= caps
->side_band
= 1;
173 ptr
+= strlen(GIT_CAP_SIDE_BAND
);
177 if (!git__prefixcmp(ptr
, GIT_CAP_DELETE_REFS
)) {
178 caps
->common
= caps
->delete_refs
= 1;
179 ptr
+= strlen(GIT_CAP_DELETE_REFS
);
183 if (!git__prefixcmp(ptr
, GIT_CAP_THIN_PACK
)) {
184 caps
->common
= caps
->thin_pack
= 1;
185 ptr
+= strlen(GIT_CAP_THIN_PACK
);
189 if (!git__prefixcmp(ptr
, GIT_CAP_SYMREF
)) {
192 if ((error
= append_symref(&ptr
, symrefs
, ptr
)) < 0)
198 /* We don't know this capability, so skip it */
199 ptr
= strchr(ptr
, ' ');
205 static int recv_pkt(git_pkt
**out
, gitno_buffer
*buf
)
207 const char *ptr
= buf
->data
, *line_end
= ptr
;
209 int pkt_type
, error
= 0, ret
;
213 error
= git_pkt_parse_line(&pkt
, ptr
, &line_end
, buf
->offset
);
218 break; /* return the pkt */
220 if (error
< 0 && error
!= GIT_EBUFS
)
223 if ((ret
= gitno_recv(buf
)) < 0)
227 gitno_consume(buf
, line_end
);
228 pkt_type
= pkt
->type
;
237 static int store_common(transport_smart
*t
)
240 gitno_buffer
*buf
= &t
->buffer
;
244 if ((error
= recv_pkt(&pkt
, buf
)) < 0)
247 if (pkt
->type
== GIT_PKT_ACK
) {
248 if (git_vector_insert(&t
->common
, pkt
) < 0)
260 static int fetch_setup_walk(git_revwalk
**out
, git_repository
*repo
)
262 git_revwalk
*walk
= NULL
;
268 if ((error
= git_reference_list(&refs
, repo
)) < 0)
271 if ((error
= git_revwalk_new(&walk
, repo
)) < 0)
274 git_revwalk_sorting(walk
, GIT_SORT_TIME
);
276 for (i
= 0; i
< refs
.count
; ++i
) {
278 if (!git__prefixcmp(refs
.strings
[i
], GIT_REFS_TAGS_DIR
))
281 if ((error
= git_reference_lookup(&ref
, repo
, refs
.strings
[i
])) < 0)
284 if (git_reference_type(ref
) == GIT_REF_SYMBOLIC
)
287 if ((error
= git_revwalk_push(walk
, git_reference_target(ref
))) < 0)
290 git_reference_free(ref
);
293 git_strarray_free(&refs
);
298 git_revwalk_free(walk
);
299 git_reference_free(ref
);
300 git_strarray_free(&refs
);
304 static int wait_while_ack(gitno_buffer
*buf
)
307 git_pkt_ack
*pkt
= NULL
;
312 if ((error
= recv_pkt((git_pkt
**)&pkt
, buf
)) < 0)
315 if (pkt
->type
== GIT_PKT_NAK
)
318 if (pkt
->type
== GIT_PKT_ACK
&&
319 (pkt
->status
!= GIT_ACK_CONTINUE
&&
320 pkt
->status
!= GIT_ACK_COMMON
)) {
330 int git_smart__negotiate_fetch(git_transport
*transport
, git_repository
*repo
, const git_remote_head
* const *wants
, size_t count
)
332 transport_smart
*t
= (transport_smart
*)transport
;
333 gitno_buffer
*buf
= &t
->buffer
;
334 git_buf data
= GIT_BUF_INIT
;
335 git_revwalk
*walk
= NULL
;
336 int error
= -1, pkt_type
;
340 if ((error
= git_pkt_buffer_wants(wants
, count
, &t
->caps
, &data
)) < 0)
343 if ((error
= fetch_setup_walk(&walk
, repo
)) < 0)
347 * Our support for ACK extensions is simply to parse them. On
348 * the first ACK we will accept that as enough common
349 * objects. We give up if we haven't found an answer in the
354 error
= git_revwalk_next(&oid
, walk
);
357 if (GIT_ITEROVER
== error
)
363 git_pkt_buffer_have(&oid
, &data
);
366 if (t
->cancelled
.val
) {
367 giterr_set(GITERR_NET
, "The fetch was cancelled by the user");
372 git_pkt_buffer_flush(&data
);
373 if (git_buf_oom(&data
)) {
378 if ((error
= git_smart__negotiation_step(&t
->parent
, data
.ptr
, data
.size
)) < 0)
381 git_buf_clear(&data
);
382 if (t
->caps
.multi_ack
|| t
->caps
.multi_ack_detailed
) {
383 if ((error
= store_common(t
)) < 0)
386 pkt_type
= recv_pkt(NULL
, buf
);
388 if (pkt_type
== GIT_PKT_ACK
) {
390 } else if (pkt_type
== GIT_PKT_NAK
) {
392 } else if (pkt_type
< 0) {
393 /* recv_pkt returned an error */
397 giterr_set(GITERR_NET
, "Unexpected pkt type");
404 if (t
->common
.length
> 0)
407 if (i
% 20 == 0 && t
->rpc
) {
411 if ((error
= git_pkt_buffer_wants(wants
, count
, &t
->caps
, &data
)) < 0)
414 git_vector_foreach(&t
->common
, i
, pkt
) {
415 if ((error
= git_pkt_buffer_have(&pkt
->oid
, &data
)) < 0)
419 if (git_buf_oom(&data
)) {
426 /* Tell the other end that we're done negotiating */
427 if (t
->rpc
&& t
->common
.length
> 0) {
431 if ((error
= git_pkt_buffer_wants(wants
, count
, &t
->caps
, &data
)) < 0)
434 git_vector_foreach(&t
->common
, i
, pkt
) {
435 if ((error
= git_pkt_buffer_have(&pkt
->oid
, &data
)) < 0)
439 if (git_buf_oom(&data
)) {
445 if ((error
= git_pkt_buffer_done(&data
)) < 0)
448 if (t
->cancelled
.val
) {
449 giterr_set(GITERR_NET
, "The fetch was cancelled by the user");
453 if ((error
= git_smart__negotiation_step(&t
->parent
, data
.ptr
, data
.size
)) < 0)
457 git_revwalk_free(walk
);
459 /* Now let's eat up whatever the server gives us */
460 if (!t
->caps
.multi_ack
&& !t
->caps
.multi_ack_detailed
) {
461 pkt_type
= recv_pkt(NULL
, buf
);
465 } else if (pkt_type
!= GIT_PKT_ACK
&& pkt_type
!= GIT_PKT_NAK
) {
466 giterr_set(GITERR_NET
, "Unexpected pkt type");
470 error
= wait_while_ack(buf
);
476 git_revwalk_free(walk
);
481 static int no_sideband(transport_smart
*t
, struct git_odb_writepack
*writepack
, gitno_buffer
*buf
, git_transfer_progress
*stats
)
486 if (t
->cancelled
.val
) {
487 giterr_set(GITERR_NET
, "The fetch was cancelled by the user");
491 if (writepack
->append(writepack
, buf
->data
, buf
->offset
, stats
) < 0)
494 gitno_consume_n(buf
, buf
->offset
);
496 if ((recvd
= gitno_recv(buf
)) < 0)
500 if (writepack
->commit(writepack
, stats
) < 0)
506 struct network_packetsize_payload
508 git_transfer_progress_cb callback
;
510 git_transfer_progress
*stats
;
511 size_t last_fired_bytes
;
514 static int network_packetsize(size_t received
, void *payload
)
516 struct network_packetsize_payload
*npp
= (struct network_packetsize_payload
*)payload
;
518 /* Accumulate bytes */
519 npp
->stats
->received_bytes
+= received
;
521 /* Fire notification if the threshold is reached */
522 if ((npp
->stats
->received_bytes
- npp
->last_fired_bytes
) > NETWORK_XFER_THRESHOLD
) {
523 npp
->last_fired_bytes
= npp
->stats
->received_bytes
;
525 if (npp
->callback(npp
->stats
, npp
->payload
))
532 int git_smart__download_pack(
533 git_transport
*transport
,
534 git_repository
*repo
,
535 git_transfer_progress
*stats
,
536 git_transfer_progress_cb transfer_progress_cb
,
537 void *progress_payload
)
539 transport_smart
*t
= (transport_smart
*)transport
;
540 gitno_buffer
*buf
= &t
->buffer
;
542 struct git_odb_writepack
*writepack
= NULL
;
544 struct network_packetsize_payload npp
= {0};
546 memset(stats
, 0, sizeof(git_transfer_progress
));
548 if (transfer_progress_cb
) {
549 npp
.callback
= transfer_progress_cb
;
550 npp
.payload
= progress_payload
;
552 t
->packetsize_cb
= &network_packetsize
;
553 t
->packetsize_payload
= &npp
;
555 /* We might have something in the buffer already from negotiate_fetch */
556 if (t
->buffer
.offset
> 0 && !t
->cancelled
.val
)
557 if (t
->packetsize_cb(t
->buffer
.offset
, t
->packetsize_payload
))
558 git_atomic_set(&t
->cancelled
, 1);
561 if ((error
= git_repository_odb__weakptr(&odb
, repo
)) < 0 ||
562 ((error
= git_odb_write_pack(&writepack
, odb
, transfer_progress_cb
, progress_payload
)) != 0))
566 * If the remote doesn't support the side-band, we can feed
567 * the data directly to the pack writer. Otherwise, we need to
568 * check which one belongs there.
570 if (!t
->caps
.side_band
&& !t
->caps
.side_band_64k
) {
571 error
= no_sideband(t
, writepack
, buf
, stats
);
578 /* Check cancellation before network call */
579 if (t
->cancelled
.val
) {
585 if ((error
= recv_pkt(&pkt
, buf
)) >= 0) {
586 /* Check cancellation after network call */
587 if (t
->cancelled
.val
) {
590 } else if (pkt
->type
== GIT_PKT_PROGRESS
) {
591 if (t
->progress_cb
) {
592 git_pkt_progress
*p
= (git_pkt_progress
*) pkt
;
593 error
= t
->progress_cb(p
->data
, p
->len
, t
->message_cb_payload
);
595 } else if (pkt
->type
== GIT_PKT_DATA
) {
596 git_pkt_data
*p
= (git_pkt_data
*) pkt
;
599 error
= writepack
->append(writepack
, p
->data
, p
->len
, stats
);
600 } else if (pkt
->type
== GIT_PKT_FLUSH
) {
601 /* A flush indicates the end of the packfile */
614 * Trailing execution of transfer_progress_cb, if necessary...
615 * Only the callback through the npp datastructure currently
616 * updates the last_fired_bytes value. It is possible that
617 * progress has already been reported with the correct
618 * "received_bytes" value, but until (if?) this is unified
619 * then we will report progress again to be sure that the
620 * correct last received_bytes value is reported.
622 if (npp
.callback
&& npp
.stats
->received_bytes
> npp
.last_fired_bytes
) {
623 error
= npp
.callback(npp
.stats
, npp
.payload
);
628 error
= writepack
->commit(writepack
, stats
);
632 writepack
->free(writepack
);
633 if (transfer_progress_cb
) {
634 t
->packetsize_cb
= NULL
;
635 t
->packetsize_payload
= NULL
;
641 static int gen_pktline(git_buf
*buf
, git_push
*push
)
645 char old_id
[GIT_OID_HEXSZ
+1], new_id
[GIT_OID_HEXSZ
+1];
647 old_id
[GIT_OID_HEXSZ
] = '\0'; new_id
[GIT_OID_HEXSZ
] = '\0';
649 git_vector_foreach(&push
->specs
, i
, spec
) {
650 len
= 2*GIT_OID_HEXSZ
+ 7 + strlen(spec
->refspec
.dst
);
654 if (push
->report_status
)
655 len
+= strlen(GIT_CAP_REPORT_STATUS
) + 1;
656 len
+= strlen(GIT_CAP_SIDE_BAND_64K
) + 1;
659 git_oid_fmt(old_id
, &spec
->roid
);
660 git_oid_fmt(new_id
, &spec
->loid
);
662 git_buf_printf(buf
, "%04"PRIxZ
"%s %s %s", len
, old_id
, new_id
, spec
->refspec
.dst
);
665 git_buf_putc(buf
, '\0');
666 /* Core git always starts their capabilities string with a space */
667 if (push
->report_status
) {
668 git_buf_putc(buf
, ' ');
669 git_buf_printf(buf
, GIT_CAP_REPORT_STATUS
);
671 git_buf_putc(buf
, ' ');
672 git_buf_printf(buf
, GIT_CAP_SIDE_BAND_64K
);
675 git_buf_putc(buf
, '\n');
678 git_buf_puts(buf
, "0000");
679 return git_buf_oom(buf
) ? -1 : 0;
682 static int add_push_report_pkt(git_push
*push
, git_pkt
*pkt
)
688 status
= git__calloc(1, sizeof(push_status
));
689 GITERR_CHECK_ALLOC(status
);
691 status
->ref
= git__strdup(((git_pkt_ok
*)pkt
)->ref
);
693 git_vector_insert(&push
->status
, status
) < 0) {
694 git_push_status_free(status
);
699 status
= git__calloc(1, sizeof(push_status
));
700 GITERR_CHECK_ALLOC(status
);
701 status
->ref
= git__strdup(((git_pkt_ng
*)pkt
)->ref
);
702 status
->msg
= git__strdup(((git_pkt_ng
*)pkt
)->msg
);
703 if (!status
->ref
|| !status
->msg
||
704 git_vector_insert(&push
->status
, status
) < 0) {
705 git_push_status_free(status
);
710 push
->unpack_ok
= ((git_pkt_unpack
*)pkt
)->unpack_ok
;
715 giterr_set(GITERR_NET
, "report-status: protocol error");
722 static int add_push_report_sideband_pkt(git_push
*push
, git_pkt_data
*data_pkt
)
725 const char *line
= data_pkt
->data
, *line_end
;
726 size_t line_len
= data_pkt
->len
;
729 while (line_len
> 0) {
730 error
= git_pkt_parse_line(&pkt
, line
, &line_end
, line_len
);
735 /* Advance in the buffer */
736 line_len
-= (line_end
- line
);
739 error
= add_push_report_pkt(push
, pkt
);
743 if (error
< 0 && error
!= GIT_ITEROVER
)
750 static int parse_report(transport_smart
*transport
, git_push
*push
)
753 const char *line_end
= NULL
;
754 gitno_buffer
*buf
= &transport
->buffer
;
759 error
= git_pkt_parse_line(&pkt
, buf
->data
,
760 &line_end
, buf
->offset
);
764 if (error
< 0 && error
!= GIT_EBUFS
)
767 if (error
== GIT_EBUFS
) {
768 if ((recvd
= gitno_recv(buf
)) < 0)
772 giterr_set(GITERR_NET
, "Early EOF");
778 gitno_consume(buf
, line_end
);
784 /* This is a sideband packet which contains other packets */
785 error
= add_push_report_sideband_pkt(push
, (git_pkt_data
*)pkt
);
788 giterr_set(GITERR_NET
, "report-status: Error reported: %s",
789 ((git_pkt_err
*)pkt
)->error
);
792 case GIT_PKT_PROGRESS
:
793 if (transport
->progress_cb
) {
794 git_pkt_progress
*p
= (git_pkt_progress
*) pkt
;
795 error
= transport
->progress_cb(p
->data
, p
->len
, transport
->message_cb_payload
);
799 error
= add_push_report_pkt(push
, pkt
);
805 /* add_push_report_pkt returns GIT_ITEROVER when it receives a flush */
806 if (error
== GIT_ITEROVER
)
814 static int add_ref_from_push_spec(git_vector
*refs
, push_spec
*push_spec
)
816 git_pkt_ref
*added
= git__calloc(1, sizeof(git_pkt_ref
));
817 GITERR_CHECK_ALLOC(added
);
819 added
->type
= GIT_PKT_REF
;
820 git_oid_cpy(&added
->head
.oid
, &push_spec
->loid
);
821 added
->head
.name
= git__strdup(push_spec
->refspec
.dst
);
823 if (!added
->head
.name
||
824 git_vector_insert(refs
, added
) < 0) {
825 git_pkt_free((git_pkt
*)added
);
832 static int update_refs_from_report(
834 git_vector
*push_specs
,
835 git_vector
*push_report
)
838 push_spec
*push_spec
;
839 push_status
*push_status
;
840 size_t i
, j
, refs_len
;
843 /* For each push spec we sent to the server, we should have
844 * gotten back a status packet in the push report */
845 if (push_specs
->length
!= push_report
->length
) {
846 giterr_set(GITERR_NET
, "report-status: protocol error");
850 /* We require that push_specs be sorted with push_spec_rref_cmp,
851 * and that push_report be sorted with push_status_ref_cmp */
852 git_vector_sort(push_specs
);
853 git_vector_sort(push_report
);
855 git_vector_foreach(push_specs
, i
, push_spec
) {
856 push_status
= git_vector_get(push_report
, i
);
858 /* For each push spec we sent to the server, we should have
859 * gotten back a status packet in the push report which matches */
860 if (strcmp(push_spec
->refspec
.dst
, push_status
->ref
)) {
861 giterr_set(GITERR_NET
, "report-status: protocol error");
866 /* We require that refs be sorted with ref_name_cmp */
867 git_vector_sort(refs
);
869 refs_len
= refs
->length
;
871 /* Merge join push_specs with refs */
872 while (i
< push_specs
->length
&& j
< refs_len
) {
873 push_spec
= git_vector_get(push_specs
, i
);
874 push_status
= git_vector_get(push_report
, i
);
875 ref
= git_vector_get(refs
, j
);
877 cmp
= strcmp(push_spec
->refspec
.dst
, ref
->head
.name
);
879 /* Iterate appropriately */
886 add_ref_from_push_spec(refs
, push_spec
) < 0)
889 /* Update case, delete case */
892 git_oid_cpy(&ref
->head
.oid
, &push_spec
->loid
);
895 for (; i
< push_specs
->length
; i
++) {
896 push_spec
= git_vector_get(push_specs
, i
);
897 push_status
= git_vector_get(push_report
, i
);
900 if (!push_status
->msg
&&
901 add_ref_from_push_spec(refs
, push_spec
) < 0)
905 /* Remove any refs which we updated to have a zero OID. */
906 git_vector_rforeach(refs
, i
, ref
) {
907 if (git_oid_iszero(&ref
->head
.oid
)) {
908 git_vector_remove(refs
, i
);
909 git_pkt_free((git_pkt
*)ref
);
913 git_vector_sort(refs
);
918 struct push_packbuilder_payload
920 git_smart_subtransport_stream
*stream
;
922 git_push_transfer_progress cb
;
925 double last_progress_report_time
;
928 static int stream_thunk(void *buf
, size_t size
, void *data
)
931 struct push_packbuilder_payload
*payload
= data
;
933 if ((error
= payload
->stream
->write(payload
->stream
, (const char *)buf
, size
)) < 0)
937 double current_time
= git__timer();
938 payload
->last_bytes
+= size
;
940 if ((current_time
- payload
->last_progress_report_time
) >= MIN_PROGRESS_UPDATE_INTERVAL
) {
941 payload
->last_progress_report_time
= current_time
;
942 error
= payload
->cb(payload
->pb
->nr_written
, payload
->pb
->nr_objects
, payload
->last_bytes
, payload
->cb_payload
);
949 int git_smart__push(git_transport
*transport
, git_push
*push
)
951 transport_smart
*t
= (transport_smart
*)transport
;
952 struct push_packbuilder_payload packbuilder_payload
= {0};
953 git_buf pktline
= GIT_BUF_INIT
;
954 int error
= 0, need_pack
= 0;
958 packbuilder_payload
.pb
= push
->pb
;
960 if (push
->transfer_progress_cb
) {
961 packbuilder_payload
.cb
= push
->transfer_progress_cb
;
962 packbuilder_payload
.cb_payload
= push
->transfer_progress_cb_payload
;
967 git_remote_head
*head
;
968 char hex
[GIT_OID_HEXSZ
+1]; hex
[GIT_OID_HEXSZ
] = '\0';
970 git_vector_foreach(&push
->remote
->refs
, i
, head
) {
971 git_oid_fmt(hex
, &head
->oid
);
972 fprintf(stderr
, "%s (%s)\n", hex
, head
->name
);
975 git_vector_foreach(&push
->specs
, i
, spec
) {
976 git_oid_fmt(hex
, &spec
->roid
);
977 fprintf(stderr
, "%s (%s) -> ", hex
, spec
->lref
);
978 git_oid_fmt(hex
, &spec
->loid
);
979 fprintf(stderr
, "%s (%s)\n", hex
, spec
->rref
?
980 spec
->rref
: spec
->lref
);
986 * Figure out if we need to send a packfile; which is in all
987 * cases except when we only send delete commands
989 git_vector_foreach(&push
->specs
, i
, spec
) {
990 if (spec
->refspec
.src
&& spec
->refspec
.src
[0] != '\0') {
996 if ((error
= git_smart__get_push_stream(t
, &packbuilder_payload
.stream
)) < 0 ||
997 (error
= gen_pktline(&pktline
, push
)) < 0 ||
998 (error
= packbuilder_payload
.stream
->write(packbuilder_payload
.stream
, git_buf_cstr(&pktline
), git_buf_len(&pktline
))) < 0)
1002 (error
= git_packbuilder_foreach(push
->pb
, &stream_thunk
, &packbuilder_payload
)) < 0)
1005 /* If we sent nothing or the server doesn't support report-status, then
1006 * we consider the pack to have been unpacked successfully */
1007 if (!push
->specs
.length
|| !push
->report_status
)
1008 push
->unpack_ok
= 1;
1009 else if ((error
= parse_report(t
, push
)) < 0)
1012 /* If progress is being reported write the final report */
1013 if (push
->transfer_progress_cb
) {
1014 error
= push
->transfer_progress_cb(
1015 push
->pb
->nr_written
,
1016 push
->pb
->nr_objects
,
1017 packbuilder_payload
.last_bytes
,
1018 push
->transfer_progress_cb_payload
);
1024 if (push
->status
.length
) {
1025 error
= update_refs_from_report(&t
->refs
, &push
->specs
, &push
->status
);
1029 error
= git_smart__update_heads(t
, NULL
);
1033 git_buf_free(&pktline
);