From: Thierry Reding <treding@xxxxxxxxxx> The git-am --no-verify flag is analogous to the same flag passed to git-commit. It bypasses the pre-applypatch and applypatch-msg hooks if they are enabled. Signed-off-by: Thierry Reding <treding@xxxxxxxxxx> --- Changes in v2: - add test to verify that the new option works Documentation/git-am.txt | 8 +++++- builtin/am.c | 11 ++++++-- t/t4154-am-noverify.sh | 60 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 4 deletions(-) create mode 100755 t/t4154-am-noverify.sh diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt index 326276e51ce5..0c1dfb3c98b4 100644 --- a/Documentation/git-am.txt +++ b/Documentation/git-am.txt @@ -9,7 +9,7 @@ git-am - Apply a series of patches from a mailbox SYNOPSIS -------- [verse] -'git am' [--signoff] [--keep] [--[no-]keep-cr] [--[no-]utf8] +'git am' [--signoff] [--keep] [--[no-]keep-cr] [--[no-]utf8] [--no-verify] [--[no-]3way] [--interactive] [--committer-date-is-author-date] [--ignore-date] [--ignore-space-change | --ignore-whitespace] [--whitespace=<option>] [-C<n>] [-p<n>] [--directory=<dir>] @@ -138,6 +138,12 @@ include::rerere-options.txt[] --interactive:: Run interactively. +-n:: +--no-verify:: + By default, the pre-applypatch and applypatch-msg hooks are run. + When any of `--no-verify` or `-n` is given, these are bypassed. + See also linkgit:githooks[5]. + --committer-date-is-author-date:: By default the command records the date from the e-mail message as the commit author date, and uses the time of diff --git a/builtin/am.c b/builtin/am.c index 20aea0d2487b..26ad8a468dc4 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -117,6 +117,7 @@ struct am_state { /* various operating modes and command line options */ int interactive; + int no_verify; int threeway; int quiet; int signoff; /* enum signoff_type */ @@ -472,10 +473,12 @@ static void am_destroy(const struct am_state *state) */ static int run_applypatch_msg_hook(struct am_state *state) { - int ret; + int ret = 0; assert(state->msg); - ret = run_hooks_l("applypatch-msg", am_path(state, "final-commit"), NULL); + + if (!state->no_verify) + ret = run_hooks_l("applypatch-msg", am_path(state, "final-commit"), NULL); if (!ret) { FREE_AND_NULL(state->msg); @@ -1640,7 +1643,7 @@ static void do_commit(const struct am_state *state) const char *reflog_msg, *author, *committer = NULL; struct strbuf sb = STRBUF_INIT; - if (run_hooks("pre-applypatch")) + if (!state->no_verify && run_hooks("pre-applypatch")) exit(1); if (write_cache_as_tree(&tree, 0, NULL)) @@ -2329,6 +2332,8 @@ int cmd_am(int argc, const char **argv, const char *prefix) struct option options[] = { OPT_BOOL('i', "interactive", &state.interactive, N_("run interactively")), + OPT_BOOL('n', "no-verify", &state.no_verify, + N_("bypass pre-applypatch and applypatch-msg hooks")), OPT_HIDDEN_BOOL('b', "binary", &binary, N_("historical option -- no-op")), OPT_BOOL('3', "3way", &state.threeway, diff --git a/t/t4154-am-noverify.sh b/t/t4154-am-noverify.sh new file mode 100755 index 000000000000..fbf45998243f --- /dev/null +++ b/t/t4154-am-noverify.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +test_description='git am --no-verify' + +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITAL_BRANCH_NAME + +. ./test-lib.sh + +test_expect_success setup ' + echo "root" >file && + git add file && + git commit -m "zeroth" && + git branch side-success && + git branch side-failure && + echo "foo" >>file && + git add file && + git commit -m "first" && + git format-patch --stdout HEAD^ >patch1 +' + +setup_success_hook () { + test_when_finished "rm -f actual_hooks expected_hooks" && + echo "$1" >expected_hooks && + test_hook "$1" <<-EOF + echo $1 >>actual_hooks + EOF +} + +test_expect_success '--no-verify with succeeding hook' ' + setup_success_hook "pre-applypatch" && + setup_success_hook "applypatch-msg" && + git checkout side-success && + git am --no-verify patch1 +' + +setup_failing_hook () { + test_when_finished "rm -f actual_hooks" && + test_hook "$1" <<-EOF + echo $1-failing-hook >>actual_hooks + exit 1 + EOF +} + +test_expect_failure 'with failing hook' ' + test_when_finished "git am --abort" && + setup_failing_hook "pre-applypatch" && + setup_failing_hook "applypatch-msg" && + git checkout side-failure && + git am patch1 +' + +test_expect_success '--no-verify with failing hook' ' + setup_success_hook "pre-applypatch" && + setup_success_hook "applypatch-msg" && + git checkout side-failure && + git am --no-verify patch1 +' + +test_done -- 2.38.1