From patchwork Mon Aug 5 22:43:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Josh Steadmon X-Patchwork-Id: 11077833 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DA2F917E0 for ; Mon, 5 Aug 2019 22:43:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C801428970 for ; Mon, 5 Aug 2019 22:43:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BBDB828988; Mon, 5 Aug 2019 22:43:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2764428970 for ; Mon, 5 Aug 2019 22:43:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730733AbfHEWnq (ORCPT ); Mon, 5 Aug 2019 18:43:46 -0400 Received: from mail-vs1-f74.google.com ([209.85.217.74]:47485 "EHLO mail-vs1-f74.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728870AbfHEWnq (ORCPT ); Mon, 5 Aug 2019 18:43:46 -0400 Received: by mail-vs1-f74.google.com with SMTP id d139so21626002vsc.14 for ; Mon, 05 Aug 2019 15:43:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc:content-transfer-encoding; bh=nzXciFsTiMatBZDVhDLZ10LqNSNnvu0f6Z8XDgGSdOM=; b=uALiLqwRsJ0gyrKV5DBYa3M42z9/mzaNaZGusB+1zleSf6yN03/311+bphHq3tgdlx WX+4zgAZg8b+iX/orb0b2Ls59cuRotjmINNyEGULHLXt795bYVCR59n45eyxF2kC3kK0 w4V2bZ4zpAmjzMsAm2TRNqX8xdlTzMBWgYXHNQZAsnHk9Z+vZpkJm3ICjaten13HdJ4F O+nlRumalh4zLAde1Wx97yXvZmhsGzYB38Npc7emMrsA+cj//DKMu6xg9KKjyZ26fsWh NjpjEhRE62W7LpWFG/nTFJxTemXXH4dE+w+0yIHDaQmtKQpDjVNtiXyter4iILoGLTDc Q8kw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc:content-transfer-encoding; bh=nzXciFsTiMatBZDVhDLZ10LqNSNnvu0f6Z8XDgGSdOM=; b=lPqzyDY4gnmxwQllMEcnnjOsKumyGbnM9qF4bNdegdyb0ZzLGreC7NhEUdGu6kdSPr FCTOt1uWU2SvjKUAQqOQMWCHUVzMSyAxqlzwP6TjOJqyNUTb50s3DRZdLkfPzHLbwdgt vFzoxo9P8H7zK6VvDtTv8Ay2+G6W78uYpzcr27wAKgilWGVPbMQuoc28XFqyE9bqFkRc Byqvm8IlGwLcEOMzkdVf2ouB51it4EdR7wsUxjF15BXeeNQNHwg6g49lktQeEcqwgCTt 40THS24gSjGiddud/1gJO5xkdG8wXDkuhwKyuClWrlarf5eoKyyArpAubE4WCzKeO4sn dd3Q== X-Gm-Message-State: APjAAAWjjlSdewL+TGN+bAHp57Y1hg3eBn97dPUzhDf6IkRNFudXv39m sObDmHLYGXnX6fuFBAFkWVJKeaVim9SmRMV6kv6MLsxn6rsv3bmAI0H6yoeLzYbYmeB3c/KxGEL +Cc+b7z0QGMRFZ9vxNJNTbgYPAeeRzqqBFOKSzoG6yoOjJp/kOZJNzTxbX4Wmb9U= X-Google-Smtp-Source: APXvYqyOjjvRpy5MYbq24vRy1swMVb6R0jy/3GEIXxMnEJPdGqk/ER1SYp50ZehnunnjY337xy5VnPJKscqrvw== X-Received: by 2002:a67:ec42:: with SMTP id z2mr463125vso.218.1565045024599; Mon, 05 Aug 2019 15:43:44 -0700 (PDT) Date: Mon, 5 Aug 2019 15:43:36 -0700 In-Reply-To: Message-Id: <50857290955c5467ef6f75083395c695340fa284.1565044345.git.steadmon@google.com> Mime-Version: 1.0 References: X-Mailer: git-send-email 2.22.0.770.g0f2c4a37fd-goog Subject: [PATCH v4 1/4] t7503: verify proper hook execution From: Josh Steadmon To: git@vger.kernel.org Cc: gitster@pobox.com, git@grubix.eu, martin.agren@gmail.com Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP t7503 did not verify that the expected hooks actually ran during testing. Fix that by making the hook scripts write their $0 into a file so that we can compare actual execution vs. expected execution. While we're at it, do some test style cleanups, such as using write_script() and doing setup inside a test_expect_success block. Improved-by: Martin Ågren Signed-off-by: Martin Ågren Signed-off-by: Josh Steadmon --- t/t7503-pre-commit-hook.sh | 157 +++++++++++++++++++++---------------- 1 file changed, 89 insertions(+), 68 deletions(-) diff --git a/t/t7503-pre-commit-hook.sh b/t/t7503-pre-commit-hook.sh index 984889b39d..a71ec31222 100755 --- a/t/t7503-pre-commit-hook.sh +++ b/t/t7503-pre-commit-hook.sh @@ -4,124 +4,144 @@ test_description='pre-commit hook' . ./test-lib.sh -test_expect_success 'with no hook' ' +HOOKDIR="$(git rev-parse --git-dir)/hooks" +PRECOMMIT="$HOOKDIR/pre-commit" + +# Prepare sample scripts that write their $0 to actual_hooks +test_expect_success 'sample script setup' ' + mkdir -p "$HOOKDIR" && + write_script "$HOOKDIR/success.sample" <<-\EOF && + echo $0 >>actual_hooks + exit 0 + EOF + write_script "$HOOKDIR/fail.sample" <<-\EOF && + echo $0 >>actual_hooks + exit 1 + EOF + write_script "$HOOKDIR/non-exec.sample" <<-\EOF && + echo $0 >>actual_hooks + exit 1 + EOF + chmod -x "$HOOKDIR/non-exec.sample" && + write_script "$HOOKDIR/require-prefix.sample" <<-\EOF && + echo $0 >>actual_hooks + test $GIT_PREFIX = "success/" + EOF + write_script "$HOOKDIR/check-author.sample" <<-\EOF + echo $0 >>actual_hooks + test "$GIT_AUTHOR_NAME" = "New Author" && + test "$GIT_AUTHOR_EMAIL" = "newauthor@example.com" + EOF +' - echo "foo" > file && +test_expect_success 'with no hook' ' + test_when_finished "rm -f actual_hooks" && + echo "foo" >file && git add file && - git commit -m "first" - + git commit -m "first" && + test_path_is_missing actual_hooks ' test_expect_success '--no-verify with no hook' ' - - echo "bar" > file && + test_when_finished "rm -f actual_hooks" && + echo "bar" >file && git add file && - git commit --no-verify -m "bar" - + git commit --no-verify -m "bar" && + test_path_is_missing actual_hooks ' -# now install hook that always succeeds -HOOKDIR="$(git rev-parse --git-dir)/hooks" -HOOK="$HOOKDIR/pre-commit" -mkdir -p "$HOOKDIR" -cat > "$HOOK" <> file && + test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" && + ln -s "success.sample" "$PRECOMMIT" && + echo "$PRECOMMIT" >expected_hooks && + echo "more" >>file && git add file && - git commit -m "more" - + git commit -m "more" && + test_cmp expected_hooks actual_hooks ' test_expect_success '--no-verify with succeeding hook' ' - - echo "even more" >> file && + test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" && + ln -s "success.sample" "$PRECOMMIT" && + echo "even more" >>file && git add file && - git commit --no-verify -m "even more" - + git commit --no-verify -m "even more" && + test_path_is_missing actual_hooks ' -# now a hook that fails -cat > "$HOOK" <> file && + test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" && + ln -s "fail.sample" "$PRECOMMIT" && + echo "$PRECOMMIT" >expected_hooks && + echo "another" >>file && git add file && - test_must_fail git commit -m "another" - + test_must_fail git commit -m "another" && + test_cmp expected_hooks actual_hooks ' test_expect_success '--no-verify with failing hook' ' - - echo "stuff" >> file && + test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" && + ln -s "fail.sample" "$PRECOMMIT" && + echo "stuff" >>file && git add file && - git commit --no-verify -m "stuff" - + git commit --no-verify -m "stuff" && + test_path_is_missing actual_hooks ' -chmod -x "$HOOK" test_expect_success POSIXPERM 'with non-executable hook' ' - - echo "content" >> file && + test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" && + ln -s "non-exec.sample" "$PRECOMMIT" && + echo "content" >>file && git add file && - git commit -m "content" - + git commit -m "content" && + test_path_is_missing actual_hooks ' test_expect_success POSIXPERM '--no-verify with non-executable hook' ' - - echo "more content" >> file && + test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" && + ln -s "non-exec.sample" "$PRECOMMIT" && + echo "more content" >>file && git add file && - git commit --no-verify -m "more content" - + git commit --no-verify -m "more content" && + test_path_is_missing actual_hooks ' -chmod +x "$HOOK" - -# a hook that checks $GIT_PREFIX and succeeds inside the -# success/ subdirectory only -cat > "$HOOK" <> file && + test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks success" && + ln -s "require-prefix.sample" "$PRECOMMIT" && + echo "$PRECOMMIT" >expected_hooks && + echo "more content" >>file && git add file && mkdir success && ( cd success && git commit -m "hook requires GIT_PREFIX = success/" ) && - rmdir success + test_cmp expected_hooks actual_hooks ' test_expect_success 'with failing hook requiring GIT_PREFIX' ' - - echo "more content" >> file && + test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks fail" && + ln -s "require-prefix.sample" "$PRECOMMIT" && + echo "$PRECOMMIT" >expected_hooks && + echo "more content" >>file && git add file && mkdir fail && ( cd fail && test_must_fail git commit -m "hook must fail" ) && - rmdir fail && - git checkout -- file + git checkout -- file && + test_cmp expected_hooks actual_hooks ' test_expect_success 'check the author in hook' ' - write_script "$HOOK" <<-\EOF && - test "$GIT_AUTHOR_NAME" = "New Author" && - test "$GIT_AUTHOR_EMAIL" = "newauthor@example.com" + test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" && + ln -s "check-author.sample" "$PRECOMMIT" && + cat >expected_hooks <<-EOF && + $PRECOMMIT + $PRECOMMIT + $PRECOMMIT EOF test_must_fail git commit --allow-empty -m "by a.u.thor" && ( @@ -133,7 +153,8 @@ test_expect_success 'check the author in hook' ' ) && git commit --author="New Author " \ --allow-empty -m "by new.author via command line" && - git show -s + git show -s && + test_cmp expected_hooks actual_hooks ' test_done From patchwork Mon Aug 5 22:43:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josh Steadmon X-Patchwork-Id: 11077837 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D7706912 for ; Mon, 5 Aug 2019 22:43:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C6FA928970 for ; Mon, 5 Aug 2019 22:43:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BB4F328988; Mon, 5 Aug 2019 22:43:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5776A28970 for ; Mon, 5 Aug 2019 22:43:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730883AbfHEWns (ORCPT ); Mon, 5 Aug 2019 18:43:48 -0400 Received: from mail-vs1-f74.google.com ([209.85.217.74]:46504 "EHLO mail-vs1-f74.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728870AbfHEWns (ORCPT ); Mon, 5 Aug 2019 18:43:48 -0400 Received: by mail-vs1-f74.google.com with SMTP id x10so21576227vsp.13 for ; Mon, 05 Aug 2019 15:43:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=8pWHU0VX2sxqhaQaw0+jKNS+pFgW2uare0LdAauOU/Y=; b=WmqPE2vpHJ9iTQfYySrrSofMZDEeshhsrDLqbDPuEJYaWRvpPJl1E9gBDB4X7UG4AS WlfeTYlvN9BFMiwu5aw8GjEIhhK8/bUVYwwq81jhKNIjndeAuNXh8GsKomq8zi3U5XA0 mRYaaXY59hEmsHkPmPXXzsdyn/zxHzDcCemdNlmT+U2yp+iWI09k9OXPKupNJo0qnC4K rVN5j8x9NVpjKNE94ufP2aJ8TDdSYeL9EvP24KEUO2+Oy6i3CpJgqhXfGL657hu2X2A1 KQOgOwXUU4Kl+/+ETw0ahZoGWIwn4JRanLEElEXCqGxoZkmSFmM6L5d8ngQKlumSDokj oFAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=8pWHU0VX2sxqhaQaw0+jKNS+pFgW2uare0LdAauOU/Y=; b=TaWYQBTUXfdLhba04jqAgL71zpXZBhwPqiJkghfkOkSw9ONktyosDHspw0tEInPGdT 7+lun4S4WllRvS4gvPOtqk1ZrGUXGPSm4PblloDaWzEUfQLJ96fD9MTxVJ17kyZEjgru bi1gmlQGy3Z8MIufofMRI/6eliN9VYUyOBtP3kVMf0LiSOl9D+hRbS9QsPcTFXSYwVQ6 hC2c5zFpIPu0QEVGLqqo3QCzqzGZmlNZi7DPgSWs+raYJSBuqF71aKygfcZwvmf/sNE9 /9mpb8WcPEGilwp3EzpSMVTC8fOge8AhF9xVT3Xnjpppg38kgCbyc4M6Qk4/RDfRIUk+ 2Vyw== X-Gm-Message-State: APjAAAUkiMB6k/KNE0RnQiu55drptgxyi8X3jjH2o+ryhTXiLVlgys/M 4U9Xa+C43+SR0ZnGZAI2xVLOPXRVbOkijwlESm+6YI94YXbYCYQpnWJvujWc/LOmWs8jyUMSvxm ImEZdVv1Gv+202m+DhUhHgbg1J9Ev1qJtGq8uBYHDXKrLvzBY+RIk4TjUnj2bZyc= X-Google-Smtp-Source: APXvYqx76SHDX1as/NOkKzwsf17HipmJ2qEGKBqe7lX+puVsTk9Xy3nd9TDbA2mMXsodsWrnDkndCtX0+xYHYA== X-Received: by 2002:ab0:6896:: with SMTP id t22mr330884uar.127.1565045027088; Mon, 05 Aug 2019 15:43:47 -0700 (PDT) Date: Mon, 5 Aug 2019 15:43:37 -0700 In-Reply-To: Message-Id: <3b701a5c41da4f64e0b1cd1ccc94ec8b6aaffd2b.1565044345.git.steadmon@google.com> Mime-Version: 1.0 References: X-Mailer: git-send-email 2.22.0.770.g0f2c4a37fd-goog Subject: [PATCH v4 2/4] merge: do no-verify like commit From: Josh Steadmon To: git@vger.kernel.org Cc: gitster@pobox.com, git@grubix.eu, martin.agren@gmail.com Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Michael J Gruber f8b863598c ("builtin/merge: honor commit-msg hook for merges", 2017-09-07) introduced the no-verify flag to merge for bypassing the commit-msg hook, though in a different way from the implementation in commit.c. Change the implementation in merge.c to be the same as in commit.c so that both do the same in the same way. This also changes the output of "git merge --help" to be more clear that the hook return code is respected by default. [js: * reworded commit message * squashed documentation changes from original series' patch 3/4 ] Signed-off-by: Michael J Gruber Signed-off-by: Josh Steadmon --- Documentation/git-merge.txt | 2 +- Documentation/merge-options.txt | 4 ++++ builtin/merge.c | 6 +++--- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt index 01fd52dc70..092529c619 100644 --- a/Documentation/git-merge.txt +++ b/Documentation/git-merge.txt @@ -10,7 +10,7 @@ SYNOPSIS -------- [verse] 'git merge' [-n] [--stat] [--no-commit] [--squash] [--[no-]edit] - [-s ] [-X ] [-S[]] + [--no-verify] [-s ] [-X ] [-S[]] [--[no-]allow-unrelated-histories] [--[no-]rerere-autoupdate] [-m ] [-F ] [...] 'git merge' (--continue | --abort | --quit) diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt index 79a00d2a4a..d6a9f4b96f 100644 --- a/Documentation/merge-options.txt +++ b/Documentation/merge-options.txt @@ -105,6 +105,10 @@ option can be used to override --squash. + With --squash, --commit is not allowed, and will fail. +--no-verify:: + This option bypasses the pre-merge and commit-msg hooks. + See also linkgit:githooks[5]. + -s :: --strategy=:: Use the given merge strategy; can be supplied more than diff --git a/builtin/merge.c b/builtin/merge.c index e2ccbc44e2..4425a7a12e 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -81,7 +81,7 @@ static int show_progress = -1; static int default_to_upstream = 1; static int signoff; static const char *sign_commit; -static int verify_msg = 1; +static int no_verify; static struct strategy all_strategy[] = { { "recursive", DEFAULT_TWOHEAD | NO_TRIVIAL }, @@ -287,7 +287,7 @@ static struct option builtin_merge_options[] = { N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" }, OPT_BOOL(0, "overwrite-ignore", &overwrite_ignore, N_("update ignored files (default)")), OPT_BOOL(0, "signoff", &signoff, N_("add Signed-off-by:")), - OPT_BOOL(0, "verify", &verify_msg, N_("verify commit-msg hook")), + OPT_BOOL(0, "no-verify", &no_verify, N_("bypass commit-msg hook")), OPT_END() }; @@ -842,7 +842,7 @@ static void prepare_to_commit(struct commit_list *remoteheads) abort_commit(remoteheads, NULL); } - if (verify_msg && run_commit_hook(0 < option_edit, get_index_file(), + if (!no_verify && run_commit_hook(0 < option_edit, get_index_file(), "commit-msg", git_path_merge_msg(the_repository), NULL)) abort_commit(remoteheads, NULL); From patchwork Mon Aug 5 22:43:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Josh Steadmon X-Patchwork-Id: 11077839 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D883A912 for ; Mon, 5 Aug 2019 22:43:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C77D228970 for ; Mon, 5 Aug 2019 22:43:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BBA3028988; Mon, 5 Aug 2019 22:43:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 03B8528970 for ; Mon, 5 Aug 2019 22:43:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730900AbfHEWnv (ORCPT ); Mon, 5 Aug 2019 18:43:51 -0400 Received: from mail-pf1-f202.google.com ([209.85.210.202]:42947 "EHLO mail-pf1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728870AbfHEWnv (ORCPT ); Mon, 5 Aug 2019 18:43:51 -0400 Received: by mail-pf1-f202.google.com with SMTP id 21so54439075pfu.9 for ; Mon, 05 Aug 2019 15:43:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc:content-transfer-encoding; bh=804btAKQYijpGXbztWgXaMENWnVIMZchvAbFQB6y/yE=; b=GvkQuvX6HY3s+3Q2pUm5av/5ogxciZEWvLpTeVACvvOoR/i0ljfMIh430hJUUAH18y B3zEVG/VlFjGCiK9XBdW01buAwHCqem9M+CYo53HccCAn1wX6rmYf3X/isGguM6tYFnG q8bXMdDYVqYgGvfRrTzgK4F2h5FsOLIdtcpWxz9grdiVu6tQYheh2dEUYAcwcAnFXJix y/Uk28IfpkGe5xUi3+rYlZZpp2W/FHkmZ5jb7v6lo+WEtBJBJOX2/gmSbaxo7cgxdvAE PDJWqSeU88Go5+8aV2tZGDL3cOFfUt6ItELCg5CKNf9b6sB9/gpQSKd/CLwntLz/fXQZ 8iHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc:content-transfer-encoding; bh=804btAKQYijpGXbztWgXaMENWnVIMZchvAbFQB6y/yE=; b=m7fR1wqEQDXlk4XdkBZ15miR7JRobVea5meV4gDikUxM7rept+sukHCin4OFI3/zlO D3NTnpgRbE8UFZ6zy3nb91lWEF4MbuWTEb0lpNjJgDprmoV4SG6jifKP3r4QEaExOI+c nf421BLFM50FPJADjprLwBw0pfAirfvJsR6EPkyNY3YZRzv/baGxyhqaIJ6ZaERxz2cd ptsPGwFyJszc0ZjbksetJs8E+IDa0V9uhX3GINAtNkzwyXTTtLwvWYxaOOwMY4UdKRYL /nplOqXPJS0/1H6ozVpPcmNrFgGwJzQWclReQDW4DDX0atDeZIWezMB2hj5zlT4Sql6k Qphg== X-Gm-Message-State: APjAAAUEQQXBxjIAggAlTVRc4THA12PokEzvGwiZ/TFNCr5Drg8r5rFg i+1D2MAwb2xIFV+6SDUwYcYwK/zP8+vZgXjoeb7AvZzpiA5y52egFXItQ3no3/c5sun/eROPzoI zTlZKGs7vKaqXadpnG3aL2BltUU423m6yvnO90iTs/ZIsfhWfNeVORCRvjk5uRiM= X-Google-Smtp-Source: APXvYqx7ya5PciAsLjrorE3NmtA+AzNgGi3qKSZ+SXUwrmvIG2bDOplrdzwB829yV2v6f2CaEXyLwPoqrbCMxw== X-Received: by 2002:a63:6d8d:: with SMTP id i135mr156786pgc.303.1565045029816; Mon, 05 Aug 2019 15:43:49 -0700 (PDT) Date: Mon, 5 Aug 2019 15:43:38 -0700 In-Reply-To: Message-Id: <9210421fbb74c43a8b5e48478229a77ddd50ed3e.1565044345.git.steadmon@google.com> Mime-Version: 1.0 References: X-Mailer: git-send-email 2.22.0.770.g0f2c4a37fd-goog Subject: [PATCH v4 3/4] git-merge: honor pre-merge-commit hook From: Josh Steadmon To: git@vger.kernel.org Cc: gitster@pobox.com, git@grubix.eu, martin.agren@gmail.com Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Michael J Gruber git-merge does not honor the pre-commit hook when doing automatic merge commits, and for compatibility reasons this is going to stay. Introduce a pre-merge-commit hook which is called for an automatic merge commit just like pre-commit is called for a non-automatic merge commit (or any other commit). [js: * renamed hook from "pre-merge" to "pre-merge-commit" * only discard the index if the hook is actually present * expanded githooks documentation entry * clarified that hook should write messages to stderr * squashed test changes from the original series' patch 4/4 * modified tests to follow new pattern from this series' patch 1/4 * added a test case for non-executable merge hooks * added a test case for failed merges * when testing that the merge hook did not run, make sure we actually have a merge to perform (by resetting the "side" branch to its original state). * reworded commit message ] Improved-by: Martin Ågren Signed-off-by: Michael J Gruber Signed-off-by: Martin Ågren Signed-off-by: Josh Steadmon --- Documentation/githooks.txt | 21 +++++ builtin/merge.c | 12 +++ ...-pre-commit-and-pre-merge-commit-hooks.sh} | 84 ++++++++++++++++++- templates/hooks--pre-merge-commit.sample | 13 +++ 4 files changed, 129 insertions(+), 1 deletion(-) rename t/{t7503-pre-commit-hook.sh => t7503-pre-commit-and-pre-merge-commit-hooks.sh} (63%) create mode 100755 templates/hooks--pre-merge-commit.sample diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt index 82cd573776..d9da474fb0 100644 --- a/Documentation/githooks.txt +++ b/Documentation/githooks.txt @@ -103,6 +103,27 @@ The default 'pre-commit' hook, when enabled--and with the `hooks.allownonascii` config option unset or set to false--prevents the use of non-ASCII filenames. +pre-merge-commit +~~~~~~~~~~~~~~~~ + +This hook is invoked by linkgit:git-merge[1]. It takes no parameters, and is +invoked after the merge has been carried out successfully and before +obtaining the proposed commit log message to +make a commit. Exiting with a non-zero status from this script +causes the `git merge` command to abort before creating a commit. + +The default 'pre-merge-commit' hook, when enabled, runs the +'pre-commit' hook, if the latter is enabled. + +This hook is invoked with the environment variable +`GIT_EDITOR=:` if the command will not bring up an editor +to modify the commit message. + +If the merge cannot be carried out automatically, the conflicts +need to be resolved and the result committed separately (see +linkgit:git-merge[1]). At that point, this hook will not be executed, +but the 'pre-commit' hook will, if it is enabled. + prepare-commit-msg ~~~~~~~~~~~~~~~~~~ diff --git a/builtin/merge.c b/builtin/merge.c index 4425a7a12e..bf0ae68c40 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -816,6 +816,18 @@ static void write_merge_heads(struct commit_list *); static void prepare_to_commit(struct commit_list *remoteheads) { struct strbuf msg = STRBUF_INIT; + const char *index_file = get_index_file(); + + if (run_commit_hook(0 < option_edit, index_file, "pre-merge-commit", NULL)) + abort_commit(remoteheads, NULL); + /* + * Re-read the index as pre-merge-commit hook could have updated it, + * and write it out as a tree. We must do this before we invoke + * the editor and after we invoke run_status above. + */ + if (find_hook("pre-merge-commit")) + discard_cache(); + read_cache_from(index_file); strbuf_addbuf(&msg, &merge_msg); if (squash) BUG("the control must not reach here under --squash"); diff --git a/t/t7503-pre-commit-hook.sh b/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh similarity index 63% rename from t/t7503-pre-commit-hook.sh rename to t/t7503-pre-commit-and-pre-merge-commit-hooks.sh index a71ec31222..0700604f03 100755 --- a/t/t7503-pre-commit-hook.sh +++ b/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh @@ -1,11 +1,12 @@ #!/bin/sh -test_description='pre-commit hook' +test_description='pre-commit and pre-merge-commit hooks' . ./test-lib.sh HOOKDIR="$(git rev-parse --git-dir)/hooks" PRECOMMIT="$HOOKDIR/pre-commit" +PREMERGE="$HOOKDIR/pre-merge-commit" # Prepare sample scripts that write their $0 to actual_hooks test_expect_success 'sample script setup' ' @@ -34,6 +35,30 @@ test_expect_success 'sample script setup' ' EOF ' +test_expect_success 'root commit' ' + echo "root" >file && + git add file && + git commit -m "zeroth" && + git checkout -b side && + echo "foo" >foo && + git add foo && + git commit -m "make it non-ff" && + git branch side-orig side && + git checkout master +' + +test_expect_success 'setup conflicting branches' ' + test_when_finished "git checkout master" && + git checkout -b conflicting-a master && + echo a >conflicting && + git add conflicting && + git commit -m conflicting-a && + git checkout -b conflicting-b master && + echo b >conflicting && + git add conflicting && + git commit -m conflicting-b +' + test_expect_success 'with no hook' ' test_when_finished "rm -f actual_hooks" && echo "foo" >file && @@ -42,6 +67,15 @@ test_expect_success 'with no hook' ' test_path_is_missing actual_hooks ' +test_expect_success 'with no hook (merge)' ' + test_when_finished "rm -f actual_hooks" && + git branch -f side side-orig && + git checkout side && + git merge -m "merge master" master && + git checkout master && + test_path_is_missing actual_hooks +' + test_expect_success '--no-verify with no hook' ' test_when_finished "rm -f actual_hooks" && echo "bar" >file && @@ -60,6 +94,34 @@ test_expect_success 'with succeeding hook' ' test_cmp expected_hooks actual_hooks ' +test_expect_success 'with succeeding hook (merge)' ' + test_when_finished "rm -f \"$PREMERGE\" expected_hooks actual_hooks" && + ln -s "success.sample" "$PREMERGE" && + echo "$PREMERGE" >expected_hooks && + git checkout side && + git merge -m "merge master" master && + git checkout master && + test_cmp expected_hooks actual_hooks +' + +test_expect_success 'automatic merge fails; both hooks are available' ' + test_when_finished "rm -f \"$PREMERGE\" \"$PRECOMMIT\"" && + test_when_finished "rm -f expected_hooks actual_hooks" && + test_when_finished "git checkout master" && + ln -s "success.sample" "$PREMERGE" && + ln -s "success.sample" "$PRECOMMIT" && + + git checkout conflicting-a && + test_must_fail git merge -m "merge conflicting-b" conflicting-b && + test_path_is_missing actual_hooks && + + echo "$PRECOMMIT" >expected_hooks && + echo a+b >conflicting && + git add conflicting && + git commit -m "resolve conflict" && + test_cmp expected_hooks actual_hooks +' + test_expect_success '--no-verify with succeeding hook' ' test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" && ln -s "success.sample" "$PRECOMMIT" && @@ -88,6 +150,16 @@ test_expect_success '--no-verify with failing hook' ' test_path_is_missing actual_hooks ' +test_expect_success 'with failing hook (merge)' ' + test_when_finished "rm -f \"$PREMERGE\" expected_hooks actual_hooks" && + ln -s "fail.sample" "$PREMERGE" && + echo "$PREMERGE" >expected_hooks && + git checkout side && + test_must_fail git merge -m "merge master" master && + git checkout master && + test_cmp expected_hooks actual_hooks +' + test_expect_success POSIXPERM 'with non-executable hook' ' test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" && ln -s "non-exec.sample" "$PRECOMMIT" && @@ -106,6 +178,16 @@ test_expect_success POSIXPERM '--no-verify with non-executable hook' ' test_path_is_missing actual_hooks ' +test_expect_success POSIXPERM 'with non-executable hook (merge)' ' + test_when_finished "rm -f \"$PREMERGE\" actual_hooks" && + ln -s "non-exec.sample" "$PREMERGE" && + git branch -f side side-orig && + git checkout side && + git merge -m "merge master" master && + git checkout master && + test_path_is_missing actual_hooks +' + test_expect_success 'with hook requiring GIT_PREFIX' ' test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks success" && ln -s "require-prefix.sample" "$PRECOMMIT" && diff --git a/templates/hooks--pre-merge-commit.sample b/templates/hooks--pre-merge-commit.sample new file mode 100755 index 0000000000..399eab1924 --- /dev/null +++ b/templates/hooks--pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: From patchwork Mon Aug 5 22:43:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Josh Steadmon X-Patchwork-Id: 11077841 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A492E13B1 for ; Mon, 5 Aug 2019 22:43:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 93B9228970 for ; Mon, 5 Aug 2019 22:43:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 87BDE28988; Mon, 5 Aug 2019 22:43:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 01A6628970 for ; Mon, 5 Aug 2019 22:43:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730909AbfHEWny (ORCPT ); Mon, 5 Aug 2019 18:43:54 -0400 Received: from mail-pg1-f202.google.com ([209.85.215.202]:34898 "EHLO mail-pg1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728870AbfHEWny (ORCPT ); Mon, 5 Aug 2019 18:43:54 -0400 Received: by mail-pg1-f202.google.com with SMTP id w12so11316553pgo.2 for ; Mon, 05 Aug 2019 15:43:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc:content-transfer-encoding; bh=ck8Q+Dx5rRcKIcbzYUuy8QgvTj3f9B7xELvz0ItUU/E=; b=tSV9pY+tPU2OkOsOPKXQD4oIQSWDx6AtDYgbfdXcHTtZEkE+kVmJYlHFuBuANuWJP4 h6AeFLnGlsoS0cgaILlIq27kFuBc7JLkVaU0rtxrKFdK/BnwmXwftLUgMn0E9WleZDK9 /0R+dByDbbXOjMxQeadxrZ8Wyl6l18TUhntvvpSO4KXp8jqDeM0YVrlgjXhlJLk3GlRP ywQuhARcXKVfk90c4chbZJafanpKaMO9YEucJVLFLCEN0H5ffO0/8jpVSVntx4+64mnh DvUw/YZ5kn3AMCfbe0Yl2TYyNN+4NZjsoXPbn/6I/C/DW1smOuMM7P75ER7ls5Anbtzk tCaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc:content-transfer-encoding; bh=ck8Q+Dx5rRcKIcbzYUuy8QgvTj3f9B7xELvz0ItUU/E=; b=akbx89Sl44LhAmxaCUEJI7JEoc8e+SWCkOa5ZOKTR7gkbu4FIzuTdMyIdEc0kRwXoP m6CP0W11+LH1TjvilhokFkmr0e5GTxuBRCUndDc/3oO2FkMpCbnvZq+WGldkVVPeJ3+F CbzabrX/SkZ0skkQVVRefl2Rqoh5Pvq+O0UzuwOdv68zASjIbrgVmr2k8hvsh7KrD/FD ecZale2udzebh0B4UsCOw5a6Oh45QGtab82jqq7ghZpeXSv0fVQOuI297hRTuaqAvzDG kexJf+zoAY9LWYp6+ifZ0/qj6K+gxM/QsUsP6EH+9LXrRIA73kHq+3l/InMoj2qvxBfk jgNA== X-Gm-Message-State: APjAAAUAgxwv8u2K/0QmfBqZK/8fPA22Mo9Yy57cUNX4abJJd7l/drD7 cXJ1ibM82RrpW/zyS1lJVenOK52gOHqxVfwINIoVqmgZ0dKXdmdcR/B1ZKBX//bYWE4nH8Ko73k OddScIgSPbwS3eyuhIAN1ZELUy2ccJfTsSwd4npNoKOjg+fFMp6CrFD+SnHOXYUQ= X-Google-Smtp-Source: APXvYqx3w5iFksShXN6/sND3NBLk3u2/ISdNLbOUNLgdeBfNwZJLb69azLH7RoMs5yKq1fI24BcmUUiRU6Rg9w== X-Received: by 2002:a63:9e56:: with SMTP id r22mr164753pgo.221.1565045032385; Mon, 05 Aug 2019 15:43:52 -0700 (PDT) Date: Mon, 5 Aug 2019 15:43:39 -0700 In-Reply-To: Message-Id: <96c54883d3adbe314461c4bf70e7edc9d2ee52d3.1565044345.git.steadmon@google.com> Mime-Version: 1.0 References: X-Mailer: git-send-email 2.22.0.770.g0f2c4a37fd-goog Subject: [PATCH v4 4/4] merge: --no-verify to bypass pre-merge-commit hook From: Josh Steadmon To: git@vger.kernel.org Cc: gitster@pobox.com, git@grubix.eu, martin.agren@gmail.com Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Michael J Gruber Analogous to commit, introduce a '--no-verify' option which bypasses the pre-merge-commit hook. The shorthand '-n' is taken by '--no-stat' already. [js: * reworded commit message to reflect current state of --no-stat flag and new hook name * fixed flag documentation to reflect new hook name * cleaned up trailing whitespace * squashed test changes from the original series' patch 4/4 * modified tests to follow pattern from this series' patch 1/4 * added a test case for --no-verify with non-executable hook * when testing that the merge hook did not run, make sure we actually have a merge to perform (by resetting the "side" branch to its original state). ] Improved-by: Martin Ågren Signed-off-by: Michael J Gruber Signed-off-by: Martin Ågren Signed-off-by: Josh Steadmon --- Documentation/githooks.txt | 3 +- builtin/merge.c | 4 +- ...3-pre-commit-and-pre-merge-commit-hooks.sh | 39 +++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt index d9da474fb0..57d6e2b98d 100644 --- a/Documentation/githooks.txt +++ b/Documentation/githooks.txt @@ -106,7 +106,8 @@ the use of non-ASCII filenames. pre-merge-commit ~~~~~~~~~~~~~~~~ -This hook is invoked by linkgit:git-merge[1]. It takes no parameters, and is +This hook is invoked by linkgit:git-merge[1], and can be bypassed +with the `--no-verify` option. It takes no parameters, and is invoked after the merge has been carried out successfully and before obtaining the proposed commit log message to make a commit. Exiting with a non-zero status from this script diff --git a/builtin/merge.c b/builtin/merge.c index bf0ae68c40..c9746e37b8 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -287,7 +287,7 @@ static struct option builtin_merge_options[] = { N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" }, OPT_BOOL(0, "overwrite-ignore", &overwrite_ignore, N_("update ignored files (default)")), OPT_BOOL(0, "signoff", &signoff, N_("add Signed-off-by:")), - OPT_BOOL(0, "no-verify", &no_verify, N_("bypass commit-msg hook")), + OPT_BOOL(0, "no-verify", &no_verify, N_("bypass pre-merge-commit and commit-msg hooks")), OPT_END() }; @@ -818,7 +818,7 @@ static void prepare_to_commit(struct commit_list *remoteheads) struct strbuf msg = STRBUF_INIT; const char *index_file = get_index_file(); - if (run_commit_hook(0 < option_edit, index_file, "pre-merge-commit", NULL)) + if (!no_verify && run_commit_hook(0 < option_edit, index_file, "pre-merge-commit", NULL)) abort_commit(remoteheads, NULL); /* * Re-read the index as pre-merge-commit hook could have updated it, diff --git a/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh b/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh index 0700604f03..d900c3a696 100755 --- a/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh +++ b/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh @@ -84,6 +84,15 @@ test_expect_success '--no-verify with no hook' ' test_path_is_missing actual_hooks ' +test_expect_success '--no-verify with no hook (merge)' ' + test_when_finished "rm -f actual_hooks" && + git branch -f side side-orig && + git checkout side && + git merge --no-verify -m "merge master" master && + git checkout master && + test_path_is_missing actual_hooks +' + test_expect_success 'with succeeding hook' ' test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" && ln -s "success.sample" "$PRECOMMIT" && @@ -131,6 +140,16 @@ test_expect_success '--no-verify with succeeding hook' ' test_path_is_missing actual_hooks ' +test_expect_success '--no-verify with succeeding hook (merge)' ' + test_when_finished "rm -f \"$PREMERGE\" actual_hooks" && + ln -s "success.sample" "$PREMERGE" && + git branch -f side side-orig && + git checkout side && + git merge --no-verify -m "merge master" master && + git checkout master && + test_path_is_missing actual_hooks +' + test_expect_success 'with failing hook' ' test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" && ln -s "fail.sample" "$PRECOMMIT" && @@ -160,6 +179,16 @@ test_expect_success 'with failing hook (merge)' ' test_cmp expected_hooks actual_hooks ' +test_expect_success '--no-verify with failing hook (merge)' ' + test_when_finished "rm -f \"$PREMERGE\" actual_hooks" && + ln -s "fail.sample" "$PREMERGE" && + git branch -f side side-orig && + git checkout side && + git merge --no-verify -m "merge master" master && + git checkout master && + test_path_is_missing actual_hooks +' + test_expect_success POSIXPERM 'with non-executable hook' ' test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" && ln -s "non-exec.sample" "$PRECOMMIT" && @@ -188,6 +217,16 @@ test_expect_success POSIXPERM 'with non-executable hook (merge)' ' test_path_is_missing actual_hooks ' +test_expect_success POSIXPERM '--no-verify with non-executable hook (merge)' ' + test_when_finished "rm -f \"$PREMERGE\" actual_hooks" && + ln -s "non-exec.sample" "$PREMERGE" && + git branch -f side side-orig && + git checkout side && + git merge --no-verify -m "merge master" master && + git checkout master && + test_path_is_missing actual_hooks +' + test_expect_success 'with hook requiring GIT_PREFIX' ' test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks success" && ln -s "require-prefix.sample" "$PRECOMMIT" &&