hooks: Add function to check if a hook exists

Create find_hook() function to determine if a given hook exists and is executable. If it is, the path to the script will be returned, otherwise NULL is returned. This encapsulates the tests that are used to check for the existence of a hook in one place, making it easier to modify those checks if that is found to be necessary. This also makes it simple for places that can use a hook to check if a hook exists before doing, possibly lengthy, setup work which would be pointless if no such hook is present. The returned value is left as a static value from get_pathname() rather than a duplicate because it is anticipated that the return value will either be used as a boolean, immediately added to an argv_array list which would result in it being duplicated at that point, or used to actually run the command without much intervening work. Callers which need to hold onto the returned value for a longer time are expected to duplicate the return value themselves. Signed-off-by: Aaron Schrab <aaron@schrab.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Aaron Schrab committed Jan 13, 2013 at 00:17 UTC 5a7da2dca166fab74f4514697e26dd80e79933f5
4 files changed +27 -20
builtin/commit.c
+2 -4
@@ -1327,8 +1327,6 @@ static int git_commit_config(const char *k, const char *v, void *cb)
1327 return git_status_config(k, v, s);
1328 }
1329
1330 -static const char post_rewrite_hook[] = "hooks/post-rewrite";
1331 -
1330 static int run_rewrite_hook(const unsigned char *oldsha1,
1331 const unsigned char *newsha1)
1332 {
@@ -1339,10 +1337,10 @@ static int run_rewrite_hook(const unsigned char *oldsha1,
1337 int code;
1338 size_t n;
1339
1342 - if (access(git_path(post_rewrite_hook), X_OK) < 0)
1340 + argv[0] = find_hook("post-rewrite");
1341 + if (!argv[0])
1342 return 0;
1343
1345 - argv[0] = git_path(post_rewrite_hook);
1344 argv[1] = "amend";
1345 argv[2] = NULL;
1346
builtin/receive-pack.c
+11 -14
@@ -182,9 +182,6 @@ struct command {
182 char ref_name[FLEX_ARRAY]; /* more */
183 };
184
185 -static const char pre_receive_hook[] = "hooks/pre-receive";
186 -static const char post_receive_hook[] = "hooks/post-receive";
187 -
185 static void rp_error(const char *err, ...) __attribute__((format (printf, 1, 2)));
186 static void rp_warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
187
@@ -242,10 +239,10 @@ static int run_and_feed_hook(const char *hook_name, feed_fn feed, void *feed_sta
239 const char *argv[2];
240 int code;
241
245 - if (access(hook_name, X_OK) < 0)
242 + argv[0] = find_hook(hook_name);
243 + if (!argv[0])
244 return 0;
245
248 - argv[0] = hook_name;
246 argv[1] = NULL;
247
248 memset(&proc, 0, sizeof(proc));
@@ -331,15 +328,14 @@ static int run_receive_hook(struct command *commands, const char *hook_name,
328
329 static int run_update_hook(struct command *cmd)
330 {
334 - static const char update_hook[] = "hooks/update";
331 const char *argv[5];
332 struct child_process proc;
333 int code;
334
339 - if (access(update_hook, X_OK) < 0)
335 + argv[0] = find_hook("update");
336 + if (!argv[0])
337 return 0;
338
342 - argv[0] = update_hook;
339 argv[1] = cmd->ref_name;
340 argv[2] = sha1_to_hex(cmd->old_sha1);
341 argv[3] = sha1_to_hex(cmd->new_sha1);
@@ -532,24 +528,25 @@ static const char *update(struct command *cmd)
528 }
529 }
530
535 -static char update_post_hook[] = "hooks/post-update";
536 -
531 static void run_update_post_hook(struct command *commands)
532 {
533 struct command *cmd;
534 int argc;
535 const char **argv;
536 struct child_process proc;
537 + char *hook;
538
539 + hook = find_hook("post-update");
540 for (argc = 0, cmd = commands; cmd; cmd = cmd->next) {
541 if (cmd->error_string || cmd->did_not_exist)
542 continue;
543 argc++;
544 }
549 - if (!argc || access(update_post_hook, X_OK) < 0)
545 + if (!argc || !hook)
546 return;
547 +
548 argv = xmalloc(sizeof(*argv) * (2 + argc));
552 - argv[0] = update_post_hook;
549 + argv[0] = hook;
550
551 for (argc = 1, cmd = commands; cmd; cmd = cmd->next) {
552 char *p;
@@ -704,7 +701,7 @@ static void execute_commands(struct command *commands, const char *unpacker_erro
701 0, &cmd))
702 set_connectivity_errors(commands);
703
707 - if (run_receive_hook(commands, pre_receive_hook, 0)) {
704 + if (run_receive_hook(commands, "pre-receive", 0)) {
705 for (cmd = commands; cmd; cmd = cmd->next) {
706 if (!cmd->error_string)
707 cmd->error_string = "pre-receive hook declined";
@@ -994,7 +991,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
991 unlink_or_warn(pack_lockfile);
992 if (report_status)
993 report(commands, unpack_status);
997 - run_receive_hook(commands, post_receive_hook, 1);
994 + run_receive_hook(commands, "post-receive", 1);
995 run_update_post_hook(commands);
996 if (auto_gc) {
997 const char *argv_gc_auto[] = {
run-command.c
+13 -2
@@ -735,6 +735,15 @@ int finish_async(struct async *async)
735 #endif
736 }
737
738 +char *find_hook(const char *name)
739 +{
740 + char *path = git_path("hooks/%s", name);
741 + if (access(path, X_OK) < 0)
742 + path = NULL;
743 +
744 + return path;
745 +}
746 +
747 int run_hook(const char *index_file, const char *name, ...)
748 {
749 struct child_process hook;
@@ -744,11 +753,13 @@ int run_hook(const char *index_file, const char *name, ...)
753 va_list args;
754 int ret;
755
747 - if (access(git_path("hooks/%s", name), X_OK) < 0)
756 + p = find_hook(name);
757 + if (!p)
758 return 0;
759
760 + argv_array_push(&argv, p);
761 +
762 va_start(args, name);
751 - argv_array_push(&argv, git_path("hooks/%s", name));
763 while ((p = va_arg(args, const char *)))
764 argv_array_push(&argv, p);
765 va_end(args);
run-command.h
+1
@@ -45,6 +45,7 @@ int start_command(struct child_process *);
45 int finish_command(struct child_process *);
46 int run_command(struct child_process *);
47
48 +extern char *find_hook(const char *name);
49 extern int run_hook(const char *index_file, const char *name, ...);
50
51 #define RUN_COMMAND_NO_STDIN 1