Browse Source
The prepare-commit-msg hook is run whenever a "fresh" commit message is prepared, just before it is shown in the editor (if it is). Its purpose is to modify the commit message in-place. It takes one to three parameters. The first is the name of the file that the commit log message. The second is the source of the commit message, and can be: "message" (if a -m or -F option was given); "template" (if a -t option was given or the configuration option commit.template is set); "merge" (if the commit is a merge or a .git/MERGE_MSG file exists); "squash" (if a .git/SQUASH_MSG file exists); or "commit", followed by a commit SHA1 as the third parameter (if a -c, -C or --amend option was given). If its exit status is non-zero, git-commit will abort. The hook is not suppressed by the --no-verify option, so it should not be used as a replacement for the pre-commit hook. The sample prepare-commit-msg comments out the `Conflicts:` part of a merge's commit message; other examples are commented out, including adding a Signed-off-by line at the bottom of the commit messsage, that the user can then edit or discard altogether. Signed-off-by: Paolo Bonzini <bonzini@gnu.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
Paolo Bonzini
17 years ago
committed by
Junio C Hamano
6 changed files with 242 additions and 2 deletions
@ -0,0 +1,155 @@
@@ -0,0 +1,155 @@
|
||||
#!/bin/sh |
||||
|
||||
test_description='prepare-commit-msg hook' |
||||
|
||||
. ./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 |
||||
exit 0 |
||||
EOF |
||||
chmod +x fake-editor |
||||
FAKE_EDITOR="$(pwd)/fake-editor" |
||||
export FAKE_EDITOR |
||||
|
||||
# now install hook that always succeeds and adds a message |
||||
HOOKDIR="$(git rev-parse --git-dir)/hooks" |
||||
HOOK="$HOOKDIR/prepare-commit-msg" |
||||
mkdir -p "$HOOKDIR" |
||||
cat > "$HOOK" <<'EOF' |
||||
#!/bin/sh |
||||
if test "$2" = commit; then |
||||
source=$(git-rev-parse "$3") |
||||
else |
||||
source=${2-default} |
||||
fi |
||||
if test "$GIT_EDITOR" = :; then |
||||
sed -e "1s/.*/$source (no editor)/" "$1" > msg.tmp |
||||
else |
||||
sed -e "1s/.*/$source/" "$1" > msg.tmp |
||||
fi |
||||
mv msg.tmp "$1" |
||||
exit 0 |
||||
EOF |
||||
chmod +x "$HOOK" |
||||
|
||||
echo dummy template > "$(git rev-parse --git-dir)/template" |
||||
|
||||
test_expect_success 'with hook (-m)' ' |
||||
|
||||
echo "more" >> file && |
||||
git add file && |
||||
git commit -m "more" && |
||||
test "`git log -1 --pretty=format:%s`" = "message (no editor)" |
||||
|
||||
' |
||||
|
||||
test_expect_success 'with hook (-m editor)' ' |
||||
|
||||
echo "more" >> file && |
||||
git add file && |
||||
GIT_EDITOR="$FAKE_EDITOR" git commit -e -m "more more" && |
||||
test "`git log -1 --pretty=format:%s`" = message |
||||
|
||||
' |
||||
|
||||
test_expect_success 'with hook (-t)' ' |
||||
|
||||
echo "more" >> file && |
||||
git add file && |
||||
git commit -t "$(git rev-parse --git-dir)/template" && |
||||
test "`git log -1 --pretty=format:%s`" = template |
||||
|
||||
' |
||||
|
||||
test_expect_success 'with hook (-F)' ' |
||||
|
||||
echo "more" >> file && |
||||
git add file && |
||||
(echo more | git commit -F -) && |
||||
test "`git log -1 --pretty=format:%s`" = "message (no editor)" |
||||
|
||||
' |
||||
|
||||
test_expect_success 'with hook (-F editor)' ' |
||||
|
||||
echo "more" >> file && |
||||
git add file && |
||||
(echo more more | GIT_EDITOR="$FAKE_EDITOR" git commit -e -F -) && |
||||
test "`git log -1 --pretty=format:%s`" = message |
||||
|
||||
' |
||||
|
||||
test_expect_success 'with hook (-C)' ' |
||||
|
||||
head=`git rev-parse HEAD` && |
||||
echo "more" >> file && |
||||
git add file && |
||||
git commit -C $head && |
||||
test "`git log -1 --pretty=format:%s`" = "$head (no editor)" |
||||
|
||||
' |
||||
|
||||
test_expect_success 'with hook (editor)' ' |
||||
|
||||
echo "more more" >> file && |
||||
git add file && |
||||
GIT_EDITOR="$FAKE_EDITOR" git commit && |
||||
test "`git log -1 --pretty=format:%s`" = default |
||||
|
||||
' |
||||
|
||||
test_expect_success 'with hook (--amend)' ' |
||||
|
||||
head=`git rev-parse HEAD` && |
||||
echo "more" >> file && |
||||
git add file && |
||||
GIT_EDITOR="$FAKE_EDITOR" git commit --amend && |
||||
test "`git log -1 --pretty=format:%s`" = "$head" |
||||
|
||||
' |
||||
|
||||
test_expect_success 'with hook (-c)' ' |
||||
|
||||
head=`git rev-parse HEAD` && |
||||
echo "more" >> file && |
||||
git add file && |
||||
GIT_EDITOR="$FAKE_EDITOR" git commit -c $head && |
||||
test "`git log -1 --pretty=format:%s`" = "$head" |
||||
|
||||
' |
||||
|
||||
cat > "$HOOK" <<'EOF' |
||||
#!/bin/sh |
||||
exit 1 |
||||
EOF |
||||
|
||||
test_expect_success 'with failing hook' ' |
||||
|
||||
head=`git rev-parse HEAD` && |
||||
echo "more" >> file && |
||||
git add file && |
||||
! GIT_EDITOR="$FAKE_EDITOR" git commit -c $head |
||||
|
||||
' |
||||
|
||||
test_expect_success 'with failing hook (--no-verify)' ' |
||||
|
||||
head=`git rev-parse HEAD` && |
||||
echo "more" >> file && |
||||
git add file && |
||||
! GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify -c $head |
||||
|
||||
' |
||||
|
||||
|
||||
test_done |
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
#!/bin/sh |
||||
# |
||||
# An example hook script to prepare the commit log message. |
||||
# Called by git-commit with the name of the file that has the |
||||
# commit message, followed by the description of the commit |
||||
# message's source. The hook's purpose is to edit the commit |
||||
# message file. If the hook fails with a non-zero status, |
||||
# the commit is aborted. |
||||
# |
||||
# To enable this hook, make this file executable. |
||||
|
||||
# This hook includes three examples. The first comments out the |
||||
# "Conflicts:" part of a merge commit. |
||||
# |
||||
# The second includes the output of "git diff --name-status -r" |
||||
# into the message, just before the "git status" output. It is |
||||
# commented because it doesn't cope with --amend or with squashed |
||||
# commits. |
||||
# |
||||
# The third example adds a Signed-off-by line to the message, that can |
||||
# still be edited. This is rarely a good idea. |
||||
|
||||
case "$2 $3" in |
||||
merge) |
||||
sed -i '/^Conflicts:/,/#/!b;s/^/# &/;s/^# #/#/' "$1" ;; |
||||
|
||||
# ""|template) |
||||
# perl -i -pe ' |
||||
# print "\n" . `git diff --cached --name-status -r` |
||||
# if /^#/ && $first++ == 0' "$1" ;; |
||||
|
||||
*) ;; |
||||
esac |
||||
|
||||
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') |
||||
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" |
Loading…
Reference in new issue