git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 6/7] refactor run_receive_hook()

From
Junio C Hamano <gitster@pobox.com>
Date
Sep 8, 2011, 20:01 UTC
Message-ID
<1315512102-19022-7-git-send-email-gitster@pobox.com>
In-Reply-To
<1315512102-19022-1-git-send-email-gitster@pobox.com>

Running a hook has to make complex set-up to establish web of communication between child process and multiplexer, which is common regardless of what kind of data is fed to the hook. Refactor the parts that is specific to the data fed to the particular set of hooks from the part that runs the hook, so that the code can be reused to drive hooks that take different kind of data.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/receive-pack.c |   71 +++++++++++++++++++++++++++++++++++-------------
 1 files changed, 52 insertions(+), 19 deletions(-)
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 344660e..939b867 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -212,21 +212,15 @@ static int copy_to_sideband(int in, int out, void *arg)
 	return 0;
 }
 
-static int run_receive_hook(struct command *commands, const char *hook_name)
+typedef int (*feed_fn)(void *, const char **, size_t *);
+static int run_and_feed_hook(const char *hook_name, feed_fn feed, void *feed_state)
 {
-	static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
-	struct command *cmd;
 	struct child_process proc;
 	struct async muxer;
 	const char *argv[2];
-	int have_input = 0, code;
-
-	for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
-		if (!cmd->error_string)
-			have_input = 1;
-	}
+	int code;
 
-	if (!have_input || access(hook_name, X_OK) < 0)
+	if (access(hook_name, X_OK) < 0)
 		return 0;
 
 	argv[0] = hook_name;
@@ -254,15 +248,13 @@ static int run_receive_hook(struct command *commands, const char *hook_name)
 		return code;
 	}
 
-	for (cmd = commands; cmd; cmd = cmd->next) {
-		if (!cmd->error_string) {
-			size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
-				sha1_to_hex(cmd->old_sha1),
-				sha1_to_hex(cmd->new_sha1),
-				cmd->ref_name);
-			if (write_in_full(proc.in, buf, n) != n)
-				break;
-		}
+	while (1) {
+		const char *buf;
+		size_t n;
+		if (feed(feed_state, &buf, &n))
+			break;
+		if (write_in_full(proc.in, buf, n) != n)
+			break;
 	}
 	close(proc.in);
 	if (use_sideband)
@@ -270,6 +262,47 @@ static int run_receive_hook(struct command *commands, const char *hook_name)
 	return finish_command(&proc);
 }
 
+struct receive_hook_feed_state {
+	struct command *cmd;
+	struct strbuf buf;
+};
+
+static int feed_receive_hook(void *state_, const char **bufp, size_t *sizep)
+{
+	struct receive_hook_feed_state *state = state_;
+	struct command *cmd = state->cmd;
+
+	while (cmd && cmd->error_string)
+		cmd = cmd->next;
+	if (!cmd)
+		return -1; /* EOF */
+	strbuf_reset(&state->buf);
+	strbuf_addf(&state->buf, "%s %s %s\n",
+		    sha1_to_hex(cmd->old_sha1), sha1_to_hex(cmd->new_sha1),
+		    cmd->ref_name);
+	state->cmd = cmd->next;
+	if (bufp) {
+		*bufp = state->buf.buf;
+		*sizep = state->buf.len;
+	}
+	return 0;
+}
+
+static int run_receive_hook(struct command *commands, const char *hook_name)
+{
+	struct receive_hook_feed_state state;
+	int status;
+
+	strbuf_init(&state.buf, 0);
+	state.cmd = commands;
+	if (feed_receive_hook(&state, NULL, NULL))
+		return 0;
+	state.cmd = commands;
+	status = run_and_feed_hook(hook_name, feed_receive_hook, &state);
+	strbuf_release(&state.buf);
+	return status;
+}
+
 static int run_update_hook(struct command *cmd)
 {
 	static const char update_hook[] = "hooks/update";
-- 
1.7.7.rc0.188.g3793ac
Previous: Junio C HamanoNext: Junio C Hamano
Message 7 of 22 in “"push -s"”
  1. 0/7 "push -s"Junio C Hamano, Sep 8, 2011
  2. 1/7 send-pack: typofix error messageJunio C Hamano, Sep 8, 2011
  3. 2/7 Split GPG interface into its own helper libraryJunio C Hamano, Sep 8, 2011
  4. 3/7 push -s: skeletonJunio C Hamano, Sep 8, 2011
  5. 4/7 push -s: send signed push certificateJunio C Hamano, Sep 8, 2011
  6. 5/7 push -s: receiving endJunio C Hamano, Sep 8, 2011
  7. 6/7 refactor run_receive_hook()Junio C Hamano, Sep 8, 2011
  8. 7/7 push -s: support pre-receive-signature hookJunio C Hamano, Sep 8, 2011
  9. 0/4 Signed pushJunio C Hamano, Sep 9, 2011
  10. 1/4 send-pack: typofix error messageJunio C Hamano, Sep 9, 2011
  11. 2/4 Split GPG interface into its own helper libraryJunio C Hamano, Sep 9, 2011
  12. 3/4 rename "match_refs()" to "match_push_refs()"Junio C Hamano, Sep 9, 2011
  13. 4/4 push -s: signed pushJunio C Hamano, Sep 9, 2011
  14. 4/4 push -s: signed pushJunio C Hamano, Sep 9, 2011
  15. Junio C HamanoSep 10, 2011
  16. Sverre RabbelierSep 10, 2011
  17. Junio C HamanoSep 10, 2011
  18. Ted Ts'oSep 10, 2011
  19. Junio C HamanoSep 11, 2011
  20. Sverre RabbelierSep 11, 2011
  21. Ted Ts'oSep 11, 2011
  22. Robin H. JohnsonSep 10, 2011

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.