{"thread":{"id":"22537","subject":"[PATCH v2 4/6] receive-pack: Refactor how capabilities are shown to the client","startedAt":"2010-02-05T20:57:36Z","lastAt":"2010-02-09T17:41:18Z","messageCount":14,"participants":["Shawn O. Pearce","Junio C Hamano","Larry D'Anna"],"isPatch":true,"patchVersion":2,"patchTotal":6},"messages":[{"id":"133722","messageId":"1265403462-20572-1-git-send-email-spearce@spearce.org","threadId":"22537","inReplyTo":null,"subject":"[PATCH v2 0/6] receive-pack hooks over sideband","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2010-02-05T20:57:36Z","receivedAt":"2010-02-05T20:57:36Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"This is a respin of the patch I posted yesterday.  Same idea,\nwe want to make the messages printed by hooks available over the\nsideband protocol so git:// and http:// smart clients are able to\npresent them, similar to how ssh:// works.\n\nNo real major changes from v1, the series is just broken apart to\nmake it easier to review, and Erik Faye-Lund's patch was integrated\nto get a bidirectional async interface, rather than my hacked\n.is_reader attempt in v1.\n\nErik Faye-Lund (1):\n  run-command: support custom fd-set in async\n\nShawn O. Pearce (5):\n  run-command: Allow stderr to be a caller supplied pipe\n  send-pack: demultiplex a sideband stream with status data\n  receive-pack: Refactor how capabilities are shown to the client\n  receive-pack: Wrap status reports inside side-band-64k\n  receive-pack: Send hook output over side band #2\n\n Documentation/technical/api-run-command.txt |   52 ++++++++++---\n builtin-fetch-pack.c                        |    7 +-\n builtin-receive-pack.c                      |  111 +++++++++++++++++++++------\n builtin-send-pack.c                         |   66 ++++++++++++----\n convert.c                                   |    5 +-\n remote-curl.c                               |    7 +-\n run-command.c                               |   91 +++++++++++++++++++---\n run-command.h                               |   11 ++-\n t/t5401-update-hooks.sh                     |   22 +++---\n upload-pack.c                               |    7 +-\n 10 files changed, 290 insertions(+), 89 deletions(-)\n"},{"id":"133723","messageId":"1265403462-20572-2-git-send-email-spearce@spearce.org","threadId":"22537","inReplyTo":"1265403462-20572-1-git-send-email-spearce@spearce.org","subject":"[PATCH v2 1/6] run-command: Allow stderr to be a caller supplied pipe","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2010-02-05T20:57:37Z","receivedAt":"2010-02-05T20:57:37Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Like .out, .err may now be set to a file descriptor > 0, which\nis a writable pipe/socket/file that the child's stderr will be\nredirected into.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n Documentation/technical/api-run-command.txt |    2 +-\n run-command.c                               |    8 ++++++++\n run-command.h                               |    2 +-\n 3 files changed, 10 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/technical/api-run-command.txt b/Documentation/technical/api-run-command.txt\nindex b26c281..a1280dd 100644\n--- a/Documentation/technical/api-run-command.txt\n+++ b/Documentation/technical/api-run-command.txt\n@@ -135,7 +135,7 @@ stderr as follows:\n \n \t.in: The FD must be readable; it becomes child's stdin.\n \t.out: The FD must be writable; it becomes child's stdout.\n-\t.err > 0 is not supported.\n+\t.err: The FD must be writable; it becomes child's stderr.\n \n   The specified FD is closed by start_command(), even if it fails to\n   run the sub-process!\ndiff --git a/run-command.c b/run-command.c\nindex cf2d8f7..bfd2312 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -94,6 +94,9 @@ fail_pipe:\n \t\telse if (need_err) {\n \t\t\tdup2(fderr[1], 2);\n \t\t\tclose_pair(fderr);\n+\t\t} else if (cmd->err > 1) {\n+\t\t\tdup2(cmd->err, 2);\n+\t\t\tclose(cmd->err);\n \t\t}\n \n \t\tif (cmd->no_stdout)\n@@ -156,6 +159,9 @@ fail_pipe:\n \t} else if (need_err) {\n \t\ts2 = dup(2);\n \t\tdup2(fderr[1], 2);\n+\t} else if (cmd->err > 2) {\n+\t\ts2 = dup(2);\n+\t\tdup2(cmd->err, 2);\n \t}\n \n \tif (cmd->no_stdout) {\n@@ -228,6 +234,8 @@ fail_pipe:\n \n \tif (need_err)\n \t\tclose(fderr[1]);\n+\telse if (cmd->err)\n+\t\tclose(cmd->err);\n \n \treturn 0;\n }\ndiff --git a/run-command.h b/run-command.h\nindex fb34209..a29171a 100644\n--- a/run-command.h\n+++ b/run-command.h\n@@ -18,7 +18,7 @@ struct child_process {\n \t * - Specify > 0 to set a channel to a particular FD as follows:\n \t *     .in: a readable FD, becomes child's stdin\n \t *     .out: a writable FD, becomes child's stdout/stderr\n-\t *     .err > 0 not supported\n+\t *     .err: a writable FD, becomes child's stderr\n \t *   The specified FD is closed by start_command(), even in case\n \t *   of errors!\n \t */\n-- \n1.7.0.rc1.199.g9253ab\n"},{"id":"133724","messageId":"1265403462-20572-3-git-send-email-spearce@spearce.org","threadId":"22537","inReplyTo":"1265403462-20572-1-git-send-email-spearce@spearce.org","subject":"[PATCH v2 2/6] run-command: support custom fd-set in async","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2010-02-05T20:57:38Z","receivedAt":"2010-02-05T20:57:38Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"From: Erik Faye-Lund <kusmabite@gmail.com>\n\nThis patch adds the possibility to supply a set of non-0 file\ndescriptors for async process communication instead of the\ndefault-created pipe.\n\nAdditionally, we now support bi-directional communiction with the\nasync procedure, by giving the async function both read and write\nfile descriptors.\n\nTo retain compatiblity and similar \"API feel\" with start_command,\nwe require start_async callers to set .out = -1 to get a readable\nfile descriptor.  If either of .in or .out is 0, we supply no file\ndescriptor to the async process.\n\n[sp: Note: Erik started this patch, and a huge bulk of it is\n     his work.  All bugs were introduced later by Shawn.]\n\nSigned-off-by: Erik Faye-Lund <kusmabite@gmail.com>\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n Documentation/technical/api-run-command.txt |   50 +++++++++++++---\n builtin-fetch-pack.c                        |    7 +-\n convert.c                                   |    5 +-\n remote-curl.c                               |    7 +-\n run-command.c                               |   83 ++++++++++++++++++++++----\n run-command.h                               |    9 ++-\n upload-pack.c                               |    7 +-\n 7 files changed, 131 insertions(+), 37 deletions(-)\n\ndiff --git a/Documentation/technical/api-run-command.txt b/Documentation/technical/api-run-command.txt\nindex a1280dd..8994859 100644\n--- a/Documentation/technical/api-run-command.txt\n+++ b/Documentation/technical/api-run-command.txt\n@@ -64,8 +64,8 @@ The functions above do the following:\n `start_async`::\n \n \tRun a function asynchronously. Takes a pointer to a `struct\n-\tasync` that specifies the details and returns a pipe FD\n-\tfrom which the caller reads. See below for details.\n+\tasync` that specifies the details and returns a set of pipe FDs\n+\tfor communication with the function. See below for details.\n \n `finish_async`::\n \n@@ -180,17 +180,47 @@ The caller:\n    struct async variable;\n 2. initializes .proc and .data;\n 3. calls start_async();\n-4. processes the data by reading from the fd in .out;\n-5. closes .out;\n+4. processes communicates with proc through .in and .out;\n+5. closes .in and .out;\n 6. calls finish_async().\n \n+The members .in, .out are used to provide a set of fd's for\n+communication between the caller and the callee as follows:\n+\n+. Specify 0 to have no file descriptor passed.  The callee will\n+  receive -1 in the corresponding argument.\n+\n+. Specify < 0 to have a pipe allocated; start_async() replaces\n+  with the pipe FD in the following way:\n+\n+\t.in: Returns the writable pipe end into which the caller\n+\twrites; the readable end of the pipe becomes the function's\n+\tin argument.\n+\n+\t.out: Returns the readable pipe end from which the caller\n+\treads; the writable end of the pipe becomes the function's\n+\tout argument.\n+\n+  The caller of start_async() must close the returned FDs after it\n+  has completed reading from/writing from them.\n+\n+. Specify a file descriptor > 0 to be used by the function:\n+\n+\t.in: The FD must be readable; it becomes the function's in.\n+\t.out: The FD must be writable; it becomes the function's out.\n+\n+  The specified FD is closed by start_async(), even if it fails to\n+  run the function.\n+\n The function pointer in .proc has the following signature:\n \n-\tint proc(int fd, void *data);\n+\tint proc(int in, int out, void *data);\n \n-. fd specifies a writable file descriptor to which the function must\n-  write the data that it produces. The function *must* close this\n-  descriptor before it returns.\n+. in, out specifies a set of file descriptors to which the function\n+  must read/write the data that it needs/produces.  The function\n+  *must* close these descriptors before it returns.  A descriptor\n+  may be -1 if the caller did not configure a descriptor for that\n+  direction.\n \n . data is the value that the caller has specified in the .data member\n   of struct async.\n@@ -205,8 +235,8 @@ because this facility is implemented by a pipe to a forked process on\n UNIX, but by a thread in the same address space on Windows:\n \n . It cannot change the program's state (global variables, environment,\n-  etc.) in a way that the caller notices; in other words, .out is the\n-  only communication channel to the caller.\n+  etc.) in a way that the caller notices; in other words, .in and .out\n+  are the only communication channels to the caller.\n \n . It must not change the program's state that the caller of the\n   facility also uses.\ndiff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c\nindex 8ed4a6f..dbd8b7b 100644\n--- a/builtin-fetch-pack.c\n+++ b/builtin-fetch-pack.c\n@@ -586,12 +586,12 @@ static int everything_local(struct ref **refs, int nr_match, char **match)\n \treturn retval;\n }\n \n-static int sideband_demux(int fd, void *data)\n+static int sideband_demux(int in, int out, void *data)\n {\n \tint *xd = data;\n \n-\tint ret = recv_sideband(\"fetch-pack\", xd[0], fd);\n-\tclose(fd);\n+\tint ret = recv_sideband(\"fetch-pack\", xd[0], out);\n+\tclose(out);\n \treturn ret;\n }\n \n@@ -613,6 +613,7 @@ static int get_pack(int xd[2], char **pack_lockfile)\n \t\t */\n \t\tdemux.proc = sideband_demux;\n \t\tdemux.data = xd;\n+\t\tdemux.out = -1;\n \t\tif (start_async(&demux))\n \t\t\tdie(\"fetch-pack: unable to fork off sideband\"\n \t\t\t    \" demultiplexer\");\ndiff --git a/convert.c b/convert.c\nindex 491e714..e70ee09 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -241,7 +241,7 @@ struct filter_params {\n \tconst char *cmd;\n };\n \n-static int filter_buffer(int fd, void *data)\n+static int filter_buffer(int in, int out, void *data)\n {\n \t/*\n \t * Spawn cmd and feed the buffer contents through its stdin.\n@@ -254,7 +254,7 @@ static int filter_buffer(int fd, void *data)\n \tmemset(&child_process, 0, sizeof(child_process));\n \tchild_process.argv = argv;\n \tchild_process.in = -1;\n-\tchild_process.out = fd;\n+\tchild_process.out = out;\n \n \tif (start_command(&child_process))\n \t\treturn error(\"cannot fork to run external filter %s\", params->cmd);\n@@ -291,6 +291,7 @@ static int apply_filter(const char *path, const char *src, size_t len,\n \tmemset(&async, 0, sizeof(async));\n \tasync.proc = filter_buffer;\n \tasync.data = &params;\n+\tasync.out = -1;\n \tparams.src = src;\n \tparams.size = len;\n \tparams.cmd = cmd;\ndiff --git a/remote-curl.c b/remote-curl.c\nindex 3edbf57..6bb3366 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -184,13 +184,13 @@ static struct discovery* discover_refs(const char *service)\n \treturn last;\n }\n \n-static int write_discovery(int fd, void *data)\n+static int write_discovery(int in, int out, void *data)\n {\n \tstruct discovery *heads = data;\n \tint err = 0;\n-\tif (write_in_full(fd, heads->buf, heads->len) != heads->len)\n+\tif (write_in_full(out, heads->buf, heads->len) != heads->len)\n \t\terr = 1;\n-\tclose(fd);\n+\tclose(out);\n \treturn err;\n }\n \n@@ -202,6 +202,7 @@ static struct ref *parse_git_refs(struct discovery *heads)\n \tmemset(&async, 0, sizeof(async));\n \tasync.proc = write_discovery;\n \tasync.data = heads;\n+\tasync.out = -1;\n \n \tif (start_async(&async))\n \t\tdie(\"cannot start thread to parse advertised refs\");\ndiff --git a/run-command.c b/run-command.c\nindex bfd2312..0d95340 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -327,17 +327,51 @@ int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const\n static unsigned __stdcall run_thread(void *data)\n {\n \tstruct async *async = data;\n-\treturn async->proc(async->fd_for_proc, async->data);\n+\treturn async->proc(async->proc_in, async->proc_out, async->data);\n }\n #endif\n \n int start_async(struct async *async)\n {\n-\tint pipe_out[2];\n+\tint need_in, need_out;\n+\tint fdin[2], fdout[2];\n+\tint proc_in, proc_out;\n \n-\tif (pipe(pipe_out) < 0)\n-\t\treturn error(\"cannot create pipe: %s\", strerror(errno));\n-\tasync->out = pipe_out[0];\n+\tneed_in = async->in < 0;\n+\tif (need_in) {\n+\t\tif (pipe(fdin) < 0) {\n+\t\t\tif (async->out > 0)\n+\t\t\t\tclose(async->out);\n+\t\t\treturn error(\"cannot create pipe: %s\", strerror(errno));\n+\t\t}\n+\t\tasync->in = fdin[1];\n+\t}\n+\n+\tneed_out = async->out < 0;\n+\tif (need_out) {\n+\t\tif (pipe(fdout) < 0) {\n+\t\t\tif (need_in)\n+\t\t\t\tclose_pair(fdin);\n+\t\t\telse if (async->in)\n+\t\t\t\tclose(async->in);\n+\t\t\treturn error(\"cannot create pipe: %s\", strerror(errno));\n+\t\t}\n+\t\tasync->out = fdout[0];\n+\t}\n+\n+\tif (need_in)\n+\t\tproc_in = fdin[0];\n+\telse if (async->in)\n+\t\tproc_in = async->in;\n+\telse\n+\t\tproc_in = -1;\n+\n+\tif (need_out)\n+\t\tproc_out = fdout[1];\n+\telse if (async->out)\n+\t\tproc_out = async->out;\n+\telse\n+\t\tproc_out = -1;\n \n #ifndef WIN32\n \t/* Flush stdio before fork() to avoid cloning buffers */\n@@ -346,24 +380,47 @@ int start_async(struct async *async)\n \tasync->pid = fork();\n \tif (async->pid < 0) {\n \t\terror(\"fork (async) failed: %s\", strerror(errno));\n-\t\tclose_pair(pipe_out);\n-\t\treturn -1;\n+\t\tgoto error;\n \t}\n \tif (!async->pid) {\n-\t\tclose(pipe_out[0]);\n-\t\texit(!!async->proc(pipe_out[1], async->data));\n+\t\tif (need_in)\n+\t\t\tclose(fdin[1]);\n+\t\tif (need_out)\n+\t\t\tclose(fdout[0]);\n+\t\texit(!!async->proc(proc_in, proc_out, async->data));\n \t}\n-\tclose(pipe_out[1]);\n+\n+\tif (need_in)\n+\t\tclose(fdin[0]);\n+\telse if (async->in)\n+\t\tclose(async->in);\n+\n+\tif (need_out)\n+\t\tclose(fdout[1]);\n+\telse if (async->out)\n+\t\tclose(async->out);\n #else\n-\tasync->fd_for_proc = pipe_out[1];\n+\tasync->proc_in = proc_in;\n+\tasync->proc_out = proc_out;\n \tasync->tid = (HANDLE) _beginthreadex(NULL, 0, run_thread, async, 0, NULL);\n \tif (!async->tid) {\n \t\terror(\"cannot create thread: %s\", strerror(errno));\n-\t\tclose_pair(pipe_out);\n-\t\treturn -1;\n+\t\tgoto error;\n \t}\n #endif\n \treturn 0;\n+\n+error:\n+\tif (need_in)\n+\t\tclose_pair(fdin);\n+\telse if (async->in)\n+\t\tclose(async->in);\n+\n+\tif (need_out)\n+\t\tclose_pair(fdout);\n+\telse if (async->out)\n+\t\tclose(async->out);\n+\treturn -1;\n }\n \n int finish_async(struct async *async)\ndiff --git a/run-command.h b/run-command.h\nindex a29171a..65ccb1c 100644\n--- a/run-command.h\n+++ b/run-command.h\n@@ -64,17 +64,20 @@ int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const\n  */\n struct async {\n \t/*\n-\t * proc writes to fd and closes it;\n+\t * proc reads from in; closes it before return\n+\t * proc writes to out; closes it before return\n \t * returns 0 on success, non-zero on failure\n \t */\n-\tint (*proc)(int fd, void *data);\n+\tint (*proc)(int in, int out, void *data);\n \tvoid *data;\n+\tint in;\t\t/* caller writes here and closes it */\n \tint out;\t/* caller reads from here and closes it */\n #ifndef WIN32\n \tpid_t pid;\n #else\n \tHANDLE tid;\n-\tint fd_for_proc;\n+\tint proc_in;\n+\tint proc_out;\n #endif\n };\n \ndiff --git a/upload-pack.c b/upload-pack.c\nindex df15181..dc464d7 100644\n--- a/upload-pack.c\n+++ b/upload-pack.c\n@@ -105,12 +105,12 @@ static void show_edge(struct commit *commit)\n \tfprintf(pack_pipe, \"-%s\\n\", sha1_to_hex(commit->object.sha1));\n }\n \n-static int do_rev_list(int fd, void *create_full_pack)\n+static int do_rev_list(int in, int out, void *create_full_pack)\n {\n \tint i;\n \tstruct rev_info revs;\n \n-\tpack_pipe = xfdopen(fd, \"w\");\n+\tpack_pipe = xfdopen(out, \"w\");\n \tinit_revisions(&revs, NULL);\n \trevs.tag_objects = 1;\n \trevs.tree_objects = 1;\n@@ -162,8 +162,9 @@ static void create_pack_file(void)\n \tint arg = 0;\n \n \tif (shallow_nr) {\n+\t\tmemset(&rev_list, 0, sizeof(rev_list));\n \t\trev_list.proc = do_rev_list;\n-\t\trev_list.data = 0;\n+\t\trev_list.out = -1;\n \t\tif (start_async(&rev_list))\n \t\t\tdie(\"git upload-pack: unable to fork git-rev-list\");\n \t\targv[arg++] = \"pack-objects\";\n-- \n1.7.0.rc1.199.g9253ab\n"},{"id":"133727","messageId":"1265403462-20572-4-git-send-email-spearce@spearce.org","threadId":"22537","inReplyTo":"1265403462-20572-1-git-send-email-spearce@spearce.org","subject":"[PATCH v2 3/6] send-pack: demultiplex a sideband stream with status data","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2010-02-05T20:57:39Z","receivedAt":"2010-02-05T20:57:39Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"If the server advertises side-band-64k capability, we request\nit and pull the status report data out of side band #1, and let\nside band #2 go to our stderr.  The latter channel be used by the\nremote side to send our user messages.  This basically mirrors the\nside-band-64k capability in upload-pack.\n\nServers may choose to use side band #2 to send error messages from\nhook scripts that are meant for the push end user.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n builtin-send-pack.c |   66 ++++++++++++++++++++++++++++++++++++++------------\n 1 files changed, 50 insertions(+), 16 deletions(-)\n\ndiff --git a/builtin-send-pack.c b/builtin-send-pack.c\nindex 8fffdbf..2478e18 100644\n--- a/builtin-send-pack.c\n+++ b/builtin-send-pack.c\n@@ -372,6 +372,14 @@ static void print_helper_status(struct ref *ref)\n \tstrbuf_release(&buf);\n }\n \n+static int sideband_demux(int in, int out, void *data)\n+{\n+\tint *fd = data;\n+\tint ret = recv_sideband(\"send-pack\", fd[0], out);\n+\tclose(out);\n+\treturn ret;\n+}\n+\n int send_pack(struct send_pack_args *args,\n \t      int fd[], struct child_process *conn,\n \t      struct ref *remote_refs,\n@@ -382,18 +390,22 @@ int send_pack(struct send_pack_args *args,\n \tstruct strbuf req_buf = STRBUF_INIT;\n \tstruct ref *ref;\n \tint new_refs;\n-\tint ask_for_status_report = 0;\n \tint allow_deleting_refs = 0;\n-\tint expect_status_report = 0;\n+\tint status_report = 0;\n+\tint use_sideband = 0;\n+\tunsigned cmds_sent = 0;\n \tint ret;\n+\tstruct async demux;\n \n \t/* Does the other end support the reporting? */\n \tif (server_supports(\"report-status\"))\n-\t\task_for_status_report = 1;\n+\t\tstatus_report = 1;\n \tif (server_supports(\"delete-refs\"))\n \t\tallow_deleting_refs = 1;\n \tif (server_supports(\"ofs-delta\"))\n \t\targs->use_ofs_delta = 1;\n+\tif (server_supports(\"side-band-64k\"))\n+\t\tuse_sideband = 1;\n \n \tif (!remote_refs) {\n \t\tfprintf(stderr, \"No refs in common and none specified; doing nothing.\\n\"\n@@ -456,28 +468,30 @@ int send_pack(struct send_pack_args *args,\n \t\tif (!ref->deletion)\n \t\t\tnew_refs++;\n \n-\t\tif (!args->dry_run) {\n+\t\tif (args->dry_run) {\n+\t\t\tref->status = REF_STATUS_OK;\n+\t\t} else {\n \t\t\tchar *old_hex = sha1_to_hex(ref->old_sha1);\n \t\t\tchar *new_hex = sha1_to_hex(ref->new_sha1);\n \n-\t\t\tif (ask_for_status_report) {\n-\t\t\t\tpacket_buf_write(&req_buf, \"%s %s %s%c%s\",\n+\t\t\tif (!cmds_sent && (status_report || use_sideband)) {\n+\t\t\t\tpacket_buf_write(&req_buf, \"%s %s %s%c%s%s\",\n \t\t\t\t\told_hex, new_hex, ref->name, 0,\n-\t\t\t\t\t\"report-status\");\n-\t\t\t\task_for_status_report = 0;\n-\t\t\t\texpect_status_report = 1;\n+\t\t\t\t\tstatus_report ? \" report-status\" : \"\",\n+\t\t\t\t\tuse_sideband ? \" side-band-64k\" : \"\");\n \t\t\t}\n \t\t\telse\n \t\t\t\tpacket_buf_write(&req_buf, \"%s %s %s\",\n \t\t\t\t\told_hex, new_hex, ref->name);\n+\t\t\tref->status = status_report ?\n+\t\t\t\tREF_STATUS_EXPECTING_REPORT :\n+\t\t\t\tREF_STATUS_OK;\n+\t\t\tcmds_sent++;\n \t\t}\n-\t\tref->status = expect_status_report ?\n-\t\t\tREF_STATUS_EXPECTING_REPORT :\n-\t\t\tREF_STATUS_OK;\n \t}\n \n \tif (args->stateless_rpc) {\n-\t\tif (!args->dry_run) {\n+\t\tif (!args->dry_run && cmds_sent) {\n \t\t\tpacket_buf_flush(&req_buf);\n \t\t\tsend_sideband(out, -1, req_buf.buf, req_buf.len, LARGE_PACKET_MAX);\n \t\t}\n@@ -487,23 +501,43 @@ int send_pack(struct send_pack_args *args,\n \t}\n \tstrbuf_release(&req_buf);\n \n-\tif (new_refs && !args->dry_run) {\n+\tif (use_sideband && cmds_sent) {\n+\t\tmemset(&demux, 0, sizeof(demux));\n+\t\tdemux.proc = sideband_demux;\n+\t\tdemux.data = fd;\n+\t\tdemux.out = -1;\n+\t\tif (start_async(&demux))\n+\t\t\tdie(\"receive-pack: unable to fork off sideband demultiplexer\");\n+\t\tin = demux.out;\n+\t}\n+\n+\tif (new_refs && cmds_sent) {\n \t\tif (pack_objects(out, remote_refs, extra_have, args) < 0) {\n \t\t\tfor (ref = remote_refs; ref; ref = ref->next)\n \t\t\t\tref->status = REF_STATUS_NONE;\n+\t\t\tif (use_sideband)\n+\t\t\t\tfinish_async(&demux);\n \t\t\treturn -1;\n \t\t}\n \t}\n-\tif (args->stateless_rpc && !args->dry_run)\n+\tif (args->stateless_rpc && cmds_sent)\n \t\tpacket_flush(out);\n \n-\tif (expect_status_report)\n+\tif (status_report && cmds_sent)\n \t\tret = receive_status(in, remote_refs);\n \telse\n \t\tret = 0;\n \tif (args->stateless_rpc)\n \t\tpacket_flush(out);\n \n+\tif (use_sideband && cmds_sent) {\n+\t\tif (finish_async(&demux)) {\n+\t\t\terror(\"error in sideband demultiplexer\");\n+\t\t\tret = -1;\n+\t\t}\n+\t\tclose(demux.out);\n+\t}\n+\n \tif (ret < 0)\n \t\treturn ret;\n \tfor (ref = remote_refs; ref; ref = ref->next) {\n-- \n1.7.0.rc1.199.g9253ab\n"},{"id":"133721","messageId":"1265403462-20572-5-git-send-email-spearce@spearce.org","threadId":"22537","inReplyTo":"1265403462-20572-1-git-send-email-spearce@spearce.org","subject":"[PATCH v2 4/6] receive-pack: Refactor how capabilities are shown to the client","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2010-02-05T20:57:40Z","receivedAt":"2010-02-05T20:57:40Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Moving capability advertisement into the packet_write call itself\nmakes it easier to add additional capabilities to the list, be\nit optional by configuration, or always present in the protocol.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n builtin-receive-pack.c |   18 ++++++++----------\n 1 files changed, 8 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin-receive-pack.c b/builtin-receive-pack.c\nindex 78c0e69..325ec6e 100644\n--- a/builtin-receive-pack.c\n+++ b/builtin-receive-pack.c\n@@ -31,7 +31,7 @@ static int prefer_ofs_delta = 1;\n static int auto_update_server_info;\n static int auto_gc = 1;\n static const char *head_name;\n-static char *capabilities_to_send;\n+static int sent_capabilities;\n \n static enum deny_action parse_deny_action(const char *var, const char *value)\n {\n@@ -105,19 +105,21 @@ static int receive_pack_config(const char *var, const char *value, void *cb)\n \n static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)\n {\n-\tif (!capabilities_to_send)\n+\tif (sent_capabilities)\n \t\tpacket_write(1, \"%s %s\\n\", sha1_to_hex(sha1), path);\n \telse\n-\t\tpacket_write(1, \"%s %s%c%s\\n\",\n-\t\t\t     sha1_to_hex(sha1), path, 0, capabilities_to_send);\n-\tcapabilities_to_send = NULL;\n+\t\tpacket_write(1, \"%s %s%c%s%s\\n\",\n+\t\t\t     sha1_to_hex(sha1), path, 0,\n+\t\t\t     \" report-status delete-refs\",\n+\t\t\t     prefer_ofs_delta ? \" ofs-delta\" : \"\");\n+\tsent_capabilities = 1;\n \treturn 0;\n }\n \n static void write_head_info(void)\n {\n \tfor_each_ref(show_ref, NULL);\n-\tif (capabilities_to_send)\n+\tif (!sent_capabilities)\n \t\tshow_ref(\"capabilities^{}\", null_sha1, 0, NULL);\n \n }\n@@ -670,10 +672,6 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n \telse if (0 <= receive_unpack_limit)\n \t\tunpack_limit = receive_unpack_limit;\n \n-\tcapabilities_to_send = (prefer_ofs_delta) ?\n-\t\t\" report-status delete-refs ofs-delta \" :\n-\t\t\" report-status delete-refs \";\n-\n \tif (advertise_refs || !stateless_rpc) {\n \t\tadd_alternate_refs();\n \t\twrite_head_info();\n-- \n1.7.0.rc1.199.g9253ab\n"},{"id":"133729","messageId":"1265403462-20572-6-git-send-email-spearce@spearce.org","threadId":"22537","inReplyTo":"1265403462-20572-1-git-send-email-spearce@spearce.org","subject":"[PATCH v2 5/6] receive-pack: Wrap status reports inside side-band-64k","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2010-02-05T20:57:41Z","receivedAt":"2010-02-05T20:57:41Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"If the client requests the side-band-64k protocol capability we\nnow wrap the status report data inside of packets sent to band #1.\nThis permits us to later send additional progress or informational\nmessages down band #2.\n\nIf side-band-64k was enabled, we always send a final flush packet\nto let the client know we are done transmitting.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n builtin-receive-pack.c |   30 ++++++++++++++++++++++--------\n 1 files changed, 22 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin-receive-pack.c b/builtin-receive-pack.c\nindex 325ec6e..ff3f117 100644\n--- a/builtin-receive-pack.c\n+++ b/builtin-receive-pack.c\n@@ -2,6 +2,7 @@\n #include \"pack.h\"\n #include \"refs.h\"\n #include \"pkt-line.h\"\n+#include \"sideband.h\"\n #include \"run-command.h\"\n #include \"exec_cmd.h\"\n #include \"commit.h\"\n@@ -27,6 +28,7 @@ static int receive_unpack_limit = -1;\n static int transfer_unpack_limit = -1;\n static int unpack_limit = 100;\n static int report_status;\n+static int use_sideband;\n static int prefer_ofs_delta = 1;\n static int auto_update_server_info;\n static int auto_gc = 1;\n@@ -110,7 +112,7 @@ static int show_ref(const char *path, const unsigned char *sha1, int flag, void\n \telse\n \t\tpacket_write(1, \"%s %s%c%s%s\\n\",\n \t\t\t     sha1_to_hex(sha1), path, 0,\n-\t\t\t     \" report-status delete-refs\",\n+\t\t\t     \" report-status delete-refs side-band-64k\",\n \t\t\t     prefer_ofs_delta ? \" ofs-delta\" : \"\");\n \tsent_capabilities = 1;\n \treturn 0;\n@@ -466,6 +468,8 @@ static void read_head_info(void)\n \t\tif (reflen + 82 < len) {\n \t\t\tif (strstr(refname + reflen + 1, \"report-status\"))\n \t\t\t\treport_status = 1;\n+\t\t\tif (strstr(refname + reflen + 1, \"side-band-64k\"))\n+\t\t\t\tuse_sideband = LARGE_PACKET_MAX;\n \t\t}\n \t\tcmd = xmalloc(sizeof(struct command) + len - 80);\n \t\thashcpy(cmd->old_sha1, old_sha1);\n@@ -565,17 +569,25 @@ static const char *unpack(void)\n static void report(const char *unpack_status)\n {\n \tstruct command *cmd;\n-\tpacket_write(1, \"unpack %s\\n\",\n-\t\t     unpack_status ? unpack_status : \"ok\");\n+\tstruct strbuf buf = STRBUF_INIT;\n+\n+\tpacket_buf_write(&buf, \"unpack %s\\n\",\n+\t\t\t unpack_status ? unpack_status : \"ok\");\n \tfor (cmd = commands; cmd; cmd = cmd->next) {\n \t\tif (!cmd->error_string)\n-\t\t\tpacket_write(1, \"ok %s\\n\",\n-\t\t\t\t     cmd->ref_name);\n+\t\t\tpacket_buf_write(&buf, \"ok %s\\n\",\n+\t\t\t\t\t cmd->ref_name);\n \t\telse\n-\t\t\tpacket_write(1, \"ng %s %s\\n\",\n-\t\t\t\t     cmd->ref_name, cmd->error_string);\n+\t\t\tpacket_buf_write(&buf, \"ng %s %s\\n\",\n+\t\t\t\t\t cmd->ref_name, cmd->error_string);\n \t}\n-\tpacket_flush(1);\n+\tpacket_buf_flush(&buf);\n+\n+\tif (use_sideband)\n+\t\tsend_sideband(1, 1, buf.buf, buf.len, use_sideband);\n+\telse\n+\t\tsafe_write(1, buf.buf, buf.len);\n+\tstrbuf_release(&buf);\n }\n \n static int delete_only(struct command *cmd)\n@@ -705,5 +717,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n \t\tif (auto_update_server_info)\n \t\t\tupdate_server_info(0);\n \t}\n+\tif (use_sideband)\n+\t\tpacket_flush(1);\n \treturn 0;\n }\n-- \n1.7.0.rc1.199.g9253ab\n"},{"id":"133728","messageId":"1265403462-20572-7-git-send-email-spearce@spearce.org","threadId":"22537","inReplyTo":"1265403462-20572-1-git-send-email-spearce@spearce.org","subject":"[PATCH v2 6/6] receive-pack: Send hook output over side band #2","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2010-02-05T20:57:42Z","receivedAt":"2010-02-05T20:57:42Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"If the client requests to enable side-band-64k capability we can\nsafely send any hook stdout or stderr data down side band #2,\nso the client can present it to the user.\n\nIf side-band-64k isn't enabled, hooks continue to inherit stderr\nfrom the parent receive-pack process.\n\nWhen the side band channel is being used the push client will wind up\nprefixing all server messages with \"remote: \", just like fetch does,\nso our test vector has to be updated with the new expected output.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n builtin-receive-pack.c  |   65 ++++++++++++++++++++++++++++++++++++++++++----\n t/t5401-update-hooks.sh |   22 ++++++++--------\n 2 files changed, 70 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin-receive-pack.c b/builtin-receive-pack.c\nindex ff3f117..da1c26b 100644\n--- a/builtin-receive-pack.c\n+++ b/builtin-receive-pack.c\n@@ -139,11 +139,25 @@ static struct command *commands;\n static const char pre_receive_hook[] = \"hooks/pre-receive\";\n static const char post_receive_hook[] = \"hooks/post-receive\";\n \n+static int copy_to_sideband(int in, int out, void *arg)\n+{\n+\tchar data[128];\n+\twhile (1) {\n+\t\tssize_t sz = xread(in, data, sizeof(data));\n+\t\tif (sz <= 0)\n+\t\t\tbreak;\n+\t\tsend_sideband(1, 2, data, sz, use_sideband);\n+\t}\n+\tclose(in);\n+\treturn 0;\n+}\n+\n static int run_receive_hook(const char *hook_name)\n {\n \tstatic char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];\n \tstruct command *cmd;\n \tstruct child_process proc;\n+\tstruct async muxer;\n \tconst char *argv[2];\n \tint have_input = 0, code;\n \n@@ -163,9 +177,23 @@ static int run_receive_hook(const char *hook_name)\n \tproc.in = -1;\n \tproc.stdout_to_stderr = 1;\n \n+\tif (use_sideband) {\n+\t\tmemset(&muxer, 0, sizeof(muxer));\n+\t\tmuxer.proc = copy_to_sideband;\n+\t\tmuxer.in = -1;\n+\t\tcode = start_async(&muxer);\n+\t\tif (code)\n+\t\t\treturn code;\n+\t\tproc.err = muxer.in;\n+\t}\n+\n \tcode = start_command(&proc);\n-\tif (code)\n+\tif (code) {\n+\t\tif (use_sideband)\n+\t\t\tfinish_async(&muxer);\n \t\treturn code;\n+\t}\n+\n \tfor (cmd = commands; cmd; cmd = cmd->next) {\n \t\tif (!cmd->error_string) {\n \t\t\tsize_t n = snprintf(buf, sizeof(buf), \"%s %s %s\\n\",\n@@ -177,6 +205,8 @@ static int run_receive_hook(const char *hook_name)\n \t\t}\n \t}\n \tclose(proc.in);\n+\tif (use_sideband)\n+\t\tfinish_async(&muxer);\n \treturn finish_command(&proc);\n }\n \n@@ -184,6 +214,8 @@ static int run_update_hook(struct command *cmd)\n {\n \tstatic const char update_hook[] = \"hooks/update\";\n \tconst char *argv[5];\n+\tstruct child_process proc;\n+\tint code;\n \n \tif (access(update_hook, X_OK) < 0)\n \t\treturn 0;\n@@ -194,8 +226,18 @@ static int run_update_hook(struct command *cmd)\n \targv[3] = sha1_to_hex(cmd->new_sha1);\n \targv[4] = NULL;\n \n-\treturn run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |\n-\t\t\t\t\tRUN_COMMAND_STDOUT_TO_STDERR);\n+\tmemset(&proc, 0, sizeof(proc));\n+\tproc.no_stdin = 1;\n+\tproc.stdout_to_stderr = 1;\n+\tproc.err = use_sideband ? -1 : 0;\n+\tproc.argv = argv;\n+\n+\tcode = start_command(&proc);\n+\tif (code)\n+\t\treturn code;\n+\tif (use_sideband)\n+\t\tcopy_to_sideband(proc.err, -1, NULL);\n+\treturn finish_command(&proc);\n }\n \n static int is_ref_checked_out(const char *ref)\n@@ -384,8 +426,9 @@ static char update_post_hook[] = \"hooks/post-update\";\n static void run_update_post_hook(struct command *cmd)\n {\n \tstruct command *cmd_p;\n-\tint argc, status;\n+\tint argc;\n \tconst char **argv;\n+\tstruct child_process proc;\n \n \tfor (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {\n \t\tif (cmd_p->error_string)\n@@ -407,8 +450,18 @@ static void run_update_post_hook(struct command *cmd)\n \t\targc++;\n \t}\n \targv[argc] = NULL;\n-\tstatus = run_command_v_opt(argv, RUN_COMMAND_NO_STDIN\n-\t\t\t| RUN_COMMAND_STDOUT_TO_STDERR);\n+\n+\tmemset(&proc, 0, sizeof(proc));\n+\tproc.no_stdin = 1;\n+\tproc.stdout_to_stderr = 1;\n+\tproc.err = use_sideband ? -1 : 0;\n+\tproc.argv = argv;\n+\n+\tif (!start_command(&proc)) {\n+\t\tif (use_sideband)\n+\t\t\tcopy_to_sideband(proc.err, -1, NULL);\n+\t\tfinish_command(&proc);\n+\t}\n }\n \n static void execute_commands(const char *unpacker_error)\ndiff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh\nindex 64f66c9..c3cf397 100755\n--- a/t/t5401-update-hooks.sh\n+++ b/t/t5401-update-hooks.sh\n@@ -118,19 +118,19 @@ test_expect_success 'send-pack produced no output' '\n '\n \n cat <<EOF >expect\n-STDOUT pre-receive\n-STDERR pre-receive\n-STDOUT update refs/heads/master\n-STDERR update refs/heads/master\n-STDOUT update refs/heads/tofail\n-STDERR update refs/heads/tofail\n-STDOUT post-receive\n-STDERR post-receive\n-STDOUT post-update\n-STDERR post-update\n+remote: STDOUT pre-receive\n+remote: STDERR pre-receive\n+remote: STDOUT update refs/heads/master\n+remote: STDERR update refs/heads/master\n+remote: STDOUT update refs/heads/tofail\n+remote: STDERR update refs/heads/tofail\n+remote: STDOUT post-receive\n+remote: STDERR post-receive\n+remote: STDOUT post-update\n+remote: STDERR post-update\n EOF\n test_expect_success 'send-pack stderr contains hook messages' '\n-\tgrep ^STD send.err >actual &&\n+\tgrep ^remote: send.err | sed \"s/ *\\$//\" >actual &&\n \ttest_cmp - actual <expect\n '\n \n-- \n1.7.0.rc1.199.g9253ab\n"},{"id":"133730","messageId":"7vd40j1j2a.fsf@alter.siamese.dyndns.org","threadId":"22537","inReplyTo":"1265403462-20572-6-git-send-email-spearce@spearce.org","subject":"Re: [PATCH v2 5/6] receive-pack: Wrap status reports inside side-band-64k","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-05T21:14:37Z","receivedAt":"2010-02-05T21:14:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Shawn O. Pearce\" <spearce@spearce.org> writes:\n\n> If the client requests the side-band-64k protocol capability we\n> now wrap the status report data inside of packets sent to band #1.\n> This permits us to later send additional progress or informational\n> messages down band #2.\n>\n> If side-band-64k was enabled, we always send a final flush packet\n> to let the client know we are done transmitting.\n\nTwo questions.\n\n - Why does use_sideband, the variable with the same name as a boolean\n   variable used by other parts of the system to decide whether we should\n   or should not use the sideband communiocation, get a value other than 0\n   or 1?  What is the benefit of using it to keep an actual value?  Does\n   the benefit outweigh the confusion factor?\n\n - What happens if client wants only side-band, not 64k?  This is just\n   theoretical and \"we don't bother\" is a perfectly acceptable answer.  I\n   am just curious ;-).\n"},{"id":"133734","messageId":"20100205215344.GC27498@spearce.org","threadId":"22537","inReplyTo":"7vd40j1j2a.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v2 5/6] receive-pack: Wrap status reports inside side-band-64k","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2010-02-05T21:53:44Z","receivedAt":"2010-02-05T21:53:44Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Junio C Hamano <gitster@pobox.com> wrote:\n> \"Shawn O. Pearce\" <spearce@spearce.org> writes:\n> \n> > If the client requests the side-band-64k protocol capability we\n> > now wrap the status report data inside of packets sent to band #1.\n> > This permits us to later send additional progress or informational\n> > messages down band #2.\n> >\n> > If side-band-64k was enabled, we always send a final flush packet\n> > to let the client know we are done transmitting.\n> \n> Two questions.\n> \n>  - Why does use_sideband, the variable with the same name as a boolean\n>    variable used by other parts of the system to decide whether we should\n>    or should not use the sideband communiocation, get a value other than 0\n>    or 1?  What is the benefit of using it to keep an actual value?  Does\n>    the benefit outweigh the confusion factor?\n\nI was following the existing convention of use_sideband is\nmaximum-packet-size in server code, and boolean in client code.\n\nWell, I do diverage a bit in the client, in the client side\nuse_sideband = 2 in builtin-fetch-pack.c for side-band-64k and\nuse_sideband = 1 in builtin-send-pack.c for the same thing.\n \n>  - What happens if client wants only side-band, not 64k?  This is just\n>    theoretical and \"we don't bother\" is a perfectly acceptable answer.  I\n>    am just curious ;-).\n\nWhy bother?  What client doesn't understand side-band-64k but would\nunderstand this?\n\n-- \nShawn.\n"},{"id":"133735","messageId":"7vhbpvxr3x.fsf@alter.siamese.dyndns.org","threadId":"22537","inReplyTo":"20100205215344.GC27498@spearce.org","subject":"Re: [PATCH v2 5/6] receive-pack: Wrap status reports inside side-band-64k","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-05T22:19:46Z","receivedAt":"2010-02-05T22:19:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Shawn O. Pearce\" <spearce@spearce.org> writes:\n\n> I was following the existing convention of use_sideband is\n> maximum-packet-size in server code, and boolean in client code.\n\nAhh, I forgot about that -- we did it when we introduced different packet\nsize limit.\n\nNow it all makes sense.  Thanks.\n"},{"id":"134046","messageId":"20100209165207.GA12030@cthulhu","threadId":"22537","inReplyTo":"1265403462-20572-7-git-send-email-spearce@spearce.org","subject":"Re: [PATCH v2 6/6] receive-pack: Send hook output over side band #2","fromName":"Larry D'Anna","fromEmail":"larry@elder-gods.org","sentAt":"2010-02-09T16:52:07Z","receivedAt":"2010-02-09T16:52:07Z","isPatch":true,"sender":{"key":"larry@elder-gods.org","avatar":"https://avatars.githubusercontent.com/u/3013304?v=4"},"body":"\nThis breaks t5401.  See <7v4olqlva7.fsf@alter.siamese.dyndns.org> in another thread.\n\n     --larry\n"},{"id":"134052","messageId":"20100209172027.GC26964@spearce.org","threadId":"22537","inReplyTo":"20100209165207.GA12030@cthulhu","subject":"Re: [PATCH v2 6/6] receive-pack: Send hook output over side band #2","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2010-02-09T17:20:27Z","receivedAt":"2010-02-09T17:20:27Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Larry D'Anna <larry@elder-gods.org> wrote:\n> \n> This breaks t5401.  See <7v4olqlva7.fsf@alter.siamese.dyndns.org> in another thread.\n\nNo.  Your patch causes t5401 to break.  If you apply this series on\ntop of maint, its fine.  If you merge this series into master, and\ncorrectly fix the Win32 merge conflict in run-command.c, its fine.\n\n/me goes to look at your series, to see if I can figure out what\nbroke along the way.\n\n-- \nShawn.\n"},{"id":"134054","messageId":"20100209173307.GA1115@cthulhu","threadId":"22537","inReplyTo":"20100209172027.GC26964@spearce.org","subject":"Re: [PATCH v2 6/6] receive-pack: Send hook output over side band #2","fromName":"Larry D'Anna","fromEmail":"larry@elder-gods.org","sentAt":"2010-02-09T17:33:07Z","receivedAt":"2010-02-09T17:33:07Z","isPatch":true,"sender":{"key":"larry@elder-gods.org","avatar":"https://avatars.githubusercontent.com/u/3013304?v=4"},"body":"* Shawn O. Pearce (spearce@spearce.org) [100209 12:20]:\n> Larry D'Anna <larry@elder-gods.org> wrote:\n> > \n> > This breaks t5401.  See <7v4olqlva7.fsf@alter.siamese.dyndns.org> in another thread.\n> \n> No.  Your patch causes t5401 to break.  If you apply this series on\n> top of maint, its fine.  If you merge this series into master, and\n> correctly fix the Win32 merge conflict in run-command.c, its fine.\n\nWell, the version of this commit that's in pu is defiantly failing t5401 on my\nmachine.  Just tested it again with a clean build.  My series isn't an ancestor\nof it either.  Did you notice the failure is intermittent?  You have to run it a\nfew times before it fails.\n\n       --larry\n"},{"id":"134055","messageId":"20100209174118.GA14620@cthulhu","threadId":"22537","inReplyTo":"20100209173307.GA1115@cthulhu","subject":"Re: [PATCH v2 6/6] receive-pack: Send hook output over side band #2","fromName":"Larry D'Anna","fromEmail":"larry@elder-gods.org","sentAt":"2010-02-09T17:41:18Z","receivedAt":"2010-02-09T17:41:18Z","isPatch":true,"sender":{"key":"larry@elder-gods.org","avatar":"https://avatars.githubusercontent.com/u/3013304?v=4"},"body":"* Larry D'Anna (larry@elder-gods.org) [100209 12:33]:\n> * Shawn O. Pearce (spearce@spearce.org) [100209 12:20]:\n> > Larry D'Anna <larry@elder-gods.org> wrote:\n> > > \n> > > This breaks t5401.  See <7v4olqlva7.fsf@alter.siamese.dyndns.org> in another thread.\n> > \n> > No.  Your patch causes t5401 to break.  If you apply this series on\n> > top of maint, its fine.  If you merge this series into master, and\n> > correctly fix the Win32 merge conflict in run-command.c, its fine.\n> \n> Well, the version of this commit that's in pu is defiantly failing t5401 on my\n> machine.  Just tested it again with a clean build.  My series isn't an ancestor\n> of it either.  Did you notice the failure is intermittent?  You have to run it a\n> few times before it fails.\n\nI also just tried applying the series on top of maint myself, same result.\n\n\n  --larry\n"}]}