{"thread":{"id":"1581","subject":"[PATCH] Add commit hook and make the verification customizable.","startedAt":"2005-08-19T01:05:09Z","lastAt":"2005-08-19T01:05:09Z","messageCount":1,"participants":["Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"7537","messageId":"7vslx6d9dm.fsf@assigned-by-dhcp.cox.net","threadId":"1581","inReplyTo":null,"subject":"[PATCH] Add commit hook and make the verification customizable.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-08-19T01:05:09Z","receivedAt":"2005-08-19T01:05:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"There are three hooks:\n\n    - 'pre-commit' is given an opportunity to inspect what is\n      being committed, before we invoke the EDITOR for the\n      commit message;\n\n    - 'commit-msg' is invoked on the commit log message after\n      the user prepares it;\n\n    - 'post-commit' is run after a successful commit is made.\n\nThe first two can interfere to stop the commit.  The last one is\nfor after-the-fact notification.\n\nThe earlier built-in commit checker is now moved to pre-commit.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n\n git-commit-script            |   75 +++++++++++++-----------------------------\n templates/hooks--commit-msg  |   14 ++++++++\n templates/hooks--post-commit |    8 ++++\n templates/hooks--pre-commit  |   60 ++++++++++++++++++++++++++++++++++\n 4 files changed, 105 insertions(+), 52 deletions(-)\n create mode 100644 templates/hooks--commit-msg\n create mode 100644 templates/hooks--post-commit\n create mode 100644 templates/hooks--pre-commit\n\n971fd26a05c6a5f71c727b7350c091d5bdb4ebb7\ndiff --git a/git-commit-script b/git-commit-script\n--- a/git-commit-script\n+++ b/git-commit-script\n@@ -6,10 +6,10 @@\n . git-sh-setup-script || die \"Not a git archive\"\n \n usage () {\n-\tdie 'git commit [-a]  [-m <message>] [-F <logfile>] [(-C|-c) <commit>] [<path>...]'\n+\tdie 'git commit [-a] [-v | --no-verify]  [-m <message>] [-F <logfile>] [(-C|-c) <commit>] [<path>...]'\n }\n \n-all= logfile= use_commit= no_edit= log_given= log_message= verify= signoff=\n+all= logfile= use_commit= no_edit= log_given= log_message= verify=t signoff=\n while case \"$#\" in 0) break;; esac\n do\n   case \"$1\" in\n@@ -67,6 +67,9 @@ do\n   -s|--s|--si|--sig|--sign|--signo|--signof|--signoff)\n     signoff=t\n     shift ;;\n+  -n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|--no-verify)\n+    verify=\n+    shift ;;\n   -v|--v|--ve|--ver|--veri|--verif|--verify)\n     verify=t\n     shift ;;\n@@ -101,56 +104,10 @@ git-update-cache -q --refresh || exit 1\n \n case \"$verify\" in\n t)\n-\t# This is slightly modified from Andrew Morton's Perfect Patch.\n-\t# Lines you introduce should not have trailing whitespace.\n-\t# Also check for an indentation that has SP before a TAB.\n-\tperl -e '\n-\t    my $fh;\n-\t    my $found_bad = 0;\n-\t    my $filename;\n-\t    my $reported_filename = \"\";\n-\t    my $lineno;\n-\t    sub bad_line {\n-\t\tmy ($why, $line) = @_;\n-\t\tif (!$found_bad) {\n-\t\t    print \"*\\n\";\n-\t\t    print \"* You have some suspicious patch lines:\\n\";\n-\t\t    print \"*\\n\";\n-\t\t    $found_bad = 1;\n-\t\t}\n-\t\tif ($reported_filename ne $filename) {\n-\t\t    print \"* In $filename\\n\";\n-\t\t    $reported_filename = $filename;\n-\t\t}\n-\t\tprint \"* $why (line $lineno)\\n$line\\n\";\n-\t    }\n-\t    open $fh, \"-|\", qw(git-diff-cache -p -M --cached HEAD);\n-\t    while (<$fh>) {\n-\t\tif (m|^diff --git a/(.*) b/\\1$|) {\n-\t\t    $filename = $1;\n-\t\t    next;\n-\t\t}\n-\t\tif (/^@@ -\\S+ \\+(\\d+)/) {\n-\t\t    $lineno = $1 - 1;\n-\t\t    next;\n-\t\t}\n-\t\tif (/^ /) {\n-\t\t    $lineno++;\n-\t\t    next;\n-\t\t}\n-\t\tif (s/^\\+//) {\n-\t\t    $lineno++;\n-\t\t    chomp;\n-\t\t    if (/\\s$/) {\n-\t\t\tbad_line(\"trailing whitespace\", $_);\n-\t\t    }\n-\t\t    if (/^\\s* \t/) {\n-\t\t\tbad_line(\"indent SP followed by a TAB\", $_);\n-\t\t    }\n-\t\t}\n-\t    }\n-\t    exit($found_bad);\n-\t' || exit ;;\n+\tif test -x \"$GIT_DIR\"/hooks/pre-commit\n+\tthen\n+\t\t\"$GIT_DIR\"/hooks/pre-commit || exit\n+\tfi\n esac\n \n PARENTS=\"-p HEAD\"\n@@ -255,6 +212,15 @@ case \"$no_edit\" in\n \t${VISUAL:-${EDITOR:-vi}} .editmsg\n \t;;\n esac\n+\n+case \"$verify\" in\n+t)\n+\tif test -x \"$GIT_DIR\"/hooks/commit-msg\n+\tthen\n+\t\t\"$GIT_DIR\"/hooks/commit-msg .editmsg || exit\n+\tfi\n+esac\n+\n grep -v '^#' < .editmsg | git-stripspace > .cmitmsg\n grep -v -i '^Signed-off-by' .cmitmsg >.cmitchk\n if test -s .cmitchk\n@@ -269,4 +235,9 @@ else\n fi\n ret=\"$?\"\n rm -f .cmitmsg .editmsg .cmitchk\n+\n+if test -x \"$GIT_DIR\"/hooks/post-commit && test \"$ret\" = 0\n+then\n+\t\"$GIT_DIR\"/hooks/post-commit\n+fi\n exit \"$ret\"\ndiff --git a/templates/hooks--commit-msg b/templates/hooks--commit-msg\nnew file mode 100644\n--- /dev/null\n+++ b/templates/hooks--commit-msg\n@@ -0,0 +1,14 @@\n+#!/bin/sh\n+#\n+# An example hook script to check the commit log message.\n+# Called by git-commit-script with one argument, the name of the file\n+# that has the commit message.  The hook should exit with non-zero\n+# status after issuing an appropriate message if it wants to stop the\n+# commit.  The hook is allowed to edit the commit message file.\n+#\n+# To enable this hook, make this file executable.\n+\n+# This example catches duplicate Signed-off-by lines.\n+\n+test \"\" = \"$(grep '^Signed-off-by: ' \"$1\" |\n+\t sort | uniq -c | sed -e '/^[ \t]*1 /d')\"\ndiff --git a/templates/hooks--post-commit b/templates/hooks--post-commit\nnew file mode 100644\n--- /dev/null\n+++ b/templates/hooks--post-commit\n@@ -0,0 +1,8 @@\n+#!/bin/sh\n+#\n+# An example hook script that is called after a successful\n+# commit is made.\n+#\n+# To enable this hook, make this file executable.\n+\n+: Nothing\ndiff --git a/templates/hooks--pre-commit b/templates/hooks--pre-commit\nnew file mode 100644\n--- /dev/null\n+++ b/templates/hooks--pre-commit\n@@ -0,0 +1,60 @@\n+#!/bin/sh\n+#\n+# An example hook script to verify what is about to be committed.\n+# Called by git-commit-script with no arguments.  The hook should\n+# exit with non-zero status after issuing an appropriate message if\n+# it wants to stop the commit.\n+#\n+# To enable this hook, make this file executable.\n+\n+# This is slightly modified from Andrew Morton's Perfect Patch.\n+# Lines you introduce should not have trailing whitespace.\n+# Also check for an indentation that has SP before a TAB.\n+perl -e '\n+    my $fh;\n+    my $found_bad = 0;\n+    my $filename;\n+    my $reported_filename = \"\";\n+    my $lineno;\n+    sub bad_line {\n+\tmy ($why, $line) = @_;\n+\tif (!$found_bad) {\n+\t    print \"*\\n\";\n+\t    print \"* You have some suspicious patch lines:\\n\";\n+\t    print \"*\\n\";\n+\t    $found_bad = 1;\n+\t}\n+\tif ($reported_filename ne $filename) {\n+\t    print \"* In $filename\\n\";\n+\t    $reported_filename = $filename;\n+\t}\n+\tprint \"* $why (line $lineno)\\n$line\\n\";\n+    }\n+    open $fh, \"-|\", qw(git-diff-cache -p -M --cached HEAD);\n+    while (<$fh>) {\n+\tif (m|^diff --git a/(.*) b/\\1$|) {\n+\t    $filename = $1;\n+\t    next;\n+\t}\n+\tif (/^@@ -\\S+ \\+(\\d+)/) {\n+\t    $lineno = $1 - 1;\n+\t    next;\n+\t}\n+\tif (/^ /) {\n+\t    $lineno++;\n+\t    next;\n+\t}\n+\tif (s/^\\+//) {\n+\t    $lineno++;\n+\t    chomp;\n+\t    if (/\\s$/) {\n+\t\tbad_line(\"trailing whitespace\", $_);\n+\t    }\n+\t    if (/^\\s* \t/) {\n+\t\tbad_line(\"indent SP followed by a TAB\", $_);\n+\t    }\n+\t}\n+    }\n+    exit($found_bad);\n+'\n+\n"}]}