diff options
Diffstat (limited to 'contrib/hooks/post-receive-email')
-rwxr-xr-x | contrib/hooks/post-receive-email | 107 |
1 files changed, 83 insertions, 24 deletions
diff --git a/contrib/hooks/post-receive-email b/contrib/hooks/post-receive-email index 2a66063e44..fa6d41a1ab 100755 --- a/contrib/hooks/post-receive-email +++ b/contrib/hooks/post-receive-email @@ -23,6 +23,13 @@ # possible for the email to be from someone other than the person doing the # push. # +# To help with debugging and use on pre-v1.5.1 git servers, this script will +# also obey the interface of hooks/update, taking its arguments on the +# command line. Unfortunately, hooks/update is called once for each ref. +# To avoid firing one email per ref, this script just prints its output to +# the screen when used in this mode. The output can then be redirected if +# wanted. +# # Config # ------ # hooks.mailinglist @@ -48,6 +55,16 @@ # "t=%s; printf 'http://.../?id=%%s' \$t; echo;echo; git show -C \$t; echo" # Be careful if "..." contains things that will be expanded by shell "eval" # or printf. +# hooks.emailmaxlines +# The maximum number of lines that should be included in the generated +# email body. If not specified, there is no limit. +# Lines beyond the limit are suppressed and counted, and a final +# line is added indicating the number of suppressed lines. +# hooks.diffopts +# Alternate options for the git diff-tree invocation that shows changes. +# Default is "--stat --summary --find-copies-harder". Add -p to those +# options to include a unified diff of changes in addition to the usual +# summary output. # # Notes # ----- @@ -59,24 +76,16 @@ # ---------------------------- Functions # -# Top level email generation function. This decides what type of update -# this is and calls the appropriate body-generation routine after outputting -# the common header -# -# Note this function doesn't actually generate any email output, that is -# taken care of by the functions it calls: -# - generate_email_header -# - generate_create_XXXX_email -# - generate_update_XXXX_email -# - generate_delete_XXXX_email -# - generate_email_footer +# Function to prepare for email generation. This decides what type +# of update this is and whether an email should even be generated. # -generate_email() +prep_for_email() { # --- Arguments oldrev=$(git rev-parse $1) newrev=$(git rev-parse $2) refname="$3" + maxlines=$4 # --- Interpret # 0000->1234 (create) @@ -140,13 +149,13 @@ generate_email() short_refname=${refname##refs/remotes/} echo >&2 "*** Push-update of tracking branch, $refname" echo >&2 "*** - no email generated." - exit 0 + return 1 ;; *) # Anything else (is there anything else?) echo >&2 "*** Unknown type of update to $refname ($rev_type)" echo >&2 "*** - no email generated" - exit 1 + return 1 ;; esac @@ -162,9 +171,32 @@ generate_email() esac echo >&2 "*** $config_name is not set so no email will be sent" echo >&2 "*** for $refname update $oldrev->$newrev" - exit 0 + return 1 fi + return 0 +} + +# +# Top level email generation function. This calls the appropriate +# body-generation routine after outputting the common header. +# +# Note this function doesn't actually generate any email output, that is +# taken care of by the functions it calls: +# - generate_email_header +# - generate_create_XXXX_email +# - generate_update_XXXX_email +# - generate_delete_XXXX_email +# - generate_email_footer +# +# Note also that this function cannot 'exit' from the script; when this +# function is running (in hook script mode), the send_mail() function +# is already executing in another process, connected via a pipe, and +# if this function exits without, whatever has been generated to that +# point will be sent as an email... even if nothing has been generated. +# +generate_email() +{ # Email parameters # The email subject will contain the best description of the ref # that we can build from the parameters @@ -185,7 +217,12 @@ generate_email() fn_name=atag ;; esac - generate_${change_type}_${fn_name}_email + + if [ -z "$maxlines" ]; then + generate_${change_type}_${fn_name}_email + else + generate_${change_type}_${fn_name}_email | limit_lines $maxlines + fi generate_email_footer } @@ -196,7 +233,7 @@ generate_email_header() # Generate header cat <<-EOF To: $recipients - Subject: ${emailprefix}$projectdesc $refname_type, $short_refname, ${change_type}d. $describe + Subject: ${emailprefix}$projectdesc $refname_type $short_refname ${change_type}d. $describe X-Git-Refname: $refname X-Git-Reftype: $refname_type X-Git-Oldrev: $oldrev @@ -315,8 +352,8 @@ generate_update_branch_email() # "remotes/" will be ignored as well. # List all of the revisions that were removed by this update, in a - # fast forward update, this list will be empty, because rev-list O - # ^N is empty. For a non fast forward, O ^N is the list of removed + # fast-forward update, this list will be empty, because rev-list O + # ^N is empty. For a non-fast-forward, O ^N is the list of removed # revisions fast_forward="" rev="" @@ -411,10 +448,10 @@ generate_update_branch_email() # revision because the base is effectively a random revision at this # point - the user will be interested in what this revision changed # - including the undoing of previous revisions in the case of - # non-fast forward updates. + # non-fast-forward updates. echo "" echo "Summary of changes:" - git diff-tree --stat --summary --find-copies-harder $oldrev..$newrev + git diff-tree $diffopts $oldrev..$newrev } # @@ -635,6 +672,24 @@ show_new_revisions() } +limit_lines() +{ + lines=0 + skipped=0 + while IFS="" read -r line; do + lines=$((lines + 1)) + if [ $lines -gt $1 ]; then + skipped=$((skipped + 1)) + else + printf "%s\n" "$line" + fi + done + if [ $skipped -ne 0 ]; then + echo "... $skipped lines suppressed ..." + fi +} + + send_mail() { if [ -n "$envelopesender" ]; then @@ -659,7 +714,7 @@ if [ -z "$GIT_DIR" ]; then exit 1 fi -projectdesc=$(sed -ne '1p' "$GIT_DIR/description") +projectdesc=$(sed -ne '1p' "$GIT_DIR/description" 2>/dev/null) # Check if the description is unchanged from it's default, and shorten it to # a more manageable length if it is if expr "$projectdesc" : "Unnamed repository.*$" >/dev/null @@ -672,6 +727,9 @@ announcerecipients=$(git config hooks.announcelist) envelopesender=$(git config hooks.envelopesender) emailprefix=$(git config hooks.emailprefix || echo '[SCM] ') custom_showrev=$(git config hooks.showrev) +maxlines=$(git config hooks.emailmaxlines) +diffopts=$(git config hooks.diffopts) +: ${diffopts:="--stat --summary --find-copies-harder"} # --- Main loop # Allow dual mode: run from the command line just like the update hook, or @@ -680,10 +738,11 @@ if [ -n "$1" -a -n "$2" -a -n "$3" ]; then # Output to the terminal in command line mode - if someone wanted to # resend an email; they could redirect the output to sendmail # themselves - PAGER= generate_email $2 $3 $1 + prep_for_email $2 $3 $1 && PAGER= generate_email else while read oldrev newrev refname do - generate_email $oldrev $newrev $refname | send_mail + prep_for_email $oldrev $newrev $refname || continue + generate_email $maxlines | send_mail done fi |