[PATCH 3/4] run_hook(): enhance the interface to pass arbitrary environment

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Originally "run_hook()" that used to live in builtin/commit.c had a
perfectly appropriate API and name for a private function to spawn a
hook from "git commit" command. The only necessary tweak in the
context was to optionally specify which file to use as the index
file.

But then we stupidly moved this private API to run-command.c without
making the interface suitable for general consumption, and there is
no way to tweak environment variables other than GIT_INDEX_FILE when
running a hook.

Correct this mistake by adding run_hook_e() that takes an array of
environment variables.

Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx>
---

 * This is the third patch of the more complex of the two approaches.
   Instead of the simpler "setenv()" one, the final one tries to
   limit the environment change only to the hook scripts, without
   affecting the "git commit" process itself. It probably should not
   make much difference in the short run, but later when we want to
   distinguish where the authorship came from, it may be easier to
   tell with this approach as it does not contaminate the environment
   of "git commit" itself with what we obtained from "--author" option.

   Also this is independently a useful refactoring.

 run-command.c |   49 ++++++++++++++++++++++++++++++++++++-------------
 run-command.h |    1 +
 2 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/run-command.c b/run-command.c
index 1db8abf..a51d8e5 100644
--- a/run-command.c
+++ b/run-command.c
@@ -672,36 +672,59 @@ int finish_async(struct async *async)
 #endif
 }
 
-int run_hook(const char *index_file, const char *name, ...)
+static int run_hook_le(const char *const *env,
+		       const char *name,
+		       va_list args)
 {
 	struct child_process hook;
 	struct argv_array argv = ARGV_ARRAY_INIT;
-	const char *p, *env[2];
-	char index[PATH_MAX];
-	va_list args;
+	const char *p;
 	int ret;
 
 	if (access(git_path("hooks/%s", name), X_OK) < 0)
 		return 0;
 
-	va_start(args, name);
 	argv_array_push(&argv, git_path("hooks/%s", name));
 	while ((p = va_arg(args, const char *)))
 		argv_array_push(&argv, p);
-	va_end(args);
 
 	memset(&hook, 0, sizeof(hook));
 	hook.argv = argv.argv;
 	hook.no_stdin = 1;
 	hook.stdout_to_stderr = 1;
-	if (index_file) {
-		snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
-		env[0] = index;
-		env[1] = NULL;
-		hook.env = env;
-	}
-
+	hook.env = env;
 	ret = run_command(&hook);
 	argv_array_clear(&argv);
 	return ret;
 }
+
+int run_hook(const char *index_file, const char *name, ...)
+{
+	const char *const *env = NULL, *env_buf[2];
+	struct strbuf index_buf = STRBUF_INIT;
+	int status;
+	va_list args;
+
+	va_start(args, name);
+	if (index_file) {
+		strbuf_addf(&index_buf, "GIT_INDEX_FILE=%s", index_file);
+		env_buf[0] = index_buf.buf;
+		env_buf[1] = NULL;
+		env = env_buf;
+	}
+	status = run_hook_le(env, name, args);
+	va_end(args);
+	strbuf_release(&index_buf);
+	return status;
+}
+
+int run_hook_e(const char *const *env, const char *name, ...)
+{
+	int status;
+	va_list args;
+
+	va_start(args, name);
+	status = run_hook_le(env, name, args);
+	va_end(args);
+	return status;
+}
diff --git a/run-command.h b/run-command.h
index 44f7d2b..87207b9 100644
--- a/run-command.h
+++ b/run-command.h
@@ -47,6 +47,7 @@ int finish_command(struct child_process *);
 int run_command(struct child_process *);
 
 extern int run_hook(const char *index_file, const char *name, ...);
+extern int run_hook_e(const char *const *, const char *name, ...);
 
 #define RUN_COMMAND_NO_STDIN 1
 #define RUN_GIT_CMD	     2	/*If this is to be git sub-command */
-- 
1.7.10.rc0.33.g8866af

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]