Add commit hook and make the verification customizable.
There are three hooks: - 'pre-commit' is given an opportunity to inspect what is being committed, before we invoke the EDITOR for the commit message; - 'commit-msg' is invoked on the commit log message after the user prepares it; - 'post-commit' is run after a successful commit is made. The first two can interfere to stop the commit. The last one is for after-the-fact notification. The earlier built-in commit checker is now moved to pre-commit. Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
e20ce6ac76
commit
89e2c5f17b
@ -6,10 +6,10 @@
|
|||||||
. git-sh-setup-script || die "Not a git archive"
|
. git-sh-setup-script || die "Not a git archive"
|
||||||
|
|
||||||
usage () {
|
usage () {
|
||||||
die 'git commit [-a] [-m <message>] [-F <logfile>] [(-C|-c) <commit>] [<path>...]'
|
die 'git commit [-a] [-v | --no-verify] [-m <message>] [-F <logfile>] [(-C|-c) <commit>] [<path>...]'
|
||||||
}
|
}
|
||||||
|
|
||||||
all= logfile= use_commit= no_edit= log_given= log_message= verify= signoff=
|
all= logfile= use_commit= no_edit= log_given= log_message= verify=t signoff=
|
||||||
while case "$#" in 0) break;; esac
|
while case "$#" in 0) break;; esac
|
||||||
do
|
do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
@ -67,6 +67,9 @@ do
|
|||||||
-s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
|
-s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
|
||||||
signoff=t
|
signoff=t
|
||||||
shift ;;
|
shift ;;
|
||||||
|
-n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|--no-verify)
|
||||||
|
verify=
|
||||||
|
shift ;;
|
||||||
-v|--v|--ve|--ver|--veri|--verif|--verify)
|
-v|--v|--ve|--ver|--veri|--verif|--verify)
|
||||||
verify=t
|
verify=t
|
||||||
shift ;;
|
shift ;;
|
||||||
@ -101,56 +104,10 @@ git-update-cache -q --refresh || exit 1
|
|||||||
|
|
||||||
case "$verify" in
|
case "$verify" in
|
||||||
t)
|
t)
|
||||||
# This is slightly modified from Andrew Morton's Perfect Patch.
|
if test -x "$GIT_DIR"/hooks/pre-commit
|
||||||
# Lines you introduce should not have trailing whitespace.
|
then
|
||||||
# Also check for an indentation that has SP before a TAB.
|
"$GIT_DIR"/hooks/pre-commit || exit
|
||||||
perl -e '
|
fi
|
||||||
my $fh;
|
|
||||||
my $found_bad = 0;
|
|
||||||
my $filename;
|
|
||||||
my $reported_filename = "";
|
|
||||||
my $lineno;
|
|
||||||
sub bad_line {
|
|
||||||
my ($why, $line) = @_;
|
|
||||||
if (!$found_bad) {
|
|
||||||
print "*\n";
|
|
||||||
print "* You have some suspicious patch lines:\n";
|
|
||||||
print "*\n";
|
|
||||||
$found_bad = 1;
|
|
||||||
}
|
|
||||||
if ($reported_filename ne $filename) {
|
|
||||||
print "* In $filename\n";
|
|
||||||
$reported_filename = $filename;
|
|
||||||
}
|
|
||||||
print "* $why (line $lineno)\n$line\n";
|
|
||||||
}
|
|
||||||
open $fh, "-|", qw(git-diff-cache -p -M --cached HEAD);
|
|
||||||
while (<$fh>) {
|
|
||||||
if (m|^diff --git a/(.*) b/\1$|) {
|
|
||||||
$filename = $1;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
if (/^@@ -\S+ \+(\d+)/) {
|
|
||||||
$lineno = $1 - 1;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
if (/^ /) {
|
|
||||||
$lineno++;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
if (s/^\+//) {
|
|
||||||
$lineno++;
|
|
||||||
chomp;
|
|
||||||
if (/\s$/) {
|
|
||||||
bad_line("trailing whitespace", $_);
|
|
||||||
}
|
|
||||||
if (/^\s* /) {
|
|
||||||
bad_line("indent SP followed by a TAB", $_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exit($found_bad);
|
|
||||||
' || exit ;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
PARENTS="-p HEAD"
|
PARENTS="-p HEAD"
|
||||||
@ -255,6 +212,15 @@ case "$no_edit" in
|
|||||||
${VISUAL:-${EDITOR:-vi}} .editmsg
|
${VISUAL:-${EDITOR:-vi}} .editmsg
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
case "$verify" in
|
||||||
|
t)
|
||||||
|
if test -x "$GIT_DIR"/hooks/commit-msg
|
||||||
|
then
|
||||||
|
"$GIT_DIR"/hooks/commit-msg .editmsg || exit
|
||||||
|
fi
|
||||||
|
esac
|
||||||
|
|
||||||
grep -v '^#' < .editmsg | git-stripspace > .cmitmsg
|
grep -v '^#' < .editmsg | git-stripspace > .cmitmsg
|
||||||
grep -v -i '^Signed-off-by' .cmitmsg >.cmitchk
|
grep -v -i '^Signed-off-by' .cmitmsg >.cmitchk
|
||||||
if test -s .cmitchk
|
if test -s .cmitchk
|
||||||
@ -269,4 +235,9 @@ else
|
|||||||
fi
|
fi
|
||||||
ret="$?"
|
ret="$?"
|
||||||
rm -f .cmitmsg .editmsg .cmitchk
|
rm -f .cmitmsg .editmsg .cmitchk
|
||||||
|
|
||||||
|
if test -x "$GIT_DIR"/hooks/post-commit && test "$ret" = 0
|
||||||
|
then
|
||||||
|
"$GIT_DIR"/hooks/post-commit
|
||||||
|
fi
|
||||||
exit "$ret"
|
exit "$ret"
|
||||||
|
14
templates/hooks--commit-msg
Normal file
14
templates/hooks--commit-msg
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# An example hook script to check the commit log message.
|
||||||
|
# Called by git-commit-script with one argument, the name of the file
|
||||||
|
# that has the commit message. The hook should exit with non-zero
|
||||||
|
# status after issuing an appropriate message if it wants to stop the
|
||||||
|
# commit. The hook is allowed to edit the commit message file.
|
||||||
|
#
|
||||||
|
# To enable this hook, make this file executable.
|
||||||
|
|
||||||
|
# This example catches duplicate Signed-off-by lines.
|
||||||
|
|
||||||
|
test "" = "$(grep '^Signed-off-by: ' "$1" |
|
||||||
|
sort | uniq -c | sed -e '/^[ ]*1 /d')"
|
8
templates/hooks--post-commit
Normal file
8
templates/hooks--post-commit
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# An example hook script that is called after a successful
|
||||||
|
# commit is made.
|
||||||
|
#
|
||||||
|
# To enable this hook, make this file executable.
|
||||||
|
|
||||||
|
: Nothing
|
60
templates/hooks--pre-commit
Normal file
60
templates/hooks--pre-commit
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# An example hook script to verify what is about to be committed.
|
||||||
|
# Called by git-commit-script with no arguments. The hook should
|
||||||
|
# exit with non-zero status after issuing an appropriate message if
|
||||||
|
# it wants to stop the commit.
|
||||||
|
#
|
||||||
|
# To enable this hook, make this file executable.
|
||||||
|
|
||||||
|
# This is slightly modified from Andrew Morton's Perfect Patch.
|
||||||
|
# Lines you introduce should not have trailing whitespace.
|
||||||
|
# Also check for an indentation that has SP before a TAB.
|
||||||
|
perl -e '
|
||||||
|
my $fh;
|
||||||
|
my $found_bad = 0;
|
||||||
|
my $filename;
|
||||||
|
my $reported_filename = "";
|
||||||
|
my $lineno;
|
||||||
|
sub bad_line {
|
||||||
|
my ($why, $line) = @_;
|
||||||
|
if (!$found_bad) {
|
||||||
|
print "*\n";
|
||||||
|
print "* You have some suspicious patch lines:\n";
|
||||||
|
print "*\n";
|
||||||
|
$found_bad = 1;
|
||||||
|
}
|
||||||
|
if ($reported_filename ne $filename) {
|
||||||
|
print "* In $filename\n";
|
||||||
|
$reported_filename = $filename;
|
||||||
|
}
|
||||||
|
print "* $why (line $lineno)\n$line\n";
|
||||||
|
}
|
||||||
|
open $fh, "-|", qw(git-diff-cache -p -M --cached HEAD);
|
||||||
|
while (<$fh>) {
|
||||||
|
if (m|^diff --git a/(.*) b/\1$|) {
|
||||||
|
$filename = $1;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
if (/^@@ -\S+ \+(\d+)/) {
|
||||||
|
$lineno = $1 - 1;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
if (/^ /) {
|
||||||
|
$lineno++;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
if (s/^\+//) {
|
||||||
|
$lineno++;
|
||||||
|
chomp;
|
||||||
|
if (/\s$/) {
|
||||||
|
bad_line("trailing whitespace", $_);
|
||||||
|
}
|
||||||
|
if (/^\s* /) {
|
||||||
|
bad_line("indent SP followed by a TAB", $_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exit($found_bad);
|
||||||
|
'
|
||||||
|
|
Loading…
Reference in New Issue
Block a user