Commit bffa852f89268390d6bc3e6f99f5f0cccdc88f63

Carlos Martín Nieto 2012-07-13T12:01:11

indexer: recognize and mark when all of the packfile has been downloaded We can't always rely on the network telling us when the download is finished. Recognize it from the indexer itself.

diff --git a/examples/network/fetch.c b/examples/network/fetch.c
index 52e0412..372c858 100644
--- a/examples/network/fetch.c
+++ b/examples/network/fetch.c
@@ -96,7 +96,7 @@ int fetch(git_repository *repo, int argc, char **argv)
 	// the download rate.
 	do {
 		usleep(10000);
-		printf("\rReceived %d/%d objects in %zu bytes", stats.processed, stats.total, bytes);
+		printf("\rReceived %d/%d objects (%d) in %d bytes", stats.received, stats.total, stats.processed, bytes);
 	} while (!data.finished);
 
 	if (data.ret < 0)
diff --git a/include/git2/indexer.h b/include/git2/indexer.h
index d300ba0..92d1d9e 100644
--- a/include/git2/indexer.h
+++ b/include/git2/indexer.h
@@ -19,6 +19,8 @@ GIT_BEGIN_DECL
 typedef struct git_indexer_stats {
 	unsigned int total;
 	unsigned int processed;
+	unsigned int received;
+	unsigned int data_received;
 } git_indexer_stats;
 
 
diff --git a/src/fetch.c b/src/fetch.c
index d96ac77..eb13701 100644
--- a/src/fetch.c
+++ b/src/fetch.c
@@ -324,7 +324,10 @@ int git_fetch__download_pack(
 			goto on_error;
 
 		*bytes += recvd;
-	} while(recvd > 0);
+	} while(recvd > 0 && !stats->data_received);
+
+	if (!stats->data_received)
+		giterr_set(GITERR_NET, "Early EOF while downloading packfile");
 
 	if (git_indexer_stream_finalize(idx, stats))
 		goto on_error;
diff --git a/src/indexer.c b/src/indexer.c
index 797a582..30c6469 100644
--- a/src/indexer.c
+++ b/src/indexer.c
@@ -324,8 +324,8 @@ int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t siz
 		if (git_vector_init(&idx->deltas, (unsigned int)(idx->nr_objects / 2), NULL) < 0)
 			return -1;
 
+		memset(stats, 0, sizeof(git_indexer_stats));
 		stats->total = (unsigned int)idx->nr_objects;
-		stats->processed = 0;
 	}
 
 	/* Now that we have data in the pack, let's try to parse it */
@@ -361,6 +361,7 @@ int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t siz
 			if (error < 0)
 				return error;
 
+			stats->received++;
 			continue;
 		}
 
@@ -379,8 +380,17 @@ int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t siz
 		git__free(obj.data);
 
 		stats->processed = (unsigned int)++processed;
+		stats->received++;
 	}
 
+	/*
+	 * If we've received all of the objects and our packfile is
+	 * one hash beyond the end of the last object, all of the
+	 * packfile is here.
+	 */
+	if (stats->received == idx->nr_objects && idx->pack->mwf.size >= idx->off + 20)
+		stats->data_received = 1;
+
 	return 0;
 
 on_error: