X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=fetch-clone.c;h=da1b3ffbaa13ee4dfc8d080759b3f936850b7647;hb=ae448e3854d8b6e7e37aa88fa3917f5dd97f3210;hp=f46fe6ecbb775b965fb6110dc81746cd5bb230c5;hpb=92e802c6ccb96d1b5e8561b0a136d43d82253293;p=git.git diff --git a/fetch-clone.c b/fetch-clone.c index f46fe6ec..da1b3ffb 100644 --- a/fetch-clone.c +++ b/fetch-clone.c @@ -1,5 +1,7 @@ #include "cache.h" +#include "exec_cmd.h" #include +#include static int finish_pack(const char *pack_tmp_name, const char *me) { @@ -27,8 +29,7 @@ static int finish_pack(const char *pack_tmp_name, const char *me) dup2(pipe_fd[1], 1); close(pipe_fd[0]); close(pipe_fd[1]); - execlp("git-index-pack","git-index-pack", - "-o", idx, pack_tmp_name, NULL); + execl_git_cmd("index-pack", "-o", idx, pack_tmp_name, NULL); error("cannot exec git-index-pack <%s> <%s>", idx, pack_tmp_name); exit(1); @@ -105,8 +106,7 @@ int receive_unpack_pack(int fd[2], const char *me, int quiet) dup2(fd[0], 0); close(fd[0]); close(fd[1]); - execlp("git-unpack-objects", "git-unpack-objects", - quiet ? "-q" : NULL, NULL); + execl_git_cmd("unpack-objects", quiet ? "-q" : NULL, NULL); die("git-unpack-objects exec failed"); } close(fd[0]); @@ -130,10 +130,35 @@ int receive_unpack_pack(int fd[2], const char *me, int quiet) die("git-unpack-objects died of unnatural causes %d", status); } -int receive_keep_pack(int fd[2], const char *me) +/* + * We average out the download speed over this many "events", where + * an event is a minimum of about half a second. That way, we get + * a reasonably stable number. + */ +#define NR_AVERAGE (4) + +/* + * A "binary msec" is a power-of-two-msec, aka 1/1024th of a second. + * Keeing the time in that format means that "bytes / msecs" means + * is the same as kB/s (modulo rounding). + * + * 1000512 is a magic number (usecs in a second, rounded up by half + * of 1024, to make "rounding" come out right ;) + */ +#define usec_to_binarymsec(x) ((int)(x) / (1000512 >> 10)) + +int receive_keep_pack(int fd[2], const char *me, int quiet) { char tmpfile[PATH_MAX]; int ofd, ifd; + unsigned long total; + static struct timeval prev_tv; + struct average { + unsigned long bytes; + unsigned long time; + } download[NR_AVERAGE] = { {0, 0}, }; + unsigned long avg_bytes, avg_time; + int idx = 0; ifd = fd[0]; snprintf(tmpfile, sizeof(tmpfile), @@ -142,6 +167,10 @@ int receive_keep_pack(int fd[2], const char *me) if (ofd < 0) return error("unable to create temporary file %s", tmpfile); + gettimeofday(&prev_tv, NULL); + total = 0; + avg_bytes = 0; + avg_time = 0; while (1) { char buf[8192]; ssize_t sz, wsz, pos; @@ -149,10 +178,13 @@ int receive_keep_pack(int fd[2], const char *me) if (sz == 0) break; if (sz < 0) { - error("error reading pack (%s)", strerror(errno)); - close(ofd); - unlink(tmpfile); - return -1; + if (errno != EINTR && errno != EAGAIN) { + error("error reading pack (%s)", strerror(errno)); + close(ofd); + unlink(tmpfile); + return -1; + } + sz = 0; } pos = 0; while (pos < sz) { @@ -166,6 +198,40 @@ int receive_keep_pack(int fd[2], const char *me) } pos += wsz; } + total += sz; + if (!quiet) { + static unsigned long last; + struct timeval tv; + unsigned long diff = total - last; + /* not really "msecs", but a power-of-two millisec (1/1024th of a sec) */ + unsigned long msecs; + + gettimeofday(&tv, NULL); + msecs = tv.tv_sec - prev_tv.tv_sec; + msecs <<= 10; + msecs += usec_to_binarymsec(tv.tv_usec - prev_tv.tv_usec); + + if (msecs > 500) { + prev_tv = tv; + last = total; + + /* Update averages ..*/ + avg_bytes += diff; + avg_time += msecs; + avg_bytes -= download[idx].bytes; + avg_time -= download[idx].time; + download[idx].bytes = diff; + download[idx].time = msecs; + idx++; + if (idx >= NR_AVERAGE) + idx = 0; + + fprintf(stderr, "%4lu.%03luMB (%lu kB/s) \r", + total >> 20, + 1000*((total >> 10) & 1023)>>10, + avg_bytes / avg_time ); + } + } } close(ofd); return finish_pack(tmpfile, me);