Skip to content

Commit

Permalink
hooks: Add function to check if a hook exists
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
aschrab authored and gitster committed Jan 14, 2013
1 parent 94702dd commit 5a7da2d
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 20 deletions.
6 changes: 2 additions & 4 deletions builtin/commit.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -1327,8 +1327,6 @@ static int git_commit_config(const char *k, const char *v, void *cb)
return git_status_config(k, v, s); return git_status_config(k, v, s);
} }


static const char post_rewrite_hook[] = "hooks/post-rewrite";

static int run_rewrite_hook(const unsigned char *oldsha1, static int run_rewrite_hook(const unsigned char *oldsha1,
const unsigned char *newsha1) const unsigned char *newsha1)
{ {
Expand All @@ -1339,10 +1337,10 @@ static int run_rewrite_hook(const unsigned char *oldsha1,
int code; int code;
size_t n; size_t n;


if (access(git_path(post_rewrite_hook), X_OK) < 0) argv[0] = find_hook("post-rewrite");
if (!argv[0])
return 0; return 0;


argv[0] = git_path(post_rewrite_hook);
argv[1] = "amend"; argv[1] = "amend";
argv[2] = NULL; argv[2] = NULL;


Expand Down
25 changes: 11 additions & 14 deletions builtin/receive-pack.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -182,9 +182,6 @@ struct command {
char ref_name[FLEX_ARRAY]; /* more */ char ref_name[FLEX_ARRAY]; /* more */
}; };


static const char pre_receive_hook[] = "hooks/pre-receive";
static const char post_receive_hook[] = "hooks/post-receive";

static void rp_error(const char *err, ...) __attribute__((format (printf, 1, 2))); static void rp_error(const char *err, ...) __attribute__((format (printf, 1, 2)));
static void rp_warning(const char *err, ...) __attribute__((format (printf, 1, 2))); static void rp_warning(const char *err, ...) __attribute__((format (printf, 1, 2)));


Expand Down Expand Up @@ -242,10 +239,10 @@ static int run_and_feed_hook(const char *hook_name, feed_fn feed, void *feed_sta
const char *argv[2]; const char *argv[2];
int code; int code;


if (access(hook_name, X_OK) < 0) argv[0] = find_hook(hook_name);
if (!argv[0])
return 0; return 0;


argv[0] = hook_name;
argv[1] = NULL; argv[1] = NULL;


memset(&proc, 0, sizeof(proc)); memset(&proc, 0, sizeof(proc));
Expand Down Expand Up @@ -331,15 +328,14 @@ static int run_receive_hook(struct command *commands, const char *hook_name,


static int run_update_hook(struct command *cmd) static int run_update_hook(struct command *cmd)
{ {
static const char update_hook[] = "hooks/update";
const char *argv[5]; const char *argv[5];
struct child_process proc; struct child_process proc;
int code; int code;


if (access(update_hook, X_OK) < 0) argv[0] = find_hook("update");
if (!argv[0])
return 0; return 0;


argv[0] = update_hook;
argv[1] = cmd->ref_name; argv[1] = cmd->ref_name;
argv[2] = sha1_to_hex(cmd->old_sha1); argv[2] = sha1_to_hex(cmd->old_sha1);
argv[3] = sha1_to_hex(cmd->new_sha1); argv[3] = sha1_to_hex(cmd->new_sha1);
Expand Down Expand Up @@ -532,24 +528,25 @@ static const char *update(struct command *cmd)
} }
} }


static char update_post_hook[] = "hooks/post-update";

static void run_update_post_hook(struct command *commands) static void run_update_post_hook(struct command *commands)
{ {
struct command *cmd; struct command *cmd;
int argc; int argc;
const char **argv; const char **argv;
struct child_process proc; struct child_process proc;
char *hook;


hook = find_hook("post-update");
for (argc = 0, cmd = commands; cmd; cmd = cmd->next) { for (argc = 0, cmd = commands; cmd; cmd = cmd->next) {
if (cmd->error_string || cmd->did_not_exist) if (cmd->error_string || cmd->did_not_exist)
continue; continue;
argc++; argc++;
} }
if (!argc || access(update_post_hook, X_OK) < 0) if (!argc || !hook)
return; return;

argv = xmalloc(sizeof(*argv) * (2 + argc)); argv = xmalloc(sizeof(*argv) * (2 + argc));
argv[0] = update_post_hook; argv[0] = hook;


for (argc = 1, cmd = commands; cmd; cmd = cmd->next) { for (argc = 1, cmd = commands; cmd; cmd = cmd->next) {
char *p; char *p;
Expand Down Expand Up @@ -704,7 +701,7 @@ static void execute_commands(struct command *commands, const char *unpacker_erro
0, &cmd)) 0, &cmd))
set_connectivity_errors(commands); set_connectivity_errors(commands);


if (run_receive_hook(commands, pre_receive_hook, 0)) { if (run_receive_hook(commands, "pre-receive", 0)) {
for (cmd = commands; cmd; cmd = cmd->next) { for (cmd = commands; cmd; cmd = cmd->next) {
if (!cmd->error_string) if (!cmd->error_string)
cmd->error_string = "pre-receive hook declined"; cmd->error_string = "pre-receive hook declined";
Expand Down Expand Up @@ -994,7 +991,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
unlink_or_warn(pack_lockfile); unlink_or_warn(pack_lockfile);
if (report_status) if (report_status)
report(commands, unpack_status); report(commands, unpack_status);
run_receive_hook(commands, post_receive_hook, 1); run_receive_hook(commands, "post-receive", 1);
run_update_post_hook(commands); run_update_post_hook(commands);
if (auto_gc) { if (auto_gc) {
const char *argv_gc_auto[] = { const char *argv_gc_auto[] = {
Expand Down
15 changes: 13 additions & 2 deletions run-command.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -735,6 +735,15 @@ int finish_async(struct async *async)
#endif #endif
} }


char *find_hook(const char *name)
{
char *path = git_path("hooks/%s", name);
if (access(path, X_OK) < 0)
path = NULL;

return path;
}

int run_hook(const char *index_file, const char *name, ...) int run_hook(const char *index_file, const char *name, ...)
{ {
struct child_process hook; struct child_process hook;
Expand All @@ -744,11 +753,13 @@ int run_hook(const char *index_file, const char *name, ...)
va_list args; va_list args;
int ret; int ret;


if (access(git_path("hooks/%s", name), X_OK) < 0) p = find_hook(name);
if (!p)
return 0; return 0;


argv_array_push(&argv, p);

va_start(args, name); va_start(args, name);
argv_array_push(&argv, git_path("hooks/%s", name));
while ((p = va_arg(args, const char *))) while ((p = va_arg(args, const char *)))
argv_array_push(&argv, p); argv_array_push(&argv, p);
va_end(args); va_end(args);
Expand Down
1 change: 1 addition & 0 deletions run-command.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ int start_command(struct child_process *);
int finish_command(struct child_process *); int finish_command(struct child_process *);
int run_command(struct child_process *); int run_command(struct child_process *);


extern char *find_hook(const char *name);
extern int run_hook(const char *index_file, const char *name, ...); extern int run_hook(const char *index_file, const char *name, ...);


#define RUN_COMMAND_NO_STDIN 1 #define RUN_COMMAND_NO_STDIN 1
Expand Down

0 comments on commit 5a7da2d

Please sign in to comment.