@@ -8,7 +8,7 @@ git-hook - Manage configured hooks
SYNOPSIS
--------
[verse]
-'git hook' list <hook-name>
+'git hook' list [--porcelain] <hook-name>
DESCRIPTION
-----------
@@ -43,11 +43,20 @@ Local config
COMMANDS
--------
-list <hook-name>::
+list [--porcelain] <hook-name>::
List the hooks which have been configured for <hook-name>. Hooks appear
in the order they should be run, and note the config scope where the relevant
`hook.<hook-name>.command` was specified, not the `hookcmd` (if applicable).
++
+If `--porcelain` is specified, instead print the commands alone, separated by
+newlines, for easy parsing by a script.
+
+OPTIONS
+-------
+--porcelain::
+ With `list`, print the commands in the order they should be run,
+ separated by newlines, for easy parsing by a script.
GIT
---
@@ -16,8 +16,11 @@ static int list(int argc, const char **argv, const char *prefix)
struct list_head *head, *pos;
struct hook *item;
struct strbuf hookname = STRBUF_INIT;
+ int porcelain = 0;
struct option list_options[] = {
+ OPT_BOOL(0, "porcelain", &porcelain,
+ "format for execution by a script"),
OPT_END(),
};
@@ -29,6 +32,8 @@ static int list(int argc, const char **argv, const char *prefix)
builtin_hook_usage, list_options);
}
+
+
strbuf_addstr(&hookname, argv[0]);
head = hook_list(&hookname);
@@ -41,10 +46,14 @@ static int list(int argc, const char **argv, const char *prefix)
list_for_each(pos, head) {
item = list_entry(pos, struct hook, list);
- if (item)
- printf("%s:\t%s\n",
- config_scope_name(item->origin),
- item->command.buf);
+ if (item) {
+ if (porcelain)
+ printf("%s\n", item->command.buf);
+ else
+ printf("%s:\t%s\n",
+ config_scope_name(item->origin),
+ item->command.buf);
+ }
}
clear_hook_list();
@@ -72,4 +72,16 @@ test_expect_success 'git hook list reorders on duplicate commands' '
test_cmp expected actual
'
+test_expect_success 'git hook list --porcelain prints just the command' '
+ setup_hooks &&
+
+ cat >expected <<-EOF &&
+ $ROOT/path/def
+ $ROOT/path/ghi
+ EOF
+
+ git hook list --porcelain pre-commit >actual &&
+ test_cmp expected actual
+'
+
test_done
Teach 'git hook list --porcelain <hookname>', which prints simply the commands to be run in the order suggested by the config. This option is intended for use by user scripts, wrappers, or out-of-process Git commands which still want to execute hooks. For example, the following snippet might be added to git-send-email.perl to introduce a `pre-send-email` hook: sub pre_send_email { open(my $fh, 'git hook list --porcelain pre-send-email |'); chomp(my @hooks = <$fh>); close($fh); foreach $hook (@hooks) { system $hook } Signed-off-by: Emily Shaffer <emilyshaffer@google.com> --- Documentation/git-hook.txt | 13 +++++++++++-- builtin/hook.c | 17 +++++++++++++---- t/t1360-config-based-hooks.sh | 12 ++++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-)