From: Junio C Hamano Date: Wed, 18 Nov 2009 06:03:20 +0000 (-0800) Subject: Merge branch 'np/maint-sideband-favor-status' X-Git-Tag: v1.6.6-rc0~38 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/e36e6c00cd60130f8792319a5aa0f56d2da68e14?ds=inline;hp=-c Merge branch 'np/maint-sideband-favor-status' * np/maint-sideband-favor-status: give priority to progress messages --- e36e6c00cd60130f8792319a5aa0f56d2da68e14 diff --combined builtin-upload-archive.c index c4cd1e1327,58f6b8f377..29446e84cc --- a/builtin-upload-archive.c +++ b/builtin-upload-archive.c @@@ -35,7 -35,7 +35,7 @@@ static int run_upload_archive(int argc strcpy(buf, argv[1]); /* enter-repo smudges its argument */ if (!enter_repo(buf, 0)) - die("not a git archive"); + die("'%s' does not appear to be a git repository", buf); /* put received options in sent_argv[] */ sent_argc = 1; @@@ -132,7 -132,6 +132,6 @@@ int cmd_upload_archive(int argc, const while (1) { struct pollfd pfd[2]; - ssize_t processed[2] = { 0, 0 }; int status; pfd[0].fd = fd1[0]; @@@ -147,15 -146,14 +146,14 @@@ } continue; } - if (pfd[0].revents & POLLIN) - /* Data stream ready */ - processed[0] = process_input(pfd[0].fd, 1); if (pfd[1].revents & POLLIN) /* Status stream ready */ - processed[1] = process_input(pfd[1].fd, 2); - /* Always finish to read data when available */ - if (processed[0] || processed[1]) - continue; + if (process_input(pfd[1].fd, 2)) + continue; + if (pfd[0].revents & POLLIN) + /* Data stream ready */ + if (process_input(pfd[0].fd, 1)) + continue; if (waitpid(writer, &status, 0) < 0) error_clnt("%s", lostchild); diff --combined upload-pack.c index 38ddac2e86,8734f1d1b9..953ebe1a60 --- a/upload-pack.c +++ b/upload-pack.c @@@ -28,11 -28,9 +28,11 @@@ static unsigned long oldest_have static int multi_ack, nr_our_refs; static int use_thin_pack, use_ofs_delta, use_include_tag; -static int no_progress; +static int no_progress, daemon_mode; +static int shallow_nr; static struct object_array have_obj; static struct object_array want_obj; +static struct object_array extra_edge_obj; static unsigned int timeout; /* 0 for no sideband, * otherwise maximum packet size (up to 65520 bytes). @@@ -68,7 -66,7 +68,7 @@@ static ssize_t send_client_data(int fd } static FILE *pack_pipe = NULL; -static void show_commit(struct commit *commit) +static void show_commit(struct commit *commit, void *data) { if (commit->object.flags & BOUNDARY) fputc('-', pack_pipe); @@@ -108,7 -106,9 +108,7 @@@ static int do_rev_list(int fd, void *cr int i; struct rev_info revs; - pack_pipe = fdopen(fd, "w"); - if (create_full_pack) - use_thin_pack = 0; /* no point doing it */ + pack_pipe = xfdopen(fd, "w"); init_revisions(&revs, NULL); revs.tag_objects = 1; revs.tree_objects = 1; @@@ -136,76 -136,14 +136,76 @@@ if (prepare_revision_walk(&revs)) die("revision walk setup failed"); mark_edges_uninteresting(revs.commits, &revs, show_edge); - traverse_commit_list(&revs, show_commit, show_object); + if (use_thin_pack) + for (i = 0; i < extra_edge_obj.nr; i++) + fprintf(pack_pipe, "-%s\n", sha1_to_hex( + extra_edge_obj.objects[i].item->sha1)); + traverse_commit_list(&revs, show_commit, show_object, NULL); fflush(pack_pipe); fclose(pack_pipe); return 0; } +static int feed_msg_to_hook(int fd, const char *fmt, ...) +{ + int cnt; + char buf[1024]; + va_list params; + + va_start(params, fmt); + cnt = vsprintf(buf, fmt, params); + va_end(params); + return write_in_full(fd, buf, cnt) != cnt; +} + +static int feed_obj_to_hook(const char *label, struct object_array *oa, int i, int fd) +{ + return feed_msg_to_hook(fd, "%s %s\n", label, + sha1_to_hex(oa->objects[i].item->sha1)); +} + +static int run_post_upload_pack_hook(size_t total, struct timeval *tv) +{ + const char *argv[2]; + struct child_process proc; + int err, i; + + argv[0] = "hooks/post-upload-pack"; + argv[1] = NULL; + + if (access(argv[0], X_OK) < 0) + return 0; + + memset(&proc, 0, sizeof(proc)); + proc.argv = argv; + proc.in = -1; + proc.stdout_to_stderr = 1; + err = start_command(&proc); + if (err) + return err; + for (i = 0; !err && i < want_obj.nr; i++) + err |= feed_obj_to_hook("want", &want_obj, i, proc.in); + for (i = 0; !err && i < have_obj.nr; i++) + err |= feed_obj_to_hook("have", &have_obj, i, proc.in); + if (!err) + err |= feed_msg_to_hook(proc.in, "time %ld.%06ld\n", + (long)tv->tv_sec, (long)tv->tv_usec); + if (!err) + err |= feed_msg_to_hook(proc.in, "size %ld\n", (long)total); + if (!err) + err |= feed_msg_to_hook(proc.in, "kind %s\n", + (nr_our_refs == want_obj.nr && !have_obj.nr) + ? "clone" : "fetch"); + if (close(proc.in)) + err = 1; + if (finish_command(&proc)) + err = 1; + return err; +} + static void create_pack_file(void) { + struct timeval start_tv, tv; struct async rev_list; struct child_process pack_objects; int create_full_pack = (nr_our_refs == want_obj.nr && !have_obj.nr); @@@ -213,27 -151,17 +213,27 @@@ char abort_msg[] = "aborting due to possible repository " "corruption on the remote side."; int buffered = -1; - ssize_t sz; + ssize_t sz, total_sz; const char *argv[10]; int arg = 0; - rev_list.proc = do_rev_list; - /* .data is just a boolean: any non-NULL value will do */ - rev_list.data = create_full_pack ? &rev_list : NULL; - if (start_async(&rev_list)) - die("git upload-pack: unable to fork git-rev-list"); + gettimeofday(&start_tv, NULL); + total_sz = 0; + if (shallow_nr) { + rev_list.proc = do_rev_list; + rev_list.data = 0; + if (start_async(&rev_list)) + die("git upload-pack: unable to fork git-rev-list"); + argv[arg++] = "pack-objects"; + } else { + argv[arg++] = "pack-objects"; + argv[arg++] = "--revs"; + if (create_full_pack) + argv[arg++] = "--all"; + else if (use_thin_pack) + argv[arg++] = "--thin"; + } - argv[arg++] = "pack-objects"; argv[arg++] = "--stdout"; if (!no_progress) argv[arg++] = "--progress"; @@@ -244,7 -172,7 +244,7 @@@ argv[arg++] = NULL; memset(&pack_objects, 0, sizeof(pack_objects)); - pack_objects.in = rev_list.out; /* start_command closes it */ + pack_objects.in = shallow_nr ? rev_list.out : -1; pack_objects.out = -1; pack_objects.err = -1; pack_objects.git_cmd = 1; @@@ -253,24 -181,6 +253,24 @@@ if (start_command(&pack_objects)) die("git upload-pack: unable to fork git-pack-objects"); + /* pass on revisions we (don't) want */ + if (!shallow_nr) { + FILE *pipe_fd = xfdopen(pack_objects.in, "w"); + if (!create_full_pack) { + int i; + for (i = 0; i < want_obj.nr; i++) + fprintf(pipe_fd, "%s\n", sha1_to_hex(want_obj.objects[i].item->sha1)); + fprintf(pipe_fd, "--not\n"); + for (i = 0; i < have_obj.nr; i++) + fprintf(pipe_fd, "%s\n", sha1_to_hex(have_obj.objects[i].item->sha1)); + } + + fprintf(pipe_fd, "\n"); + fflush(pipe_fd); + fclose(pipe_fd); + } + + /* We read from pack_objects.err to capture stderr output for * progress bar, and pack_objects.out to capture the pack data. */ @@@ -308,6 -218,23 +308,23 @@@ } continue; } + if (0 <= pe && (pfd[pe].revents & (POLLIN|POLLHUP))) { + /* Status ready; we ship that in the side-band + * or dump to the standard error. + */ + sz = xread(pack_objects.err, progress, + sizeof(progress)); + if (0 < sz) + send_client_data(2, progress, sz); + else if (sz == 0) { + close(pack_objects.err); + pack_objects.err = -1; + } + else + goto fail; + /* give priority to status messages */ + continue; + } if (0 <= pu && (pfd[pu].revents & (POLLIN|POLLHUP))) { /* Data ready; we keep the last byte to ourselves * in case we detect broken rev-list, so that we @@@ -327,7 -254,7 +344,7 @@@ sz = xread(pack_objects.out, cp, sizeof(data) - outsz); if (0 < sz) - ; + total_sz += sz; else if (sz == 0) { close(pack_objects.out); pack_objects.out = -1; @@@ -345,28 -272,13 +362,13 @@@ if (sz < 0) goto fail; } - if (0 <= pe && (pfd[pe].revents & (POLLIN|POLLHUP))) { - /* Status ready; we ship that in the side-band - * or dump to the standard error. - */ - sz = xread(pack_objects.err, progress, - sizeof(progress)); - if (0 < sz) - send_client_data(2, progress, sz); - else if (sz == 0) { - close(pack_objects.err); - pack_objects.err = -1; - } - else - goto fail; - } } if (finish_command(&pack_objects)) { error("git upload-pack: git-pack-objects died with error."); goto fail; } - if (finish_async(&rev_list)) + if (shallow_nr && finish_async(&rev_list)) goto fail; /* error was already reported */ /* flush the data */ @@@ -379,16 -291,6 +381,16 @@@ } if (use_sideband) packet_flush(1); + + gettimeofday(&tv, NULL); + tv.tv_sec -= start_tv.tv_sec; + if (tv.tv_usec < start_tv.tv_usec) { + tv.tv_sec--; + tv.tv_usec += 1000000; + } + tv.tv_usec -= start_tv.tv_usec; + if (run_post_upload_pack_hook(total_sz, &tv)) + warning("post-upload-hook failed"); return; fail: @@@ -499,11 -401,12 +501,11 @@@ static int get_common_commits(void static char line[1000]; unsigned char sha1[20]; char hex[41], last_hex[41]; - int len; save_commit_buffer = 0; - for(;;) { - len = packet_read_line(0, line, sizeof(line)); + for (;;) { + int len = packet_read_line(0, line, sizeof(line)); reset_timeout(); if (!len) { @@@ -511,7 -414,7 +513,7 @@@ packet_write(1, "NAK\n"); continue; } - len = strip(line, len); + strip(line, len); if (!prefixcmp(line, "have ")) { switch (got_sha1(line+5, sha1)) { case -1: /* they have what we do not */ @@@ -551,9 -454,8 +553,9 @@@ static void receive_needs(void static char line[1000]; int len, depth = 0; + shallow_nr = 0; if (debug_fd) - write_in_full(debug_fd, "#S\n", 3); + write_str_in_full(debug_fd, "#S\n"); for (;;) { struct object *o; unsigned char sha1_buf[20]; @@@ -567,6 -469,7 +569,6 @@@ if (!prefixcmp(line, "shallow ")) { unsigned char sha1[20]; struct object *object; - use_thin_pack = 0; if (get_sha1(line + 8, sha1)) die("invalid shallow line: %s", line); object = parse_object(sha1); @@@ -578,6 -481,7 +580,6 @@@ } if (!prefixcmp(line, "deepen ")) { char *end; - use_thin_pack = 0; depth = strtol(line + 7, &end, 0); if (end == line + 7 || depth <= 0) die("Invalid deepen: %s", line); @@@ -619,11 -523,7 +621,11 @@@ } } if (debug_fd) - write_in_full(debug_fd, "#E\n", 3); + write_str_in_full(debug_fd, "#E\n"); + + if (!use_sideband && daemon_mode) + no_progress = 1; + if (depth == 0 && shallows.nr == 0) return; if (depth > 0) { @@@ -637,7 -537,6 +639,7 @@@ packet_write(1, "shallow %s", sha1_to_hex(object->sha1)); register_shallow(object->sha1); + shallow_nr++; } result = result->next; } @@@ -660,7 -559,6 +662,7 @@@ NULL, &want_obj); parents = parents->next; } + add_object_array(object, NULL, &extra_edge_obj); } /* make sure commit traversal conforms to client */ register_shallow(object->sha1); @@@ -672,8 -570,6 +674,8 @@@ for (i = 0; i < shallows.nr; i++) register_shallow(shallows.objects[i].item->sha1); } + + shallow_nr += shallows.nr; free(shallows.objects); } @@@ -725,7 -621,6 +727,7 @@@ int main(int argc, char **argv int strict = 0; git_extract_argv0_path(argv[0]); + read_replace_refs = 0; for (i = 1; i < argc; i++) { char *arg = argv[i]; @@@ -738,7 -633,6 +740,7 @@@ } if (!prefixcmp(arg, "--timeout=")) { timeout = atoi(arg+10); + daemon_mode = 1; continue; } if (!strcmp(arg, "--")) { @@@ -755,7 -649,7 +757,7 @@@ dir = argv[i]; if (!enter_repo(dir, strict)) - die("'%s': unable to chdir or not a git archive", dir); + die("'%s' does not appear to be a git repository", dir); if (is_repository_shallow()) die("attempt to fetch/clone from a shallow repository"); if (getenv("GIT_DEBUG_SEND_PACK"))