Commit 9effa2fb72f20332c2c8a83540bb224a32e0265b

Jacques Germishuys 2014-04-20T19:19:13

Fire progress callbacks also for pushes. It's not very useful to only know that a pre-receive hook has declined a push, you probably want to know why.

diff --git a/include/git2/remote.h b/include/git2/remote.h
index d57321f..88040d4 100644
--- a/include/git2/remote.h
+++ b/include/git2/remote.h
@@ -455,7 +455,8 @@ struct git_remote_callbacks {
 	/**
 	 * Textual progress from the remote. Text send over the
 	 * progress side-band will be passed to this function (this is
-	 * the 'counting objects' output.
+	 * the 'counting objects' output. This callback should return a value less
+	 * than zero to cancel the operation.
 	 */
 	int (*progress)(const char *str, int len, void *data);
 
diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c
index 7e8fcdd..e5b56ea 100644
--- a/src/transports/smart_protocol.c
+++ b/src/transports/smart_protocol.c
@@ -478,7 +478,7 @@ int git_smart__download_pack(
 	git_transport *transport,
 	git_repository *repo,
 	git_transfer_progress *stats,
-	git_transfer_progress_callback progress_cb,
+	git_transfer_progress_callback transfer_progress_cb,
 	void *progress_payload)
 {
 	transport_smart *t = (transport_smart *)transport;
@@ -490,8 +490,8 @@ int git_smart__download_pack(
 
 	memset(stats, 0, sizeof(git_transfer_progress));
 
-	if (progress_cb) {
-		npp.callback = progress_cb;
+	if (transfer_progress_cb) {
+		npp.callback = transfer_progress_cb;
 		npp.payload = progress_payload;
 		npp.stats = stats;
 		t->packetsize_cb = &network_packetsize;
@@ -504,7 +504,7 @@ int git_smart__download_pack(
 	}
 
 	if ((error = git_repository_odb__weakptr(&odb, repo)) < 0 ||
-		((error = git_odb_write_pack(&writepack, odb, progress_cb, progress_payload)) != 0))
+		((error = git_odb_write_pack(&writepack, odb, transfer_progress_cb, progress_payload)) != 0))
 		goto done;
 
 	/*
@@ -518,7 +518,7 @@ int git_smart__download_pack(
 	}
 
 	do {
-		git_pkt *pkt;
+		git_pkt *pkt = NULL;
 
 		/* Check cancellation before network call */
 		if (t->cancelled.val) {
@@ -527,40 +527,34 @@ int git_smart__download_pack(
 			goto done;
 		}
 
-		if ((error = recv_pkt(&pkt, buf)) < 0)
-			goto done;
-
-		/* Check cancellation after network call */
-		if (t->cancelled.val) {
-			giterr_clear();
-			error = GIT_EUSER;
-			goto done;
+		if ((error = recv_pkt(&pkt, buf)) >= 0) {
+			/* Check cancellation after network call */
+			if (t->cancelled.val) {
+				giterr_clear();
+				error = GIT_EUSER;
+			} else if (pkt->type == GIT_PKT_PROGRESS) {
+				if (t->progress_cb) {
+					git_pkt_progress *p = (git_pkt_progress *) pkt;
+					error = t->progress_cb(p->data, p->len, t->message_cb_payload);
+				}
+			} else if (pkt->type == GIT_PKT_DATA) {
+				git_pkt_data *p = (git_pkt_data *) pkt;
+				error = writepack->append(writepack, p->data, p->len, stats);
+			} else if (pkt->type == GIT_PKT_FLUSH) {
+				/* A flush indicates the end of the packfile */
+				git__free(pkt);
+				break;
+			}
 		}
 
-		if (pkt->type == GIT_PKT_PROGRESS) {
-			if (t->progress_cb) {
-				git_pkt_progress *p = (git_pkt_progress *) pkt;
-				error = t->progress_cb(p->data, p->len, t->message_cb_payload);
-				if (error)
-					goto done;
-			}
-			git__free(pkt);
-		} else if (pkt->type == GIT_PKT_DATA) {
-			git_pkt_data *p = (git_pkt_data *) pkt;
-			error = writepack->append(writepack, p->data, p->len, stats);
+		git__free(pkt);
+		if (error < 0)
+			goto done;
 
-			git__free(pkt);
-			if (error != 0)
-				goto done;
-		} else if (pkt->type == GIT_PKT_FLUSH) {
-			/* A flush indicates the end of the packfile */
-			git__free(pkt);
-			break;
-		}
 	} while (1);
 
 	/*
-	 * Trailing execution of progress_cb, if necessary...
+	 * Trailing execution of transfer_progress_cb, if necessary...
 	 * Only the callback through the npp datastructure currently
 	 * updates the last_fired_bytes value. It is possible that
 	 * progress has already been reported with the correct
@@ -579,7 +573,7 @@ int git_smart__download_pack(
 done:
 	if (writepack)
 		writepack->free(writepack);
-	if (progress_cb) {
+	if (transfer_progress_cb) {
 		t->packetsize_cb = NULL;
 		t->packetsize_payload = NULL;
 	}
@@ -696,10 +690,11 @@ static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt)
 	return 0;
 }
 
-static int parse_report(gitno_buffer *buf, git_push *push)
+static int parse_report(transport_smart *transport, git_push *push)
 {
 	git_pkt *pkt = NULL;
 	const char *line_end = NULL;
+	gitno_buffer *buf = &transport->buffer;
 	int error, recvd;
 
 	for (;;) {
@@ -738,6 +733,10 @@ static int parse_report(gitno_buffer *buf, git_push *push)
 				error = -1;
 				break;
 			case GIT_PKT_PROGRESS:
+				if (transport->progress_cb) {
+					git_pkt_progress *p = (git_pkt_progress *) pkt;
+					error = transport->progress_cb(p->data, p->len, transport->message_cb_payload);
+				}
 				break;
 			default:
 				error = add_push_report_pkt(push, pkt);
@@ -953,7 +952,7 @@ int git_smart__push(git_transport *transport, git_push *push)
 	 * we consider the pack to have been unpacked successfully */
 	if (!push->specs.length || !push->report_status)
 		push->unpack_ok = 1;
-	else if ((error = parse_report(&t->buffer, push)) < 0)
+	else if ((error = parse_report(t, push)) < 0)
 		goto done;
 
 	/* If progress is being reported write the final report */