This series adds a new pre-merge-commit hook, similar in usage to pre-commit. It also improves hook testing in t7503, by verifying that the correct hooks are run or bypassed as expected. The original series was done by Michael J Gruber <git@xxxxxxxxx>. I have addressed the outstanding review comments, and noted my changes in the commit messages in "[js: ...]" blocks. Changes since V4: * Used "cp" instead of "ln -s" in test hook setup to make tests more portable. Changes since V3: * Applied several test style fixes suggested by Martin (thanks!). * Clarified the documentation for pre-merge-commit hook. * Fixed a few cases where testing that the merge hook did not run might erroneously succeed if we don't have any merge to actually perform. * Simplified test cleanup by adding a new non-executable sample hook script. * Added test cases for non-executable pre-merge-commit hooks. Changes since V2: * Renamed the hook from "pre-merge" to "pre-merge-commit". * Added a new patch (1/4) to improve t7503 by verifying that the expected hooks are (or are not) run. * Squashed test changes (from V2's patch 4/4) into patch 3/4. Modified the tests to follow the example set in patch 1/4. * Reworded commit messages to match with the current state of certain flags, which changed in between V1 and V2 of this series. Josh Steadmon (1): t7503: verify proper hook execution Michael J Gruber (3): merge: do no-verify like commit git-merge: honor pre-merge-commit hook merge: --no-verify to bypass pre-merge-commit hook Documentation/git-merge.txt | 2 +- Documentation/githooks.txt | 22 ++ Documentation/merge-options.txt | 4 + builtin/merge.c | 18 +- ...3-pre-commit-and-pre-merge-commit-hooks.sh | 281 ++++++++++++++++++ t/t7503-pre-commit-hook.sh | 139 --------- templates/hooks--pre-merge-commit.sample | 13 + 7 files changed, 336 insertions(+), 143 deletions(-) create mode 100755 t/t7503-pre-commit-and-pre-merge-commit-hooks.sh delete mode 100755 t/t7503-pre-commit-hook.sh create mode 100755 templates/hooks--pre-merge-commit.sample Range-diff against v4: 1: 5085729095 ! 1: 60bbbbf9e0 t7503: verify proper hook execution @@ t/t7503-pre-commit-hook.sh: test_description='pre-commit hook' - - echo "more" >> file && + test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" && -+ ln -s "success.sample" "$PRECOMMIT" && ++ cp "$HOOKDIR/success.sample" "$PRECOMMIT" && + echo "$PRECOMMIT" >expected_hooks && + echo "more" >>file && git add file && @@ t/t7503-pre-commit-hook.sh: test_description='pre-commit hook' - - echo "even more" >> file && + test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" && -+ ln -s "success.sample" "$PRECOMMIT" && ++ cp "$HOOKDIR/success.sample" "$PRECOMMIT" && + echo "even more" >>file && git add file && - git commit --no-verify -m "even more" @@ t/t7503-pre-commit-hook.sh: test_description='pre-commit hook' - - echo "another" >> file && + test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" && -+ ln -s "fail.sample" "$PRECOMMIT" && ++ cp "$HOOKDIR/fail.sample" "$PRECOMMIT" && + echo "$PRECOMMIT" >expected_hooks && + echo "another" >>file && git add file && @@ t/t7503-pre-commit-hook.sh: test_description='pre-commit hook' - - echo "stuff" >> file && + test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" && -+ ln -s "fail.sample" "$PRECOMMIT" && ++ cp "$HOOKDIR/fail.sample" "$PRECOMMIT" && + echo "stuff" >>file && git add file && - git commit --no-verify -m "stuff" @@ t/t7503-pre-commit-hook.sh: test_description='pre-commit hook' - - echo "content" >> file && + test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" && -+ ln -s "non-exec.sample" "$PRECOMMIT" && ++ cp "$HOOKDIR/non-exec.sample" "$PRECOMMIT" && + echo "content" >>file && git add file && - git commit -m "content" @@ t/t7503-pre-commit-hook.sh: test_description='pre-commit hook' - - echo "more content" >> file && + test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" && -+ ln -s "non-exec.sample" "$PRECOMMIT" && ++ cp "$HOOKDIR/non-exec.sample" "$PRECOMMIT" && + echo "more content" >>file && git add file && - git commit --no-verify -m "more content" @@ t/t7503-pre-commit-hook.sh: test_description='pre-commit hook' - - echo "more content" >> file && + test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks success" && -+ ln -s "require-prefix.sample" "$PRECOMMIT" && ++ cp "$HOOKDIR/require-prefix.sample" "$PRECOMMIT" && + echo "$PRECOMMIT" >expected_hooks && + echo "more content" >>file && git add file && @@ t/t7503-pre-commit-hook.sh: test_description='pre-commit hook' - - echo "more content" >> file && + test_when_finished "rm -rf \"$PRECOMMIT\" expected_hooks actual_hooks fail" && -+ ln -s "require-prefix.sample" "$PRECOMMIT" && ++ cp "$HOOKDIR/require-prefix.sample" "$PRECOMMIT" && + echo "$PRECOMMIT" >expected_hooks && + echo "more content" >>file && git add file && @@ t/t7503-pre-commit-hook.sh: test_description='pre-commit hook' - test "$GIT_AUTHOR_NAME" = "New Author" && - test "$GIT_AUTHOR_EMAIL" = "newauthor@xxxxxxxxxxx" + test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" && -+ ln -s "check-author.sample" "$PRECOMMIT" && ++ cp "$HOOKDIR/check-author.sample" "$PRECOMMIT" && + cat >expected_hooks <<-EOF && + $PRECOMMIT + $PRECOMMIT 2: 3b701a5c41 = 2: 02a97eb369 merge: do no-verify like commit 3: 9210421fbb ! 3: 2d41e0ff79 git-merge: honor pre-merge-commit hook @@ t/t7503-pre-commit-and-pre-merge-commit-hooks.sh: test_expect_success 'with succ +test_expect_success 'with succeeding hook (merge)' ' + test_when_finished "rm -f \"$PREMERGE\" expected_hooks actual_hooks" && -+ ln -s "success.sample" "$PREMERGE" && ++ cp "$HOOKDIR/success.sample" "$PREMERGE" && + echo "$PREMERGE" >expected_hooks && + git checkout side && + git merge -m "merge master" master && @@ t/t7503-pre-commit-and-pre-merge-commit-hooks.sh: test_expect_success 'with succ + 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" && ++ cp "$HOOKDIR/success.sample" "$PREMERGE" && ++ cp "$HOOKDIR/success.sample" "$PRECOMMIT" && + + git checkout conflicting-a && + test_must_fail git merge -m "merge conflicting-b" conflicting-b && @@ t/t7503-pre-commit-and-pre-merge-commit-hooks.sh: test_expect_success 'with succ + test_expect_success '--no-verify with succeeding hook' ' test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" && - ln -s "success.sample" "$PRECOMMIT" && + cp "$HOOKDIR/success.sample" "$PRECOMMIT" && @@ t/t7503-pre-commit-and-pre-merge-commit-hooks.sh: 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" && ++ cp "$HOOKDIR/fail.sample" "$PREMERGE" && + echo "$PREMERGE" >expected_hooks && + git checkout side && + test_must_fail git merge -m "merge master" master && @@ t/t7503-pre-commit-and-pre-merge-commit-hooks.sh: test_expect_success '--no-veri + test_expect_success POSIXPERM 'with non-executable hook' ' test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" && - ln -s "non-exec.sample" "$PRECOMMIT" && + cp "$HOOKDIR/non-exec.sample" "$PRECOMMIT" && @@ t/t7503-pre-commit-and-pre-merge-commit-hooks.sh: 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" && ++ cp "$HOOKDIR/non-exec.sample" "$PREMERGE" && + git branch -f side side-orig && + git checkout side && + git merge -m "merge master" master && @@ t/t7503-pre-commit-and-pre-merge-commit-hooks.sh: test_expect_success POSIXPERM + 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" && + cp "$HOOKDIR/require-prefix.sample" "$PRECOMMIT" && ## templates/hooks--pre-merge-commit.sample (new) ## @@ 4: 96c54883d3 ! 4: 7b81e2717f merge: --no-verify to bypass pre-merge-commit hook @@ t/t7503-pre-commit-and-pre-merge-commit-hooks.sh: test_expect_success '--no-veri + test_expect_success 'with succeeding hook' ' test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" && - ln -s "success.sample" "$PRECOMMIT" && + cp "$HOOKDIR/success.sample" "$PRECOMMIT" && @@ t/t7503-pre-commit-and-pre-merge-commit-hooks.sh: 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" && ++ cp "$HOOKDIR/success.sample" "$PREMERGE" && + git branch -f side side-orig && + git checkout side && + git merge --no-verify -m "merge master" master && @@ t/t7503-pre-commit-and-pre-merge-commit-hooks.sh: test_expect_success '--no-veri + test_expect_success 'with failing hook' ' test_when_finished "rm -f \"$PRECOMMIT\" expected_hooks actual_hooks" && - ln -s "fail.sample" "$PRECOMMIT" && + cp "$HOOKDIR/fail.sample" "$PRECOMMIT" && @@ t/t7503-pre-commit-and-pre-merge-commit-hooks.sh: 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" && ++ cp "$HOOKDIR/fail.sample" "$PREMERGE" && + git branch -f side side-orig && + git checkout side && + git merge --no-verify -m "merge master" master && @@ t/t7503-pre-commit-and-pre-merge-commit-hooks.sh: test_expect_success 'with fail + test_expect_success POSIXPERM 'with non-executable hook' ' test_when_finished "rm -f \"$PRECOMMIT\" actual_hooks" && - ln -s "non-exec.sample" "$PRECOMMIT" && + cp "$HOOKDIR/non-exec.sample" "$PRECOMMIT" && @@ t/t7503-pre-commit-and-pre-merge-commit-hooks.sh: 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" && ++ cp "$HOOKDIR/non-exec.sample" "$PREMERGE" && + git branch -f side side-orig && + git checkout side && + git merge --no-verify -m "merge master" master && @@ t/t7503-pre-commit-and-pre-merge-commit-hooks.sh: test_expect_success POSIXPERM + 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" && + cp "$HOOKDIR/require-prefix.sample" "$PRECOMMIT" && -- 2.22.0.770.g0f2c4a37fd-goog