-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
An enhanced "post-receive" hook to send e-mail messages. * mh/multimail: post-receive-email: deprecate script in favor of git-multimail git-multimail: an improved replacement for post-receive-email
- v2.8.1
- v2.8.0
- v2.8.0-rc4
- v2.8.0-rc3
- v2.8.0-rc2
- v2.8.0-rc1
- v2.8.0-rc0
- v2.7.4
- v2.7.3
- v2.7.2
- v2.7.1
- v2.7.0
- v2.7.0-rc3
- v2.7.0-rc2
- v2.7.0-rc1
- v2.7.0-rc0
- v2.6.6
- v2.6.5
- v2.6.4
- v2.6.3
- v2.6.2
- v2.6.1
- v2.6.0
- v2.6.0-rc3
- v2.6.0-rc2
- v2.6.0-rc1
- v2.6.0-rc0
- v2.5.5
- v2.5.4
- v2.5.3
- v2.5.2
- v2.5.1
- v2.5.0
- v2.5.0-rc3
- v2.5.0-rc2
- v2.5.0-rc1
- v2.5.0-rc0
- v2.4.11
- v2.4.10
- v2.4.9
- v2.4.8
- v2.4.7
- v2.4.6
- v2.4.5
- v2.4.4
- v2.4.3
- v2.4.2
- v2.4.1
- v2.4.0
- v2.4.0-rc3
- v2.4.0-rc2
- v2.4.0-rc1
- v2.4.0-rc0
- v2.3.10
- v2.3.9
- v2.3.8
- v2.3.7
- v2.3.6
- v2.3.5
- v2.3.4
- v2.3.3
- v2.3.2
- v2.3.1
- v2.3.0
- v2.3.0-rc2
- v2.3.0-rc1
- v2.3.0-rc0
- v2.2.3
- v2.2.2
- v2.2.1
- v2.2.0
- v2.2.0-rc3
- v2.2.0-rc2
- v2.2.0-rc1
- v2.2.0-rc0
- v2.1.4
- v2.1.3
- v2.1.2
- v2.1.1
- v2.1.0
- v2.1.0-rc2
- v2.1.0-rc1
- v2.1.0-rc0
- v2.0.5
- v2.0.4
- v2.0.3
- v2.0.2
- v2.0.1
- v2.0.0
- v2.0.0-rc4
- v2.0.0-rc3
- v2.0.0-rc2
- v2.0.0-rc1
- v2.0.0-rc0
- v1.9.5
- v1.9.4
- v1.9.3
- v1.9.2
- v1.9.1
- v1.9.0
- v1.9.0-rc3
- v1.9-rc2
- v1.9-rc1
- v1.9-rc0
- v1.8.5.6
- v1.8.5.5
- v1.8.5.4
- v1.8.5.3
- v1.8.5.2
- v1.8.5.1
- v1.8.5
- v1.8.5-rc3
- v1.8.5-rc2
- v1.8.5-rc1
- v1.8.5-rc0
- v1.8.4.5
- v1.8.4.4
- v1.8.4.3
- v1.8.4.2
- v1.8.4.1
- v1.8.4
- v1.8.4-rc4
- v1.8.4-rc3
- v1.8.4-rc2
- v1.8.4-rc1
- v1.8.4-rc0
Showing
7 changed files
with
3,411 additions
and
4 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
This copy of git-multimail is distributed as part of the "contrib" | ||
section of the Git project as a convenience to Git users. | ||
git-multimail is developed as an independent project at the following | ||
website: | ||
|
||
https://github.com/mhagger/git-multimail | ||
|
||
The version in this directory was obtained from the upstream project | ||
on 2013-07-14 and consists of the "git-multimail" subdirectory from | ||
revision | ||
|
||
1a5cb09c698a74d15a715a86b09ead5f56bf4b06 | ||
|
||
Please see the README file in this directory for information about how | ||
to report bugs or contribute to git-multimail. |
145 changes: 145 additions & 0 deletions
145
contrib/hooks/multimail/README.migrate-from-post-receive-email
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
git-multimail is close to, but not exactly, a plug-in replacement for | ||
the old Git project script contrib/hooks/post-receive-email. This | ||
document describes the differences and explains how to configure | ||
git-multimail to get behavior closest to that of post-receive-email. | ||
|
||
If you are in a hurry | ||
===================== | ||
|
||
A script called migrate-mailhook-config is included with | ||
git-multimail. If you run this script within a Git repository that is | ||
configured to use post-receive-email, it will convert the | ||
configuration settings into the approximate equivalent settings for | ||
git-multimail. For more information, run | ||
|
||
migrate-mailhook-config --help | ||
|
||
|
||
Configuration differences | ||
========================= | ||
|
||
* The names of the config options for git-multimail are in namespace | ||
"multimailhook.*" instead of "hooks.*". (Editorial comment: | ||
post-receive-email should never have used such a generic top-level | ||
namespace.) | ||
|
||
* In emails about new annotated tags, post-receive-email includes a | ||
shortlog of all changes since the previous annotated tag. To get | ||
this behavior with git-multimail, you need to set | ||
multimailhook.announceshortlog to true: | ||
|
||
git config multimailhook.announceshortlog true | ||
|
||
* multimailhook.commitlist -- This is a new configuration variable. | ||
Recipients listed here will receive a separate email for each new | ||
commit. However, if this variable is *not* set, it defaults to the | ||
value of multimailhook.mailinglist. Therefore, if you *don't* want | ||
the members of multimailhook.mailinglist to receive one email per | ||
commit, then set this value to the empty string: | ||
|
||
git config multimailhook.commitlist '' | ||
|
||
* multimailhook.emailprefix -- If this value is not set, then the | ||
subjects of generated emails are prefixed with the short name of the | ||
repository enclosed in square brackets; e.g., "[myrepo]". | ||
post-receive-email defaults to prefix "[SCM]" if this option is not | ||
set. So if you were using the old default and want to retain it | ||
(for example, to avoid having to change your email filters), set | ||
this variable explicitly to the old value: | ||
|
||
git config multimailhook.emailprefix "[SCM]" | ||
|
||
* The "multimailhook.showrev" configuration option is not supported. | ||
Its main use is obsoleted by the one-email-per-commit feature of | ||
git-multimail. | ||
|
||
|
||
Other differences | ||
================= | ||
|
||
This section describes other differences in the behavior of | ||
git-multimail vs. post-receive-email. For full details, please refer | ||
to the main README file: | ||
|
||
* One email per commit. For each reference change, the script first | ||
outputs one email summarizing the reference change (including | ||
one-line summaries of the new commits), then it outputs a separate | ||
email for each new commit that was introduced, including patches. | ||
These one-email-per-commit emails go to the addresses listed in | ||
multimailhook.commitlist. post-receive-email sends only one email | ||
for each *reference* that is changed, no matter how many commits | ||
were added to the reference. | ||
|
||
* Better algorithm for detecting new commits. post-receive-email | ||
processes one reference change at a time, which causes it to fail to | ||
describe new commits that were included in multiple branches. For | ||
example, if a single push adds the "*" commits in the diagram below, | ||
then post-receive-email would never include the details of the two | ||
commits that are common to "master" and "branch" in its | ||
notifications. | ||
|
||
o---o---o---*---*---* <-- master | ||
\ | ||
*---* <-- branch | ||
|
||
git-multimail analyzes all reference modifications to determine | ||
which commits were not present before the change, therefore avoiding | ||
that error. | ||
|
||
* In reference change emails, git-multimail tells which commits have | ||
been added to the reference vs. are entirely new to the repository, | ||
and which commits that have been omitted from the reference | ||
vs. entirely discarded from the repository. | ||
|
||
* The environment in which Git is running can be configured via an | ||
"Environment" abstraction. | ||
|
||
* Built-in support for Gitolite-managed repositories. | ||
|
||
* Instead of using full SHA1 object names in emails, git-multimail | ||
mostly uses abbreviated SHA1s, plus one-line log message summaries | ||
where appropriate. | ||
|
||
* In the schematic diagrams that explain non-fast-forward commits, | ||
git-multimail shows the names of the branches involved. | ||
|
||
* The emails generated by git-multimail include the name of the Git | ||
repository that was modified; this is convenient for recipients who | ||
are monitoring multiple repositories. | ||
|
||
* git-multimail allows the email "From" addresses to be configured. | ||
|
||
* The recipients lists (multimailhook.mailinglist, | ||
multimailhook.refchangelist, multimailhook.announcelist, and | ||
multimailhook.commitlist) can be comma-separated values and/or | ||
multivalued settings in the config file; e.g., | ||
|
||
[multimailhook] | ||
mailinglist = mr.brown@example.com, mr.black@example.com | ||
announcelist = Him <him@example.com> | ||
announcelist = Jim <jim@example.com> | ||
announcelist = pop@example.com | ||
|
||
This might make it easier to maintain short recipients lists without | ||
requiring full-fledged mailing list software. | ||
|
||
* By default, git-multimail sets email "Reply-To" headers to reply to | ||
the pusher (for reference updates) and to the author (for commit | ||
notifications). By default, the pusher's email address is | ||
constructed by appending "multimailhook.emaildomain" to the pusher's | ||
username. | ||
|
||
* The generated emails contain a configurable footer. By default, it | ||
lists the name of the administrator who should be contacted to | ||
unsubscribe from notification emails. | ||
|
||
* New option multimailhook.emailmaxlinelength to limit the length of | ||
lines in the main part of the email body. The default limit is 500 | ||
characters. | ||
|
||
* New option multimailhook.emailstrictutf8 to ensure that the main | ||
part of the email body is valid UTF-8. Invalid characters are | ||
turned into the Unicode replacement character, U+FFFD. By default | ||
this option is turned on. | ||
|
||
* Written in Python. Easier to add new features. |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,269 @@ | ||
#! /usr/bin/env python2 | ||
|
||
"""Migrate a post-receive-email configuration to be usable with git_multimail.py. | ||
See README.migrate-from-post-receive-email for more information. | ||
""" | ||
|
||
import sys | ||
import optparse | ||
|
||
from git_multimail import CommandError | ||
from git_multimail import Config | ||
from git_multimail import read_output | ||
|
||
|
||
OLD_NAMES = [ | ||
'mailinglist', | ||
'announcelist', | ||
'envelopesender', | ||
'emailprefix', | ||
'showrev', | ||
'emailmaxlines', | ||
'diffopts', | ||
] | ||
|
||
NEW_NAMES = [ | ||
'environment', | ||
'reponame', | ||
'mailinglist', | ||
'refchangelist', | ||
'commitlist', | ||
'announcelist', | ||
'announceshortlog', | ||
'envelopesender', | ||
'administrator', | ||
'emailprefix', | ||
'emailmaxlines', | ||
'diffopts', | ||
'emaildomain', | ||
] | ||
|
||
|
||
INFO = """\ | ||
SUCCESS! | ||
Your post-receive-email configuration has been converted to | ||
git-multimail format. Please see README and | ||
README.migrate-from-post-receive-email to learn about other | ||
git-multimail configuration possibilities. | ||
For example, git-multimail has the following new options with no | ||
equivalent in post-receive-email. You might want to read about them | ||
to see if they would be useful in your situation: | ||
""" | ||
|
||
|
||
def _check_old_config_exists(old): | ||
"""Check that at least one old configuration value is set.""" | ||
|
||
for name in OLD_NAMES: | ||
if old.has_key(name): | ||
return True | ||
|
||
return False | ||
|
||
|
||
def _check_new_config_clear(new): | ||
"""Check that none of the new configuration names are set.""" | ||
|
||
retval = True | ||
for name in NEW_NAMES: | ||
if new.has_key(name): | ||
if retval: | ||
sys.stderr.write('INFO: The following configuration values already exist:\n\n') | ||
sys.stderr.write(' "%s.%s"\n' % (new.section, name)) | ||
retval = False | ||
|
||
return retval | ||
|
||
|
||
def erase_values(config, names): | ||
for name in names: | ||
if config.has_key(name): | ||
try: | ||
sys.stderr.write('...unsetting "%s.%s"\n' % (config.section, name)) | ||
config.unset_all(name) | ||
except CommandError: | ||
sys.stderr.write( | ||
'\nWARNING: could not unset "%s.%s". ' | ||
'Perhaps it is not set at the --local level?\n\n' | ||
% (config.section, name) | ||
) | ||
|
||
|
||
def is_section_empty(section, local): | ||
"""Return True iff the specified configuration section is empty. | ||
Iff local is True, use the --local option when invoking 'git | ||
config'.""" | ||
|
||
if local: | ||
local_option = ['--local'] | ||
else: | ||
local_option = [] | ||
|
||
try: | ||
read_output( | ||
['git', 'config'] | ||
+ local_option | ||
+ ['--get-regexp', '^%s\.' % (section,)] | ||
) | ||
except CommandError, e: | ||
if e.retcode == 1: | ||
# This means that no settings were found. | ||
return True | ||
else: | ||
raise | ||
else: | ||
return False | ||
|
||
|
||
def remove_section_if_empty(section): | ||
"""If the specified configuration section is empty, delete it.""" | ||
|
||
try: | ||
empty = is_section_empty(section, local=True) | ||
except CommandError: | ||
# Older versions of git do not support the --local option, so | ||
# if the first attempt fails, try without --local. | ||
try: | ||
empty = is_section_empty(section, local=False) | ||
except CommandError: | ||
sys.stderr.write( | ||
'\nINFO: If configuration section "%s.*" is empty, you might want ' | ||
'to delete it.\n\n' | ||
% (section,) | ||
) | ||
return | ||
|
||
if empty: | ||
sys.stderr.write('...removing section "%s.*"\n' % (section,)) | ||
read_output(['git', 'config', '--remove-section', section]) | ||
else: | ||
sys.stderr.write( | ||
'\nINFO: Configuration section "%s.*" still has contents. ' | ||
'It will not be deleted.\n\n' | ||
% (section,) | ||
) | ||
|
||
|
||
def migrate_config(strict=False, retain=False, overwrite=False): | ||
old = Config('hooks') | ||
new = Config('multimailhook') | ||
if not _check_old_config_exists(old): | ||
sys.exit( | ||
'Your repository has no post-receive-email configuration. ' | ||
'Nothing to do.' | ||
) | ||
if not _check_new_config_clear(new): | ||
if overwrite: | ||
sys.stderr.write('\nWARNING: Erasing the above values...\n\n') | ||
erase_values(new, NEW_NAMES) | ||
else: | ||
sys.exit( | ||
'\nERROR: Refusing to overwrite existing values. Use the --overwrite\n' | ||
'option to continue anyway.' | ||
) | ||
|
||
name = 'showrev' | ||
if old.has_key(name): | ||
msg = 'git-multimail does not support "%s.%s"' % (old.section, name,) | ||
if strict: | ||
sys.exit( | ||
'ERROR: %s.\n' | ||
'Please unset that value then try again, or run without --strict.' | ||
% (msg,) | ||
) | ||
else: | ||
sys.stderr.write('\nWARNING: %s (ignoring).\n\n' % (msg,)) | ||
|
||
for name in ['mailinglist', 'announcelist']: | ||
if old.has_key(name): | ||
sys.stderr.write( | ||
'...copying "%s.%s" to "%s.%s"\n' % (old.section, name, new.section, name) | ||
) | ||
new.set_recipients(name, old.get_recipients(name)) | ||
|
||
if strict: | ||
sys.stderr.write( | ||
'...setting "%s.commitlist" to the empty string\n' % (new.section,) | ||
) | ||
new.set_recipients('commitlist', '') | ||
sys.stderr.write( | ||
'...setting "%s.announceshortlog" to "true"\n' % (new.section,) | ||
) | ||
new.set('announceshortlog', 'true') | ||
|
||
for name in ['envelopesender', 'emailmaxlines', 'diffopts']: | ||
if old.has_key(name): | ||
sys.stderr.write( | ||
'...copying "%s.%s" to "%s.%s"\n' % (old.section, name, new.section, name) | ||
) | ||
new.set(name, old.get(name)) | ||
|
||
name = 'emailprefix' | ||
if old.has_key(name): | ||
sys.stderr.write( | ||
'...copying "%s.%s" to "%s.%s"\n' % (old.section, name, new.section, name) | ||
) | ||
new.set(name, old.get(name)) | ||
elif strict: | ||
sys.stderr.write( | ||
'...setting "%s.%s" to "[SCM]" to preserve old subject lines\n' | ||
% (new.section, name) | ||
) | ||
new.set(name, '[SCM]') | ||
|
||
if not retain: | ||
erase_values(old, OLD_NAMES) | ||
remove_section_if_empty(old.section) | ||
|
||
sys.stderr.write(INFO) | ||
for name in NEW_NAMES: | ||
if name not in OLD_NAMES: | ||
sys.stderr.write(' "%s.%s"\n' % (new.section, name,)) | ||
sys.stderr.write('\n') | ||
|
||
|
||
def main(args): | ||
parser = optparse.OptionParser( | ||
description=__doc__, | ||
usage='%prog [OPTIONS]', | ||
) | ||
|
||
parser.add_option( | ||
'--strict', action='store_true', default=False, | ||
help=( | ||
'Slavishly configure git-multimail as closely as possible to ' | ||
'the post-receive-email configuration. Default is to turn ' | ||
'on some new features that have no equivalent in post-receive-email.' | ||
), | ||
) | ||
parser.add_option( | ||
'--retain', action='store_true', default=False, | ||
help=( | ||
'Retain the post-receive-email configuration values. ' | ||
'Default is to delete them after the new values are set.' | ||
), | ||
) | ||
parser.add_option( | ||
'--overwrite', action='store_true', default=False, | ||
help=( | ||
'Overwrite any existing git-multimail configuration settings. ' | ||
'Default is to abort if such settings already exist.' | ||
), | ||
) | ||
|
||
(options, args) = parser.parse_args(args) | ||
|
||
if args: | ||
parser.error('Unexpected arguments: %s' % (' '.join(args),)) | ||
|
||
migrate_config(strict=options.strict, retain=options.retain, overwrite=options.overwrite) | ||
|
||
|
||
main(sys.argv[1:]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
#! /usr/bin/env python2 | ||
|
||
"""Example post-receive hook based on git-multimail. | ||
This script is a simple example of a post-receive hook implemented | ||
using git_multimail.py as a Python module. It is intended to be | ||
customized before use; see the comments in the script to help you get | ||
started. | ||
It is possible to use git_multimail.py itself as a post-receive or | ||
update hook, configured via git config settings and/or command-line | ||
parameters. But for more flexibility, it can also be imported as a | ||
Python module by a custom post-receive script as done here. The | ||
latter has the following advantages: | ||
* The tool's behavior can be customized using arbitrary Python code, | ||
without having to edit git_multimail.py. | ||
* Configuration settings can be read from other sources; for example, | ||
user names and email addresses could be read from LDAP or from a | ||
database. Or the settings can even be hardcoded in the importing | ||
Python script, if this is preferred. | ||
This script is a very basic example of how to use git_multimail.py as | ||
a module. The comments below explain some of the points at which the | ||
script's behavior could be changed or customized. | ||
""" | ||
|
||
import sys | ||
import os | ||
|
||
# If necessary, add the path to the directory containing | ||
# git_multimail.py to the Python path as follows. (This is not | ||
# necessary if git_multimail.py is in the same directory as this | ||
# script): | ||
|
||
#LIBDIR = 'path/to/directory/containing/module' | ||
#sys.path.insert(0, LIBDIR) | ||
|
||
import git_multimail | ||
|
||
|
||
# It is possible to modify the output templates here; e.g.: | ||
|
||
#git_multimail.FOOTER_TEMPLATE = """\ | ||
# | ||
#-- \n\ | ||
#This email was generated by the wonderful git-multimail tool. | ||
#""" | ||
|
||
|
||
# Specify which "git config" section contains the configuration for | ||
# git-multimail: | ||
config = git_multimail.Config('multimailhook') | ||
|
||
|
||
# Select the type of environment: | ||
environment = git_multimail.GenericEnvironment(config=config) | ||
#environment = git_multimail.GitoliteEnvironment(config=config) | ||
|
||
|
||
# Choose the method of sending emails based on the git config: | ||
mailer = git_multimail.choose_mailer(config, environment) | ||
|
||
# Alternatively, you may hardcode the mailer using code like one of | ||
# the following: | ||
|
||
# Use "/usr/sbin/sendmail -t" to send emails. The envelopesender | ||
# argument is optional: | ||
#mailer = git_multimail.SendMailer( | ||
# command=['/usr/sbin/sendmail', '-t'], | ||
# envelopesender='git-repo@example.com', | ||
# ) | ||
|
||
# Use Python's smtplib to send emails. Both arguments are required. | ||
#mailer = git_multimail.SMTPMailer( | ||
# envelopesender='git-repo@example.com', | ||
# # The smtpserver argument can also include a port number; e.g., | ||
# # smtpserver='mail.example.com:25' | ||
# smtpserver='mail.example.com', | ||
# ) | ||
|
||
# OutputMailer is intended only for testing; it writes the emails to | ||
# the specified file stream. | ||
#mailer = git_multimail.OutputMailer(sys.stdout) | ||
|
||
|
||
# Read changes from stdin and send notification emails: | ||
git_multimail.run_as_post_receive_hook(environment, mailer) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters