git/t/t7504-commit-msg-hook.sh

309 lines
6.7 KiB
Bash
Raw Normal View History

#!/bin/sh
test_description='commit-msg hook'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
tests: mark tests relying on the current default for `init.defaultBranch` In addition to the manual adjustment to let the `linux-gcc` CI job run the test suite with `master` and then with `main`, this patch makes sure that GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME is set in all test scripts that currently rely on the initial branch name being `master by default. To determine which test scripts to mark up, the first step was to force-set the default branch name to `master` in - all test scripts that contain the keyword `master`, - t4211, which expects `t/t4211/history.export` with a hard-coded ref to initialize the default branch, - t5560 because it sources `t/t556x_common` which uses `master`, - t8002 and t8012 because both source `t/annotate-tests.sh` which also uses `master`) This trick was performed by this command: $ sed -i '/^ *\. \.\/\(test-lib\|lib-\(bash\|cvs\|git-svn\)\|gitweb-lib\)\.sh$/i\ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\ ' $(git grep -l master t/t[0-9]*.sh) \ t/t4211*.sh t/t5560*.sh t/t8002*.sh t/t8012*.sh After that, careful, manual inspection revealed that some of the test scripts containing the needle `master` do not actually rely on a specific default branch name: either they mention `master` only in a comment, or they initialize that branch specificially, or they do not actually refer to the current default branch. Therefore, the aforementioned modification was undone in those test scripts thusly: $ git checkout HEAD -- \ t/t0027-auto-crlf.sh t/t0060-path-utils.sh \ t/t1011-read-tree-sparse-checkout.sh \ t/t1305-config-include.sh t/t1309-early-config.sh \ t/t1402-check-ref-format.sh t/t1450-fsck.sh \ t/t2024-checkout-dwim.sh \ t/t2106-update-index-assume-unchanged.sh \ t/t3040-subprojects-basic.sh t/t3301-notes.sh \ t/t3308-notes-merge.sh t/t3423-rebase-reword.sh \ t/t3436-rebase-more-options.sh \ t/t4015-diff-whitespace.sh t/t4257-am-interactive.sh \ t/t5323-pack-redundant.sh t/t5401-update-hooks.sh \ t/t5511-refspec.sh t/t5526-fetch-submodules.sh \ t/t5529-push-errors.sh t/t5530-upload-pack-error.sh \ t/t5548-push-porcelain.sh \ t/t5552-skipping-fetch-negotiator.sh \ t/t5572-pull-submodule.sh t/t5608-clone-2gb.sh \ t/t5614-clone-submodules-shallow.sh \ t/t7508-status.sh t/t7606-merge-custom.sh \ t/t9302-fast-import-unpack-limit.sh We excluded one set of test scripts in these commands, though: the range of `git p4` tests. The reason? `git p4` stores the (foreign) remote branch in the branch called `p4/master`, which is obviously not the default branch. Manual analysis revealed that only five of these tests actually require a specific default branch name to pass; They were modified thusly: $ sed -i '/^ *\. \.\/lib-git-p4\.sh$/i\ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\ ' t/t980[0167]*.sh t/t9811*.sh Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-19 07:44:19 +08:00
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. ./test-lib.sh
test_expect_success 'with no hook' '
echo "foo" > file &&
git add file &&
git commit -m "first"
'
# set up fake editor for interactive editing
cat > fake-editor <<'EOF'
#!/bin/sh
cp FAKE_MSG "$1"
exit 0
EOF
chmod +x fake-editor
## Not using test_set_editor here so we can easily ensure the editor variable
## is only set for the editor tests
FAKE_EDITOR="$(pwd)/fake-editor"
export FAKE_EDITOR
test_expect_success 'with no hook (editor)' '
echo "more foo" >> file &&
git add file &&
echo "more foo" > FAKE_MSG &&
GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit
'
test_expect_success '--no-verify with no hook' '
echo "bar" > file &&
git add file &&
git commit --no-verify -m "bar"
'
test_expect_success '--no-verify with no hook (editor)' '
echo "more bar" > file &&
git add file &&
echo "more bar" > FAKE_MSG &&
GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
'
test_expect_success 'setup: commit-msg hook that always succeeds' '
test_hook --setup commit-msg <<-\EOF
exit 0
EOF
'
test_expect_success 'with succeeding hook' '
echo "more" >> file &&
git add file &&
git commit -m "more"
'
test_expect_success 'with succeeding hook (editor)' '
echo "more more" >> file &&
git add file &&
echo "more more" > FAKE_MSG &&
GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit
'
test_expect_success '--no-verify with succeeding hook' '
echo "even more" >> file &&
git add file &&
git commit --no-verify -m "even more"
'
test_expect_success '--no-verify with succeeding hook (editor)' '
echo "even more more" >> file &&
git add file &&
echo "even more more" > FAKE_MSG &&
GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
'
test_expect_success 'setup: commit-msg hook that always fails' '
test_hook --clobber commit-msg <<-\EOF
exit 1
EOF
'
builtin/merge: honor commit-msg hook for merges Similar to 65969d43d1 (merge: honor prepare-commit-msg hook, 2011-02-14) merge should also honor the commit-msg hook: When a merge is stopped due to conflicts or --no-commit, the subsequent commit calls the commit-msg hook. However, it is not called after a clean merge. Fix this inconsistency by invoking the hook after clean merges as well. This change is motivated by Gerrit's commit-msg hook to install a ChangeId trailer into the commit message. Without such a ChangeId, Gerrit refuses to accept any commit by default, such that the inconsistency of (not) running the commit-msg hook between commit and merge leads to confusion and might block people from getting their work done. As the githooks man page is very vocal about the possibility of skipping the commit-msg hook via the --no-verify option, implement the option in merge, too. 'git merge --continue' is currently implemented as calling cmd_commit with no further arguments. This works for most other merge related options, such as demonstrated via the --allow-unrelated-histories flag in the test. The --no-verify option however is not remembered across invocations of git-merge. Originally the author assumed an alternative in which the 'git merge --continue' command accepts the --no-verify flag, but that opens up the discussion which flags are allows to the continued merge command and which must be given in the first invocation. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-08 06:04:29 +08:00
commit_msg_is () {
test "$(git log --pretty=format:%s%b -1)" = "$1"
}
Sane use of test_expect_failure Originally, test_expect_failure was designed to be the opposite of test_expect_success, but this was a bad decision. Most tests run a series of commands that leads to the single command that needs to be tested, like this: test_expect_{success,failure} 'test title' ' setup1 && setup2 && setup3 && what is to be tested ' And expecting a failure exit from the whole sequence misses the point of writing tests. Your setup$N that are supposed to succeed may have failed without even reaching what you are trying to test. The only valid use of test_expect_failure is to check a trivial single command that is expected to fail, which is a minority in tests of Porcelain-ish commands. This large-ish patch rewrites all uses of test_expect_failure to use test_expect_success and rewrites the condition of what is tested, like this: test_expect_success 'test title' ' setup1 && setup2 && setup3 && ! this command should fail ' test_expect_failure is redefined to serve as a reminder that that test *should* succeed but due to a known breakage in git it currently does not pass. So if git-foo command should create a file 'bar' but you discovered a bug that it doesn't, you can write a test like this: test_expect_failure 'git-foo should create bar' ' rm -f bar && git foo && test -f bar ' This construct acts similar to test_expect_success, but instead of reporting "ok/FAIL" like test_expect_success does, the outcome is reported as "FIXED/still broken". Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-02-01 17:50:53 +08:00
test_expect_success 'with failing hook' '
echo "another" >> file &&
git add file &&
test_must_fail git commit -m "another"
'
Sane use of test_expect_failure Originally, test_expect_failure was designed to be the opposite of test_expect_success, but this was a bad decision. Most tests run a series of commands that leads to the single command that needs to be tested, like this: test_expect_{success,failure} 'test title' ' setup1 && setup2 && setup3 && what is to be tested ' And expecting a failure exit from the whole sequence misses the point of writing tests. Your setup$N that are supposed to succeed may have failed without even reaching what you are trying to test. The only valid use of test_expect_failure is to check a trivial single command that is expected to fail, which is a minority in tests of Porcelain-ish commands. This large-ish patch rewrites all uses of test_expect_failure to use test_expect_success and rewrites the condition of what is tested, like this: test_expect_success 'test title' ' setup1 && setup2 && setup3 && ! this command should fail ' test_expect_failure is redefined to serve as a reminder that that test *should* succeed but due to a known breakage in git it currently does not pass. So if git-foo command should create a file 'bar' but you discovered a bug that it doesn't, you can write a test like this: test_expect_failure 'git-foo should create bar' ' rm -f bar && git foo && test -f bar ' This construct acts similar to test_expect_success, but instead of reporting "ok/FAIL" like test_expect_success does, the outcome is reported as "FIXED/still broken". Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-02-01 17:50:53 +08:00
test_expect_success 'with failing hook (editor)' '
echo "more another" >> file &&
git add file &&
echo "more another" > FAKE_MSG &&
! (GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit)
'
test_expect_success '--no-verify with failing hook' '
echo "stuff" >> file &&
git add file &&
git commit --no-verify -m "stuff"
'
test_expect_success '-n followed by --verify with failing hook' '
echo "even more" >> file &&
git add file &&
test_must_fail git commit -n --verify -m "even more"
'
test_expect_success '--no-verify with failing hook (editor)' '
echo "more stuff" >> file &&
git add file &&
echo "more stuff" > FAKE_MSG &&
GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
'
builtin/merge: honor commit-msg hook for merges Similar to 65969d43d1 (merge: honor prepare-commit-msg hook, 2011-02-14) merge should also honor the commit-msg hook: When a merge is stopped due to conflicts or --no-commit, the subsequent commit calls the commit-msg hook. However, it is not called after a clean merge. Fix this inconsistency by invoking the hook after clean merges as well. This change is motivated by Gerrit's commit-msg hook to install a ChangeId trailer into the commit message. Without such a ChangeId, Gerrit refuses to accept any commit by default, such that the inconsistency of (not) running the commit-msg hook between commit and merge leads to confusion and might block people from getting their work done. As the githooks man page is very vocal about the possibility of skipping the commit-msg hook via the --no-verify option, implement the option in merge, too. 'git merge --continue' is currently implemented as calling cmd_commit with no further arguments. This works for most other merge related options, such as demonstrated via the --allow-unrelated-histories flag in the test. The --no-verify option however is not remembered across invocations of git-merge. Originally the author assumed an alternative in which the 'git merge --continue' command accepts the --no-verify flag, but that opens up the discussion which flags are allows to the continued merge command and which must be given in the first invocation. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-08 06:04:29 +08:00
test_expect_success 'merge fails with failing hook' '
test_when_finished "git branch -D newbranch" &&
test_when_finished "git checkout -f main" &&
builtin/merge: honor commit-msg hook for merges Similar to 65969d43d1 (merge: honor prepare-commit-msg hook, 2011-02-14) merge should also honor the commit-msg hook: When a merge is stopped due to conflicts or --no-commit, the subsequent commit calls the commit-msg hook. However, it is not called after a clean merge. Fix this inconsistency by invoking the hook after clean merges as well. This change is motivated by Gerrit's commit-msg hook to install a ChangeId trailer into the commit message. Without such a ChangeId, Gerrit refuses to accept any commit by default, such that the inconsistency of (not) running the commit-msg hook between commit and merge leads to confusion and might block people from getting their work done. As the githooks man page is very vocal about the possibility of skipping the commit-msg hook via the --no-verify option, implement the option in merge, too. 'git merge --continue' is currently implemented as calling cmd_commit with no further arguments. This works for most other merge related options, such as demonstrated via the --allow-unrelated-histories flag in the test. The --no-verify option however is not remembered across invocations of git-merge. Originally the author assumed an alternative in which the 'git merge --continue' command accepts the --no-verify flag, but that opens up the discussion which flags are allows to the continued merge command and which must be given in the first invocation. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-08 06:04:29 +08:00
git checkout --orphan newbranch &&
: >file2 &&
git add file2 &&
git commit --no-verify file2 -m in-side-branch &&
test_must_fail git merge --allow-unrelated-histories main &&
builtin/merge: honor commit-msg hook for merges Similar to 65969d43d1 (merge: honor prepare-commit-msg hook, 2011-02-14) merge should also honor the commit-msg hook: When a merge is stopped due to conflicts or --no-commit, the subsequent commit calls the commit-msg hook. However, it is not called after a clean merge. Fix this inconsistency by invoking the hook after clean merges as well. This change is motivated by Gerrit's commit-msg hook to install a ChangeId trailer into the commit message. Without such a ChangeId, Gerrit refuses to accept any commit by default, such that the inconsistency of (not) running the commit-msg hook between commit and merge leads to confusion and might block people from getting their work done. As the githooks man page is very vocal about the possibility of skipping the commit-msg hook via the --no-verify option, implement the option in merge, too. 'git merge --continue' is currently implemented as calling cmd_commit with no further arguments. This works for most other merge related options, such as demonstrated via the --allow-unrelated-histories flag in the test. The --no-verify option however is not remembered across invocations of git-merge. Originally the author assumed an alternative in which the 'git merge --continue' command accepts the --no-verify flag, but that opens up the discussion which flags are allows to the continued merge command and which must be given in the first invocation. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-08 06:04:29 +08:00
commit_msg_is "in-side-branch" # HEAD before merge
'
test_expect_success 'merge bypasses failing hook with --no-verify' '
test_when_finished "git branch -D newbranch" &&
test_when_finished "git checkout -f main" &&
builtin/merge: honor commit-msg hook for merges Similar to 65969d43d1 (merge: honor prepare-commit-msg hook, 2011-02-14) merge should also honor the commit-msg hook: When a merge is stopped due to conflicts or --no-commit, the subsequent commit calls the commit-msg hook. However, it is not called after a clean merge. Fix this inconsistency by invoking the hook after clean merges as well. This change is motivated by Gerrit's commit-msg hook to install a ChangeId trailer into the commit message. Without such a ChangeId, Gerrit refuses to accept any commit by default, such that the inconsistency of (not) running the commit-msg hook between commit and merge leads to confusion and might block people from getting their work done. As the githooks man page is very vocal about the possibility of skipping the commit-msg hook via the --no-verify option, implement the option in merge, too. 'git merge --continue' is currently implemented as calling cmd_commit with no further arguments. This works for most other merge related options, such as demonstrated via the --allow-unrelated-histories flag in the test. The --no-verify option however is not remembered across invocations of git-merge. Originally the author assumed an alternative in which the 'git merge --continue' command accepts the --no-verify flag, but that opens up the discussion which flags are allows to the continued merge command and which must be given in the first invocation. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-08 06:04:29 +08:00
git checkout --orphan newbranch &&
merge-recursive: enforce rule that index matches head before merging builtin/merge.c says that when we are about to perform a merge: ...the index must be in sync with the head commit. The strategies are responsible to ensure this. merge-recursive has always relied on unpack_trees() to enforce this requirement, except in the case of an "Already up to date!" merge. unpack-trees.c does not actually enforce this requirement, though. It allows for a pair of exceptions, in cases which it refers to as #14(ALT) and #2ALT. Documentation/technical/trivial-merge.txt can be consulted for the precise meanings of the various case numbers and their meanings for unpack-trees.c, but we have a high-level description of the intent behind these two exceptions in a combined and summarized form in Documentation/git-merge.txt: ...[merge will] abort if there are any changes registered in the index relative to the `HEAD` commit. (One exception is when the changed index entries are in the state that would result from the merge already.) While this high-level description does describe conditions under which it would be safe to allow the index to diverge from HEAD, it does not match what is actually implemented. In particular, unpack-trees.c has no knowledge of renames, and these two exceptions were written assuming that no renames take place. Once renames get into the mix, it is no longer safe to allow the index to not match for #2ALT. We could modify unpack-trees to only allow #14(ALT) as an exception, but that would be more strict than required for the resolve strategy (since the resolve strategy doesn't handle renames at all). Therefore, unpack_trees.c seems like the wrong place to fix this. Further, if someone fixes the combination of break and rename detection and modifies merge-recursive to take advantage of the combination, then it will also no longer be safe to allow the index to not match for #14(ALT) when the recursive strategy is in use. Therefore, leaving one of the exceptions in place with the recursive merge strategy feels like we are just leaving a latent bug in the code for folks in the future to stumble across. It may be possible to fix both unpack-trees and merge-recursive in a way that implements the exception as stated in Documentation/git-merge.txt, but it would be somewhat complex, possibly also buggy at first, and ultimately, not all that valuable. Instead, just enforce the requirement stated in builtin/merge.c; error out if the index does not match the HEAD commit, just like the 'ours' and 'octopus' strategies do. Some testcase fixups were in order: t7611: had many tests designed to show that `git merge --abort` could not always restore the index and working tree to the state they were in before the merge started. The tests that were associated with having changes in the index before the merge started are no longer applicable, so they have been removed. t7504: had a few tests that had stray staged changes that were not actually part of the test under consideration t6044: We no longer expect stray staged changes to sometimes result in the merge continuing. Also, fix a case where a merge didn't abort but should have. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-01 09:25:02 +08:00
git rm -f file &&
builtin/merge: honor commit-msg hook for merges Similar to 65969d43d1 (merge: honor prepare-commit-msg hook, 2011-02-14) merge should also honor the commit-msg hook: When a merge is stopped due to conflicts or --no-commit, the subsequent commit calls the commit-msg hook. However, it is not called after a clean merge. Fix this inconsistency by invoking the hook after clean merges as well. This change is motivated by Gerrit's commit-msg hook to install a ChangeId trailer into the commit message. Without such a ChangeId, Gerrit refuses to accept any commit by default, such that the inconsistency of (not) running the commit-msg hook between commit and merge leads to confusion and might block people from getting their work done. As the githooks man page is very vocal about the possibility of skipping the commit-msg hook via the --no-verify option, implement the option in merge, too. 'git merge --continue' is currently implemented as calling cmd_commit with no further arguments. This works for most other merge related options, such as demonstrated via the --allow-unrelated-histories flag in the test. The --no-verify option however is not remembered across invocations of git-merge. Originally the author assumed an alternative in which the 'git merge --continue' command accepts the --no-verify flag, but that opens up the discussion which flags are allows to the continued merge command and which must be given in the first invocation. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-08 06:04:29 +08:00
: >file2 &&
git add file2 &&
git commit --no-verify file2 -m in-side-branch &&
git merge --no-verify --allow-unrelated-histories main &&
commit_msg_is "Merge branch '\''main'\'' into newbranch"
builtin/merge: honor commit-msg hook for merges Similar to 65969d43d1 (merge: honor prepare-commit-msg hook, 2011-02-14) merge should also honor the commit-msg hook: When a merge is stopped due to conflicts or --no-commit, the subsequent commit calls the commit-msg hook. However, it is not called after a clean merge. Fix this inconsistency by invoking the hook after clean merges as well. This change is motivated by Gerrit's commit-msg hook to install a ChangeId trailer into the commit message. Without such a ChangeId, Gerrit refuses to accept any commit by default, such that the inconsistency of (not) running the commit-msg hook between commit and merge leads to confusion and might block people from getting their work done. As the githooks man page is very vocal about the possibility of skipping the commit-msg hook via the --no-verify option, implement the option in merge, too. 'git merge --continue' is currently implemented as calling cmd_commit with no further arguments. This works for most other merge related options, such as demonstrated via the --allow-unrelated-histories flag in the test. The --no-verify option however is not remembered across invocations of git-merge. Originally the author assumed an alternative in which the 'git merge --continue' command accepts the --no-verify flag, but that opens up the discussion which flags are allows to the continued merge command and which must be given in the first invocation. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-08 06:04:29 +08:00
'
test_expect_success 'setup: commit-msg hook made non-executable' '
git_dir="$(git rev-parse --git-dir)" &&
chmod -x "$git_dir/hooks/commit-msg"
'
builtin/merge: honor commit-msg hook for merges Similar to 65969d43d1 (merge: honor prepare-commit-msg hook, 2011-02-14) merge should also honor the commit-msg hook: When a merge is stopped due to conflicts or --no-commit, the subsequent commit calls the commit-msg hook. However, it is not called after a clean merge. Fix this inconsistency by invoking the hook after clean merges as well. This change is motivated by Gerrit's commit-msg hook to install a ChangeId trailer into the commit message. Without such a ChangeId, Gerrit refuses to accept any commit by default, such that the inconsistency of (not) running the commit-msg hook between commit and merge leads to confusion and might block people from getting their work done. As the githooks man page is very vocal about the possibility of skipping the commit-msg hook via the --no-verify option, implement the option in merge, too. 'git merge --continue' is currently implemented as calling cmd_commit with no further arguments. This works for most other merge related options, such as demonstrated via the --allow-unrelated-histories flag in the test. The --no-verify option however is not remembered across invocations of git-merge. Originally the author assumed an alternative in which the 'git merge --continue' command accepts the --no-verify flag, but that opens up the discussion which flags are allows to the continued merge command and which must be given in the first invocation. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-08 06:04:29 +08:00
test_expect_success POSIXPERM 'with non-executable hook' '
merge-recursive: enforce rule that index matches head before merging builtin/merge.c says that when we are about to perform a merge: ...the index must be in sync with the head commit. The strategies are responsible to ensure this. merge-recursive has always relied on unpack_trees() to enforce this requirement, except in the case of an "Already up to date!" merge. unpack-trees.c does not actually enforce this requirement, though. It allows for a pair of exceptions, in cases which it refers to as #14(ALT) and #2ALT. Documentation/technical/trivial-merge.txt can be consulted for the precise meanings of the various case numbers and their meanings for unpack-trees.c, but we have a high-level description of the intent behind these two exceptions in a combined and summarized form in Documentation/git-merge.txt: ...[merge will] abort if there are any changes registered in the index relative to the `HEAD` commit. (One exception is when the changed index entries are in the state that would result from the merge already.) While this high-level description does describe conditions under which it would be safe to allow the index to diverge from HEAD, it does not match what is actually implemented. In particular, unpack-trees.c has no knowledge of renames, and these two exceptions were written assuming that no renames take place. Once renames get into the mix, it is no longer safe to allow the index to not match for #2ALT. We could modify unpack-trees to only allow #14(ALT) as an exception, but that would be more strict than required for the resolve strategy (since the resolve strategy doesn't handle renames at all). Therefore, unpack_trees.c seems like the wrong place to fix this. Further, if someone fixes the combination of break and rename detection and modifies merge-recursive to take advantage of the combination, then it will also no longer be safe to allow the index to not match for #14(ALT) when the recursive strategy is in use. Therefore, leaving one of the exceptions in place with the recursive merge strategy feels like we are just leaving a latent bug in the code for folks in the future to stumble across. It may be possible to fix both unpack-trees and merge-recursive in a way that implements the exception as stated in Documentation/git-merge.txt, but it would be somewhat complex, possibly also buggy at first, and ultimately, not all that valuable. Instead, just enforce the requirement stated in builtin/merge.c; error out if the index does not match the HEAD commit, just like the 'ours' and 'octopus' strategies do. Some testcase fixups were in order: t7611: had many tests designed to show that `git merge --abort` could not always restore the index and working tree to the state they were in before the merge started. The tests that were associated with having changes in the index before the merge started are no longer applicable, so they have been removed. t7504: had a few tests that had stray staged changes that were not actually part of the test under consideration t6044: We no longer expect stray staged changes to sometimes result in the merge continuing. Also, fix a case where a merge didn't abort but should have. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-01 09:25:02 +08:00
echo "content" >file &&
git add file &&
git commit -m "content"
'
test_expect_success POSIXPERM 'with non-executable hook (editor)' '
echo "content again" >> file &&
git add file &&
echo "content again" > FAKE_MSG &&
GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -m "content again"
'
test_expect_success POSIXPERM '--no-verify with non-executable hook' '
echo "more content" >> file &&
git add file &&
git commit --no-verify -m "more content"
'
test_expect_success POSIXPERM '--no-verify with non-executable hook (editor)' '
echo "even more content" >> file &&
git add file &&
echo "even more content" > FAKE_MSG &&
GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify
'
test_expect_success 'setup: commit-msg hook that edits the commit message' '
test_hook --clobber commit-msg <<-\EOF
echo "new message" >"$1"
exit 0
EOF
'
test_expect_success 'hook edits commit message' '
echo "additional" >> file &&
git add file &&
git commit -m "additional" &&
commit_msg_is "new message"
'
test_expect_success 'hook edits commit message (editor)' '
echo "additional content" >> file &&
git add file &&
echo "additional content" > FAKE_MSG &&
GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit &&
commit_msg_is "new message"
'
test_expect_success "hook doesn't edit commit message" '
echo "plus" >> file &&
git add file &&
git commit --no-verify -m "plus" &&
commit_msg_is "plus"
'
test_expect_success "hook doesn't edit commit message (editor)" '
echo "more plus" >> file &&
git add file &&
echo "more plus" > FAKE_MSG &&
GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify &&
commit_msg_is "more plus"
builtin/merge: honor commit-msg hook for merges Similar to 65969d43d1 (merge: honor prepare-commit-msg hook, 2011-02-14) merge should also honor the commit-msg hook: When a merge is stopped due to conflicts or --no-commit, the subsequent commit calls the commit-msg hook. However, it is not called after a clean merge. Fix this inconsistency by invoking the hook after clean merges as well. This change is motivated by Gerrit's commit-msg hook to install a ChangeId trailer into the commit message. Without such a ChangeId, Gerrit refuses to accept any commit by default, such that the inconsistency of (not) running the commit-msg hook between commit and merge leads to confusion and might block people from getting their work done. As the githooks man page is very vocal about the possibility of skipping the commit-msg hook via the --no-verify option, implement the option in merge, too. 'git merge --continue' is currently implemented as calling cmd_commit with no further arguments. This works for most other merge related options, such as demonstrated via the --allow-unrelated-histories flag in the test. The --no-verify option however is not remembered across invocations of git-merge. Originally the author assumed an alternative in which the 'git merge --continue' command accepts the --no-verify flag, but that opens up the discussion which flags are allows to the continued merge command and which must be given in the first invocation. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-08 06:04:29 +08:00
'
builtin/merge: honor commit-msg hook for merges Similar to 65969d43d1 (merge: honor prepare-commit-msg hook, 2011-02-14) merge should also honor the commit-msg hook: When a merge is stopped due to conflicts or --no-commit, the subsequent commit calls the commit-msg hook. However, it is not called after a clean merge. Fix this inconsistency by invoking the hook after clean merges as well. This change is motivated by Gerrit's commit-msg hook to install a ChangeId trailer into the commit message. Without such a ChangeId, Gerrit refuses to accept any commit by default, such that the inconsistency of (not) running the commit-msg hook between commit and merge leads to confusion and might block people from getting their work done. As the githooks man page is very vocal about the possibility of skipping the commit-msg hook via the --no-verify option, implement the option in merge, too. 'git merge --continue' is currently implemented as calling cmd_commit with no further arguments. This works for most other merge related options, such as demonstrated via the --allow-unrelated-histories flag in the test. The --no-verify option however is not remembered across invocations of git-merge. Originally the author assumed an alternative in which the 'git merge --continue' command accepts the --no-verify flag, but that opens up the discussion which flags are allows to the continued merge command and which must be given in the first invocation. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-08 06:04:29 +08:00
test_expect_success 'hook called in git-merge picks up commit message' '
test_when_finished "git branch -D newbranch" &&
test_when_finished "git checkout -f main" &&
builtin/merge: honor commit-msg hook for merges Similar to 65969d43d1 (merge: honor prepare-commit-msg hook, 2011-02-14) merge should also honor the commit-msg hook: When a merge is stopped due to conflicts or --no-commit, the subsequent commit calls the commit-msg hook. However, it is not called after a clean merge. Fix this inconsistency by invoking the hook after clean merges as well. This change is motivated by Gerrit's commit-msg hook to install a ChangeId trailer into the commit message. Without such a ChangeId, Gerrit refuses to accept any commit by default, such that the inconsistency of (not) running the commit-msg hook between commit and merge leads to confusion and might block people from getting their work done. As the githooks man page is very vocal about the possibility of skipping the commit-msg hook via the --no-verify option, implement the option in merge, too. 'git merge --continue' is currently implemented as calling cmd_commit with no further arguments. This works for most other merge related options, such as demonstrated via the --allow-unrelated-histories flag in the test. The --no-verify option however is not remembered across invocations of git-merge. Originally the author assumed an alternative in which the 'git merge --continue' command accepts the --no-verify flag, but that opens up the discussion which flags are allows to the continued merge command and which must be given in the first invocation. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-08 06:04:29 +08:00
git checkout --orphan newbranch &&
merge-recursive: enforce rule that index matches head before merging builtin/merge.c says that when we are about to perform a merge: ...the index must be in sync with the head commit. The strategies are responsible to ensure this. merge-recursive has always relied on unpack_trees() to enforce this requirement, except in the case of an "Already up to date!" merge. unpack-trees.c does not actually enforce this requirement, though. It allows for a pair of exceptions, in cases which it refers to as #14(ALT) and #2ALT. Documentation/technical/trivial-merge.txt can be consulted for the precise meanings of the various case numbers and their meanings for unpack-trees.c, but we have a high-level description of the intent behind these two exceptions in a combined and summarized form in Documentation/git-merge.txt: ...[merge will] abort if there are any changes registered in the index relative to the `HEAD` commit. (One exception is when the changed index entries are in the state that would result from the merge already.) While this high-level description does describe conditions under which it would be safe to allow the index to diverge from HEAD, it does not match what is actually implemented. In particular, unpack-trees.c has no knowledge of renames, and these two exceptions were written assuming that no renames take place. Once renames get into the mix, it is no longer safe to allow the index to not match for #2ALT. We could modify unpack-trees to only allow #14(ALT) as an exception, but that would be more strict than required for the resolve strategy (since the resolve strategy doesn't handle renames at all). Therefore, unpack_trees.c seems like the wrong place to fix this. Further, if someone fixes the combination of break and rename detection and modifies merge-recursive to take advantage of the combination, then it will also no longer be safe to allow the index to not match for #14(ALT) when the recursive strategy is in use. Therefore, leaving one of the exceptions in place with the recursive merge strategy feels like we are just leaving a latent bug in the code for folks in the future to stumble across. It may be possible to fix both unpack-trees and merge-recursive in a way that implements the exception as stated in Documentation/git-merge.txt, but it would be somewhat complex, possibly also buggy at first, and ultimately, not all that valuable. Instead, just enforce the requirement stated in builtin/merge.c; error out if the index does not match the HEAD commit, just like the 'ours' and 'octopus' strategies do. Some testcase fixups were in order: t7611: had many tests designed to show that `git merge --abort` could not always restore the index and working tree to the state they were in before the merge started. The tests that were associated with having changes in the index before the merge started are no longer applicable, so they have been removed. t7504: had a few tests that had stray staged changes that were not actually part of the test under consideration t6044: We no longer expect stray staged changes to sometimes result in the merge continuing. Also, fix a case where a merge didn't abort but should have. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-01 09:25:02 +08:00
git rm -f file &&
builtin/merge: honor commit-msg hook for merges Similar to 65969d43d1 (merge: honor prepare-commit-msg hook, 2011-02-14) merge should also honor the commit-msg hook: When a merge is stopped due to conflicts or --no-commit, the subsequent commit calls the commit-msg hook. However, it is not called after a clean merge. Fix this inconsistency by invoking the hook after clean merges as well. This change is motivated by Gerrit's commit-msg hook to install a ChangeId trailer into the commit message. Without such a ChangeId, Gerrit refuses to accept any commit by default, such that the inconsistency of (not) running the commit-msg hook between commit and merge leads to confusion and might block people from getting their work done. As the githooks man page is very vocal about the possibility of skipping the commit-msg hook via the --no-verify option, implement the option in merge, too. 'git merge --continue' is currently implemented as calling cmd_commit with no further arguments. This works for most other merge related options, such as demonstrated via the --allow-unrelated-histories flag in the test. The --no-verify option however is not remembered across invocations of git-merge. Originally the author assumed an alternative in which the 'git merge --continue' command accepts the --no-verify flag, but that opens up the discussion which flags are allows to the continued merge command and which must be given in the first invocation. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-08 06:04:29 +08:00
: >file2 &&
git add file2 &&
git commit --no-verify file2 -m in-side-branch &&
git merge --allow-unrelated-histories main &&
builtin/merge: honor commit-msg hook for merges Similar to 65969d43d1 (merge: honor prepare-commit-msg hook, 2011-02-14) merge should also honor the commit-msg hook: When a merge is stopped due to conflicts or --no-commit, the subsequent commit calls the commit-msg hook. However, it is not called after a clean merge. Fix this inconsistency by invoking the hook after clean merges as well. This change is motivated by Gerrit's commit-msg hook to install a ChangeId trailer into the commit message. Without such a ChangeId, Gerrit refuses to accept any commit by default, such that the inconsistency of (not) running the commit-msg hook between commit and merge leads to confusion and might block people from getting their work done. As the githooks man page is very vocal about the possibility of skipping the commit-msg hook via the --no-verify option, implement the option in merge, too. 'git merge --continue' is currently implemented as calling cmd_commit with no further arguments. This works for most other merge related options, such as demonstrated via the --allow-unrelated-histories flag in the test. The --no-verify option however is not remembered across invocations of git-merge. Originally the author assumed an alternative in which the 'git merge --continue' command accepts the --no-verify flag, but that opens up the discussion which flags are allows to the continued merge command and which must be given in the first invocation. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-08 06:04:29 +08:00
commit_msg_is "new message"
'
test_expect_failure 'merge --continue remembers --no-verify' '
test_when_finished "git branch -D newbranch" &&
test_when_finished "git checkout -f main" &&
git checkout main &&
builtin/merge: honor commit-msg hook for merges Similar to 65969d43d1 (merge: honor prepare-commit-msg hook, 2011-02-14) merge should also honor the commit-msg hook: When a merge is stopped due to conflicts or --no-commit, the subsequent commit calls the commit-msg hook. However, it is not called after a clean merge. Fix this inconsistency by invoking the hook after clean merges as well. This change is motivated by Gerrit's commit-msg hook to install a ChangeId trailer into the commit message. Without such a ChangeId, Gerrit refuses to accept any commit by default, such that the inconsistency of (not) running the commit-msg hook between commit and merge leads to confusion and might block people from getting their work done. As the githooks man page is very vocal about the possibility of skipping the commit-msg hook via the --no-verify option, implement the option in merge, too. 'git merge --continue' is currently implemented as calling cmd_commit with no further arguments. This works for most other merge related options, such as demonstrated via the --allow-unrelated-histories flag in the test. The --no-verify option however is not remembered across invocations of git-merge. Originally the author assumed an alternative in which the 'git merge --continue' command accepts the --no-verify flag, but that opens up the discussion which flags are allows to the continued merge command and which must be given in the first invocation. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-08 06:04:29 +08:00
echo a >file2 &&
git add file2 &&
git commit --no-verify -m "add file2 to main" &&
git checkout -b newbranch main^ &&
builtin/merge: honor commit-msg hook for merges Similar to 65969d43d1 (merge: honor prepare-commit-msg hook, 2011-02-14) merge should also honor the commit-msg hook: When a merge is stopped due to conflicts or --no-commit, the subsequent commit calls the commit-msg hook. However, it is not called after a clean merge. Fix this inconsistency by invoking the hook after clean merges as well. This change is motivated by Gerrit's commit-msg hook to install a ChangeId trailer into the commit message. Without such a ChangeId, Gerrit refuses to accept any commit by default, such that the inconsistency of (not) running the commit-msg hook between commit and merge leads to confusion and might block people from getting their work done. As the githooks man page is very vocal about the possibility of skipping the commit-msg hook via the --no-verify option, implement the option in merge, too. 'git merge --continue' is currently implemented as calling cmd_commit with no further arguments. This works for most other merge related options, such as demonstrated via the --allow-unrelated-histories flag in the test. The --no-verify option however is not remembered across invocations of git-merge. Originally the author assumed an alternative in which the 'git merge --continue' command accepts the --no-verify flag, but that opens up the discussion which flags are allows to the continued merge command and which must be given in the first invocation. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-08 06:04:29 +08:00
echo b >file2 &&
git add file2 &&
git commit --no-verify file2 -m in-side-branch &&
git merge --no-verify -m not-rewritten-by-hook main &&
builtin/merge: honor commit-msg hook for merges Similar to 65969d43d1 (merge: honor prepare-commit-msg hook, 2011-02-14) merge should also honor the commit-msg hook: When a merge is stopped due to conflicts or --no-commit, the subsequent commit calls the commit-msg hook. However, it is not called after a clean merge. Fix this inconsistency by invoking the hook after clean merges as well. This change is motivated by Gerrit's commit-msg hook to install a ChangeId trailer into the commit message. Without such a ChangeId, Gerrit refuses to accept any commit by default, such that the inconsistency of (not) running the commit-msg hook between commit and merge leads to confusion and might block people from getting their work done. As the githooks man page is very vocal about the possibility of skipping the commit-msg hook via the --no-verify option, implement the option in merge, too. 'git merge --continue' is currently implemented as calling cmd_commit with no further arguments. This works for most other merge related options, such as demonstrated via the --allow-unrelated-histories flag in the test. The --no-verify option however is not remembered across invocations of git-merge. Originally the author assumed an alternative in which the 'git merge --continue' command accepts the --no-verify flag, but that opens up the discussion which flags are allows to the continued merge command and which must be given in the first invocation. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-08 06:04:29 +08:00
# resolve conflict:
echo c >file2 &&
git add file2 &&
git merge --continue &&
commit_msg_is not-rewritten-by-hook
'
# set up fake editor to replace `pick` by `reword`
cat > reword-editor <<'EOF'
#!/bin/sh
mv "$1" "$1".bup &&
sed 's/^pick/reword/' <"$1".bup >"$1"
EOF
chmod +x reword-editor
REWORD_EDITOR="$(pwd)/reword-editor"
export REWORD_EDITOR
test_expect_success 'hook is called for reword during `rebase -i`' '
GIT_SEQUENCE_EDITOR="\"$REWORD_EDITOR\"" git rebase -i HEAD^ &&
commit_msg_is "new message"
'
builtin/merge: honor commit-msg hook for merges Similar to 65969d43d1 (merge: honor prepare-commit-msg hook, 2011-02-14) merge should also honor the commit-msg hook: When a merge is stopped due to conflicts or --no-commit, the subsequent commit calls the commit-msg hook. However, it is not called after a clean merge. Fix this inconsistency by invoking the hook after clean merges as well. This change is motivated by Gerrit's commit-msg hook to install a ChangeId trailer into the commit message. Without such a ChangeId, Gerrit refuses to accept any commit by default, such that the inconsistency of (not) running the commit-msg hook between commit and merge leads to confusion and might block people from getting their work done. As the githooks man page is very vocal about the possibility of skipping the commit-msg hook via the --no-verify option, implement the option in merge, too. 'git merge --continue' is currently implemented as calling cmd_commit with no further arguments. This works for most other merge related options, such as demonstrated via the --allow-unrelated-histories flag in the test. The --no-verify option however is not remembered across invocations of git-merge. Originally the author assumed an alternative in which the 'git merge --continue' command accepts the --no-verify flag, but that opens up the discussion which flags are allows to the continued merge command and which must be given in the first invocation. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-09-08 06:04:29 +08:00
test_done