Skip to content

Commit d4102be

Browse files
avargitster
authored andcommitted
hook-list.h: add a generated list of hooks, like config-list.h
Resolve a long-standing TODO item in bugreport.c of there being no centralized listing of hooks, this fixes a bug with the bugreport listing only knowing about 1/4 of the p4 hooks. It didn't know about the "reference-transaction" hook either. We can now make sure this is kept up-to-date, as the hook.c library will die if asked to find a hook we don't know about yet. The only (undocumented) exception is the artificial "test-hook" used in our own test suite. Move some of the tests away from the "does-not-exist" pseudo-hook, and test for the new behavior. Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 85f5da5 commit d4102be

File tree

6 files changed

+77
-42
lines changed

6 files changed

+77
-42
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@
191191
/gitweb/static/gitweb.min.*
192192
/config-list.h
193193
/command-list.h
194+
/hook-list.h
194195
*.tar.gz
195196
*.dsc
196197
*.deb

Makefile

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,7 @@ XDIFF_LIB = xdiff/lib.a
817817

818818
GENERATED_H += command-list.h
819819
GENERATED_H += config-list.h
820+
GENERATED_H += hook-list.h
820821

821822
LIB_H := $(sort $(patsubst ./%,%,$(shell git ls-files '*.h' ':!t/' ':!Documentation/' 2>/dev/null || \
822823
$(FIND) . \
@@ -2207,7 +2208,9 @@ git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS)
22072208

22082209
help.sp help.s help.o: command-list.h
22092210

2210-
builtin/help.sp builtin/help.s builtin/help.o: config-list.h GIT-PREFIX
2211+
hook.sp hook.s hook.o: hook-list.h
2212+
2213+
builtin/help.sp builtin/help.s builtin/help.o: config-list.h hook-list.h GIT-PREFIX
22112214
builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \
22122215
'-DGIT_HTML_PATH="$(htmldir_relative_SQ)"' \
22132216
'-DGIT_MAN_PATH="$(mandir_relative_SQ)"' \
@@ -2240,6 +2243,11 @@ command-list.h: $(wildcard Documentation/git*.txt)
22402243
$(patsubst %,--exclude-program %,$(EXCLUDED_PROGRAMS)) \
22412244
command-list.txt >$@+ && mv $@+ $@
22422245

2246+
hook-list.h: generate-hooklist.sh
2247+
hook-list.h: Documentation/githooks.txt
2248+
$(QUIET_GEN)$(SHELL_PATH) ./generate-hooklist.sh \
2249+
>$@+ && mv $@+ $@
2250+
22432251
SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):$(GIT_VERSION):\
22442252
$(localedir_SQ):$(NO_CURL):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\
22452253
$(gitwebdir_SQ):$(PERL_PATH_SQ):$(SANE_TEXT_GREP):$(PAGER_ENV):\
@@ -2890,7 +2898,7 @@ $(SP_OBJ): %.sp: %.c GIT-CFLAGS FORCE
28902898
.PHONY: sparse $(SP_OBJ)
28912899
sparse: $(SP_OBJ)
28922900

2893-
EXCEPT_HDRS := command-list.h config-list.h unicode-width.h compat/% xdiff/%
2901+
EXCEPT_HDRS := command-list.h config-list.h hook-list.h unicode-width.h compat/% xdiff/%
28942902
ifndef GCRYPT_SHA256
28952903
EXCEPT_HDRS += sha256/gcrypt.h
28962904
endif
@@ -2912,7 +2920,7 @@ hdr-check: $(HCO)
29122920
style:
29132921
git clang-format --style file --diff --extensions c,h
29142922

2915-
check: config-list.h command-list.h
2923+
check: config-list.h command-list.h hook-list.h
29162924
@if sparse; \
29172925
then \
29182926
echo >&2 "Use 'make sparse' instead"; \

builtin/bugreport.c

Lines changed: 8 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "help.h"
55
#include "compat/compiler.h"
66
#include "hook.h"
7+
#include "hook-list.h"
78

89

910
static void get_system_info(struct strbuf *sys_info)
@@ -41,49 +42,20 @@ static void get_system_info(struct strbuf *sys_info)
4142

4243
static void get_populated_hooks(struct strbuf *hook_info, int nongit)
4344
{
44-
/*
45-
* NEEDSWORK: Doesn't look like there is a list of all possible hooks;
46-
* so below is a transcription of `git help hooks`. Later, this should
47-
* be replaced with some programmatically generated list (generated from
48-
* doc or else taken from some library which tells us about all the
49-
* hooks)
50-
*/
51-
static const char *hook[] = {
52-
"applypatch-msg",
53-
"pre-applypatch",
54-
"post-applypatch",
55-
"pre-commit",
56-
"pre-merge-commit",
57-
"prepare-commit-msg",
58-
"commit-msg",
59-
"post-commit",
60-
"pre-rebase",
61-
"post-checkout",
62-
"post-merge",
63-
"pre-push",
64-
"pre-receive",
65-
"update",
66-
"post-receive",
67-
"post-update",
68-
"push-to-checkout",
69-
"pre-auto-gc",
70-
"post-rewrite",
71-
"sendemail-validate",
72-
"fsmonitor-watchman",
73-
"p4-pre-submit",
74-
"post-index-change",
75-
};
76-
int i;
45+
const char **p;
7746

7847
if (nongit) {
7948
strbuf_addstr(hook_info,
8049
_("not run from a git repository - no hooks to show\n"));
8150
return;
8251
}
8352

84-
for (i = 0; i < ARRAY_SIZE(hook); i++)
85-
if (hook_exists(hook[i]))
86-
strbuf_addf(hook_info, "%s\n", hook[i]);
53+
for (p = hook_name_list; *p; p++) {
54+
const char *hook = *p;
55+
56+
if (hook_exists(hook))
57+
strbuf_addf(hook_info, "%s\n", hook);
58+
}
8759
}
8860

8961
static const char * const bugreport_usage[] = {

generate-hooklist.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/sh
2+
3+
echo "/* Automatically generated by generate-hooklist.sh */"
4+
5+
print_hook_list () {
6+
cat <<EOF
7+
static const char *hook_name_list[] = {
8+
EOF
9+
perl -ne '
10+
chomp;
11+
@l[$.] = $_;
12+
push @h => $l[$. - 1] if /^~~~+$/s;
13+
END {
14+
print qq[\t"$_",\n] for sort @h;
15+
}
16+
' <Documentation/githooks.txt
17+
cat <<EOF
18+
NULL,
19+
};
20+
EOF
21+
}
22+
23+
echo
24+
print_hook_list

hook.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,33 @@
11
#include "cache.h"
22
#include "hook.h"
33
#include "run-command.h"
4+
#include "hook-list.h"
5+
6+
static int known_hook(const char *name)
7+
{
8+
const char **p;
9+
size_t len = strlen(name);
10+
for (p = hook_name_list; *p; p++) {
11+
const char *hook = *p;
12+
13+
if (!strncmp(name, hook, len) && hook[len] == '\0')
14+
return 1;
15+
}
16+
if (!strcmp(name, "test-hook") ||
17+
!strcmp(name, "does-not-exist"))
18+
return 1;
19+
20+
return 0;
21+
}
422

523
const char *find_hook(const char *name)
624
{
725
static struct strbuf path = STRBUF_INIT;
826

27+
if (!known_hook(name))
28+
die(_("the hook '%s' is not known to git, should be in hook-list.h via githooks(5)"),
29+
name);
30+
931
strbuf_reset(&path);
1032
strbuf_git_path(&path, "hooks/%s", name);
1133
if (access(path.buf, X_OK) < 0) {

t/t1800-hook.sh

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,25 @@ test_description='git-hook command'
66

77
test_expect_success 'git hook run -- nonexistent hook' '
88
cat >stderr.expect <<-\EOF &&
9-
error: cannot find a hook named does-not-exist
9+
error: cannot find a hook named test-hook
1010
EOF
11-
test_expect_code 1 git hook run does-not-exist 2>stderr.actual &&
11+
test_expect_code 1 git hook run test-hook 2>stderr.actual &&
1212
test_cmp stderr.expect stderr.actual
1313
'
1414

1515
test_expect_success 'git hook run -- nonexistent hook with --ignore-missing' '
16-
git hook run --ignore-missing does-not-exist 2>stderr.actual &&
16+
git hook run --ignore-missing test-hook 2>stderr.actual &&
1717
test_must_be_empty stderr.actual
1818
'
1919

20+
test_expect_success 'git hook run -- nonexistent hook with --ignore-missing' '
21+
cat >stderr.expect <<-\EOF &&
22+
fatal: the hook '"'"'unknown-hook'"'"' is not known to git, should be in hook-list.h via githooks(5)
23+
EOF
24+
test_expect_code 128 git hook run unknown-hook 2>stderr.actual &&
25+
test_cmp stderr.expect stderr.actual
26+
'
27+
2028
test_expect_success 'git hook run -- basic' '
2129
write_script .git/hooks/test-hook <<-EOF &&
2230
echo Test hook

0 commit comments

Comments
 (0)