Merge branch 'dm/run-command-ignored-hook-advise'

A hook script that is set unexecutable is simply ignored.  Git
notifies when such a file is ignored, unless the message is
squelched via advice.ignoredHook configuration.

* dm/run-command-ignored-hook-advise:
  run-command: add hint when a hook is ignored
This commit is contained in:
Junio C Hamano
2017-11-06 14:24:22 +09:00
6 changed files with 66 additions and 0 deletions

View File

@ -351,6 +351,9 @@ advice.*::
addEmbeddedRepo:: addEmbeddedRepo::
Advice on what to do when you've accidentally added one Advice on what to do when you've accidentally added one
git repo inside of another. git repo inside of another.
ignoredHook::
Advice shown if an hook is ignored because the hook is not
set as executable.
-- --
core.fileMode:: core.fileMode::

View File

@ -17,6 +17,7 @@ int advice_set_upstream_failure = 1;
int advice_object_name_warning = 1; int advice_object_name_warning = 1;
int advice_rm_hints = 1; int advice_rm_hints = 1;
int advice_add_embedded_repo = 1; int advice_add_embedded_repo = 1;
int advice_ignored_hook = 1;
static struct { static struct {
const char *name; const char *name;
@ -38,6 +39,7 @@ static struct {
{ "objectnamewarning", &advice_object_name_warning }, { "objectnamewarning", &advice_object_name_warning },
{ "rmhints", &advice_rm_hints }, { "rmhints", &advice_rm_hints },
{ "addembeddedrepo", &advice_add_embedded_repo }, { "addembeddedrepo", &advice_add_embedded_repo },
{ "ignoredhook", &advice_ignored_hook },
/* make this an alias for backward compatibility */ /* make this an alias for backward compatibility */
{ "pushnonfastforward", &advice_push_update_rejected } { "pushnonfastforward", &advice_push_update_rejected }

View File

@ -19,6 +19,7 @@ extern int advice_set_upstream_failure;
extern int advice_object_name_warning; extern int advice_object_name_warning;
extern int advice_rm_hints; extern int advice_rm_hints;
extern int advice_add_embedded_repo; extern int advice_add_embedded_repo;
extern int advice_ignored_hook;
int git_default_advice_config(const char *var, const char *value); int git_default_advice_config(const char *var, const char *value);
__attribute__((format (printf, 1, 2))) __attribute__((format (printf, 1, 2)))

View File

@ -2350,6 +2350,7 @@ _git_config ()
advice.rmHints advice.rmHints
advice.statusHints advice.statusHints
advice.statusUoption advice.statusUoption
advice.ignoredHook
alias. alias.
am.keepcr am.keepcr
am.threeWay am.threeWay

View File

@ -5,6 +5,7 @@
#include "argv-array.h" #include "argv-array.h"
#include "thread-utils.h" #include "thread-utils.h"
#include "strbuf.h" #include "strbuf.h"
#include "string-list.h"
void child_process_init(struct child_process *child) void child_process_init(struct child_process *child)
{ {
@ -1169,11 +1170,28 @@ const char *find_hook(const char *name)
strbuf_reset(&path); strbuf_reset(&path);
strbuf_git_path(&path, "hooks/%s", name); strbuf_git_path(&path, "hooks/%s", name);
if (access(path.buf, X_OK) < 0) { if (access(path.buf, X_OK) < 0) {
int err = errno;
#ifdef STRIP_EXTENSION #ifdef STRIP_EXTENSION
strbuf_addstr(&path, STRIP_EXTENSION); strbuf_addstr(&path, STRIP_EXTENSION);
if (access(path.buf, X_OK) >= 0) if (access(path.buf, X_OK) >= 0)
return path.buf; return path.buf;
if (errno == EACCES)
err = errno;
#endif #endif
if (err == EACCES && advice_ignored_hook) {
static struct string_list advise_given = STRING_LIST_INIT_DUP;
if (!string_list_lookup(&advise_given, name)) {
string_list_insert(&advise_given, name);
advise(_("The '%s' hook was ignored because "
"it's not set as executable.\n"
"You can disable this warning with "
"`git config advice.ignoredHook false`."),
path.buf);
}
}
return NULL; return NULL;
} }
return path.buf; return path.buf;

41
t/t7520-ignored-hook-warning.sh Executable file
View File

@ -0,0 +1,41 @@
#!/bin/sh
test_description='ignored hook warning'
. ./test-lib.sh
test_expect_success setup '
hookdir="$(git rev-parse --git-dir)/hooks" &&
hook="$hookdir/pre-commit" &&
mkdir -p "$hookdir" &&
write_script "$hook" <<-\EOF
exit 0
EOF
'
test_expect_success 'no warning if hook is not ignored' '
git commit --allow-empty -m "more" 2>message &&
test_i18ngrep ! -e "hook was ignored" message
'
test_expect_success POSIXPERM 'warning if hook is ignored' '
chmod -x "$hook" &&
git commit --allow-empty -m "even more" 2>message &&
test_i18ngrep -e "hook was ignored" message
'
test_expect_success POSIXPERM 'no warning if advice.ignoredHook set to false' '
test_config advice.ignoredHook false &&
chmod -x "$hook" &&
git commit --allow-empty -m "even more" 2>message &&
test_i18ngrep ! -e "hook was ignored" message
'
test_expect_success 'no warning if unset advice.ignoredHook and hook removed' '
rm -f "$hook" &&
test_unconfig advice.ignoredHook &&
git commit --allow-empty -m "even more" 2>message &&
test_i18ngrep ! -e "hook was ignored" message
'
test_done