From: Junio C Hamano Date: Mon, 7 Sep 2009 22:24:47 +0000 (-0700) Subject: Merge branch 'jc/upload-pack-hook' X-Git-Tag: v1.6.5-rc0~4 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/e4d1afbcf2e39a997ae90befd629ee53e444c4c9?ds=inline;hp=-c Merge branch 'jc/upload-pack-hook' * jc/upload-pack-hook: upload-pack: feed "kind [clone|fetch]" to post-upload-pack hook upload-pack: add a trigger for post-upload-pack hook --- e4d1afbcf2e39a997ae90befd629ee53e444c4c9 diff --combined upload-pack.c index 25e222ffaa,8e82179c93..c77ab710c4 --- a/upload-pack.c +++ b/upload-pack.c @@@ -32,7 -32,6 +32,7 @@@ 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). @@@ -136,18 -135,72 +136,76 @@@ static int do_rev_list(int fd, void *cr if (prepare_revision_walk(&revs)) die("revision walk setup failed"); mark_edges_uninteresting(revs.commits, &revs, show_edge); + 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); @@@ -155,10 -208,12 +213,12 @@@ 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; + gettimeofday(&start_tv, NULL); + total_sz = 0; if (shallow_nr) { rev_list.proc = do_rev_list; rev_list.data = 0; @@@ -267,7 -322,7 +327,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; @@@ -319,6 -374,16 +379,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: @@@ -432,7 -497,7 +502,7 @@@ static int get_common_commits(void save_commit_buffer = 0; - for(;;) { + for (;;) { int len = packet_read_line(0, line, sizeof(line)); reset_timeout(); @@@ -497,6 -562,7 +567,6 @@@ static void receive_needs(void 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); @@@ -508,6 -574,7 +578,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); @@@ -590,7 -657,6 +660,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);