Code

Merge branch 'sp/emfile'
[git.git] / contrib / hooks / post-receive-email
index 30ae63d74da065a31cced0b161708680f39c04c0..85724bfc08f61d3b928460a8d2ad5ec03cf80b52 100755 (executable)
 #     "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.
 #
 # Notes
 # -----
 # ---------------------------- 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
+# Function to prepare for email generation. This decides what type
+# of update this is and whether an email should even be generated.
 #
-# 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
-#
-generate_email()
+prep_for_email()
 {
        # --- Arguments
        oldrev=$(git rev-parse $1)
        newrev=$(git rev-parse $2)
        refname="$3"
+       maxlines=$4
 
        # --- Interpret
        # 0000->1234 (create)
@@ -153,7 +150,7 @@ generate_email()
                        # Anything else (is there anything else?)
                        echo >&2 "*** Unknown type of update to $refname ($rev_type)"
                        echo >&2 "***  - no email generated"
-                       exit 1
+                       return 0
                        ;;
        esac
 
@@ -169,9 +166,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 0
        fi
 
+       return 1
+}
+
+#
+# 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
@@ -192,7 +212,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
 }
@@ -203,7 +228,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
@@ -642,6 +667,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
@@ -679,6 +722,7 @@ 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)
 
 # --- Main loop
 # Allow dual mode: run from the command line just like the update hook, or
@@ -687,10 +731,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