Using the to-do list command `squash` the user can specify two or
more commits and git-rebase creates one commit that introduces all
their changes combined. The authorship for the created commit is
taken from the first commit specified and the user can edit the log
message. There is a variant of `squash` available named `fixup` which
also takes the first log message without asking for user input.

While it is reasonable to not verify replayed changes twice or
rejecting some other author's changes in her name, it is insufficient
to not verify the user input used as log message in the case of
`squash`. Specify the git-commit option `--no-pre-commit` instead of
`--no-verify` when committing the squash result, but not before, to
let the commit-msg hook verify the final squash message. For the same
reasons the pre-commit hook is disabled in all replay modes, the
commit-msg hook is disabled in `fixup` mode.

Add tests. In addition to the existing test checking that the
pre-commit hook is disabled when simply picking a commit, provide a
test checking that the commit-msg hook is disabled as well.

Signed-off-by: Fabian Ruch <baf...@gmail.com>
---
 git-rebase--interactive.sh    |  2 +-
 t/t3404-rebase-interactive.sh | 80 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index cf62daa..54c4614 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -562,7 +562,7 @@ do_next () {
                        else
                                cp "$squash_msg" "$GIT_DIR"/SQUASH_MSG || exit
                                rm -f "$GIT_DIR"/MERGE_MSG
-                               do_with_author output git commit --allow-empty 
--amend --no-verify -F "$GIT_DIR"/SQUASH_MSG -e \
+                               do_with_author output git commit --allow-empty 
--amend --no-pre-commit -F "$GIT_DIR"/SQUASH_MSG -e \
                                        ${gpg_sign_opt:+"$gpg_sign_opt"} ||
                                        die_failed_squash $sha1 "$rest"
                        fi
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 7cc6ebf..abb829e 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -664,6 +664,86 @@ test_expect_success 'rebase a commit violating pre-commit' 
'
 
 '
 
+test_expect_success 'setup failing pre-commit' '
+       HOOKDIR="$(git rev-parse --git-dir)"/hooks &&
+       mkdir -p "$HOOKDIR" &&
+       PRE_COMMIT="$HOOKDIR"/pre-commit &&
+       cat >"$PRE_COMMIT" <<-EOF &&
+       #!/bin/sh
+       echo running failing pre-commit...
+       exit 1
+       EOF
+       chmod +x "$PRE_COMMIT" &&
+       git checkout -b violating-pre-commit master &&
+       test_must_fail test_commit pre-commit-violated-1 &&
+       test_commit --no-verify pre-commit-violated-1 &&
+       test_must_fail test_commit pre-commit-violated-2 &&
+       test_commit --no-verify pre-commit-violated-2 &&
+       test_must_fail test_commit pre-commit-violated-3 &&
+       test_commit --no-verify pre-commit-violated-3
+'
+
+test_expect_success 'squash commits violating pre-commit' '
+       git checkout -b squash-violating-pre-commit violating-pre-commit &&
+       test_when_finished reset_rebase &&
+       set_fake_editor &&
+       env FAKE_LINES="1 squash 2 squash 3" git rebase -i master
+'
+
+test_expect_success 'fixup commits violating pre-commit' '
+       git checkout -b fixup-violating-pre-commit violating-pre-commit &&
+       test_when_finished reset_rebase &&
+       set_fake_editor &&
+       env FAKE_LINES="1 fixup 2 fixup 3" git rebase -i master
+'
+
+test_expect_success 'clean up failing pre-commit' '
+       rm "$PRE_COMMIT"
+'
+
+test_expect_success 'setup failing commit-msg' '
+       HOOKDIR="$(git rev-parse --git-dir)"/hooks &&
+       mkdir -p "$HOOKDIR" &&
+       COMMIT_MSG="$HOOKDIR"/commit-msg &&
+       cat >"$COMMIT_MSG" <<-EOF &&
+       #!/bin/sh
+       echo running failing commit-msg...
+       exit 1
+       EOF
+       chmod +x "$COMMIT_MSG" &&
+       git checkout -b violating-commit-msg master &&
+       test_must_fail test_commit commit-msg-violated-1 &&
+       test_commit --no-verify commit-msg-violated-1 &&
+       test_must_fail test_commit commit-msg-violated-2 &&
+       test_commit --no-verify commit-msg-violated-2 &&
+       test_must_fail test_commit commit-msg-violated-3 &&
+       test_commit --no-verify commit-msg-violated-3
+'
+
+test_expect_success 'rebase a commit violating commit-msg' '
+       git checkout -b rebase-violating-commit-msg violating-commit-msg &&
+       set_fake_editor &&
+       FAKE_LINES="1" git rebase -i master
+'
+
+test_expect_success 'squash commits violating commit-msg' '
+       git checkout -b squash-violating-commit-msg violating-commit-msg &&
+       set_fake_editor &&
+       test_must_fail env FAKE_LINES="1 squash 2 squash 3" git rebase -i 
master &&
+       git commit --no-verify --amend &&
+       git rebase --continue
+'
+
+test_expect_success 'fixup commits violating commit-msg' '
+       git checkout -b fixup-violating-commit-msg violating-commit-msg &&
+       set_fake_editor &&
+       env FAKE_LINES="1 fixup 2 fixup 3" git rebase -i master
+'
+
+test_expect_success 'clean up failing commit-msg' '
+       rm "$COMMIT_MSG"
+'
+
 test_expect_success 'rebase with a file named HEAD in worktree' '
 
        rm -fr .git/hooks &&
-- 
2.0.1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to