1 git-multimail 2 ============= 3 4git-multimail is a tool for sending notification emails on pushes to a 5Git repository. It includes a Python module called git_multimail.py, 6which can either be used as a hook script directly or can be imported 7as a Python module into another script. 8 9git-multimail is derived from the Git project's old 10contrib/hooks/post-receive-email, and is mostly compatible with that 11script. See README.migrate-from-post-receive-email for details about 12the differences and for how to migrate from post-receive-email to 13git-multimail. 14 15git-multimail, like the rest of the Git project, is licensed under 16GPLv2 (see the COPYING file for details). 17 18Please note: although, as a convenience, git-multimail may be 19distributed along with the main Git project, development of 20git-multimail takes place in its own, separate project. See section 21"Getting involved" below for more information. 22 23 24By default, for each push received by the repository, git-multimail: 25 261. Outputs one email summarizing each reference that was changed. 27 These "reference change" (called "refchange" below) emails describe 28 the nature of the change (e.g., was the reference created, deleted, 29 fast-forwarded, etc.) and include a one-line summary of each commit 30 that was added to the reference. 31 322. Outputs one email for each new commit that was introduced by the 33 reference change. These "commit" emails include a list of the 34 files changed by the commit, followed by the diffs of files 35 modified by the commit. The commit emails are threaded to the 36 corresponding reference change email via "In-Reply-To". This style 37 (similar to the "git format-patch" style used on the Git mailing 38 list) makes it easy to scan through the emails, jump to patches 39 that need further attention, and write comments about specific 40 commits. Commits are handled in reverse topological order (i.e., 41 parents shown before children). For example, 42 43 [git] branch master updated 44 + [git] 01/08: doc: fix xref link from api docs to manual pages 45 + [git] 02/08: api-credentials.txt: show the big picture first 46 + [git] 03/08: api-credentials.txt: mention credential.helper explicitly 47 + [git] 04/08: api-credentials.txt: add "see also" section 48 + [git] 05/08: t3510 (cherry-pick-sequence): add missing '&&' 49 + [git] 06/08: Merge branch 'rr/maint-t3510-cascade-fix' 50 + [git] 07/08: Merge branch 'mm/api-credentials-doc' 51 + [git] 08/08: Git 1.7.11-rc2 52 53 Each commit appears in exactly one commit email, the first time 54 that it is pushed to the repository. If a commit is later merged 55 into another branch, then a one-line summary of the commit is 56 included in the reference change email (as usual), but no 57 additional commit email is generated. 58 59 By default, reference change emails have their "Reply-To" field set 60 to the person who pushed the change, and commit emails have their 61 "Reply-To" field set to the author of the commit. 62 633. Output one "announce" mail for each new annotated tag, including 64 information about the tag and optionally a shortlog describing the 65 changes since the previous tag. Such emails might be useful if you 66 use annotated tags to mark releases of your project. 67 68 69Requirements 70------------ 71 72* Python 2.x, version 2.4 or later. No non-standard Python modules 73 are required. git-multimail does *not* currently work with Python 74 3.x. 75 76 The example scripts invoke Python using the following shebang line 77 (following PEP 394 [1]): 78 79 #! /usr/bin/env python2 80 81 If your system's Python2 interpreter is not in your PATH or is not 82 called "python2", you can change the lines accordingly. Or you can 83 invoke the Python interpreter explicitly, for example via a tiny 84 shell script like 85 86 #! /bin/sh 87 /usr/local/bin/python /path/to/git_multimail.py "$@" 88 89* The "git" command must be in your PATH. git-multimail is known to 90 work with Git versions back to 1.7.1. (Earlier versions have not 91 been tested; if you do so, please report your results.) 92 93* To send emails using the default configuration, a standard sendmail 94 program must be located at '/usr/sbin/sendmail' and configured 95 correctly to send emails. If this is not the case, see the 96 multimailhook.mailer configuration variable below for how to 97 configure git-multimail to send emails via an SMTP server. 98 99 100Invocation 101---------- 102 103git_multimail.py is designed to be used as a "post-receive" hook in a 104Git repository (see githooks(5)). Link or copy it to 105$GIT_DIR/hooks/post-receive within the repository for which email 106notifications are desired. Usually it should be installed on the 107central repository for a project, to which all commits are eventually 108pushed. 109 110For use on pre-v1.5.1 Git servers, git_multimail.py can also work as 111an "update" hook, taking its arguments on the command line. To use 112this script in this manner, link or copy it to $GIT_DIR/hooks/update. 113Please note that the script is not completely reliable in this mode 114[2]. 115 116Alternatively, git_multimail.py can be imported as a Python module 117into your own Python post-receive script. This method is a bit more 118work, but allows the behavior of the hook to be customized using 119arbitrary Python code. For example, you can use a custom environment 120(perhaps inheriting from GenericEnvironment or GitoliteEnvironment) to 121 122* change how the user who did the push is determined 123 124* read users' email addresses from an LDAP server or from a database 125 126* decide which users should be notified about which commits based on 127 the contents of the commits (e.g., for users who want to be notified 128 only about changes affecting particular files or subdirectories) 129 130Or you can change how emails are sent by writing your own Mailer 131class. The "post-receive" script in this directory demonstrates how 132to use git_multimail.py as a Python module. (If you make interesting 133changes of this type, please consider sharing them with the 134community.) 135 136 137Configuration 138------------- 139 140By default, git-multimail mostly takes its configuration from the 141following "git config" settings: 142 143multimailhook.environment 144 145 This describes the general environment of the repository. 146 Currently supported values: 147 148 "generic" -- the username of the pusher is read from $USER and the 149 repository name is derived from the repository's path. 150 151 "gitolite" -- the username of the pusher is read from $GL_USER and 152 the repository name from $GL_REPO. 153 154 If neither of these environments is suitable for your setup, then 155 you can implement a Python class that inherits from Environment 156 and instantiate it via a script that looks like the example 157 post-receive script. 158 159 The environment value can be specified on the command line using 160 the --environment option. If it is not specified on the command 161 line or by multimailhook.environment, then it defaults to 162 "gitolite" if the environment contains variables $GL_USER and 163 $GL_REPO; otherwise "generic". 164 165multimailhook.repoName 166 167 A short name of this Git repository, to be used in various places 168 in the notification email text. The default is to use $GL_REPO 169 for gitolite repositories, or otherwise to derive this value from 170 the repository path name. 171 172multimailhook.mailinglist 173 174 The list of email addresses to which notification emails should be 175 sent, as RFC 2822 email addresses separated by commas. This 176 configuration option can be multivalued. Leave it unset or set it 177 to the empty string to not send emails by default. The next few 178 settings can be used to configure specific address lists for 179 specific types of notification email. 180 181multimailhook.refchangeList 182 183 The list of email addresses to which summary emails about 184 reference changes should be sent, as RFC 2822 email addresses 185 separated by commas. This configuration option can be 186 multivalued. The default is the value in 187 multimailhook.mailinglist. Set this value to the empty string to 188 prevent reference change emails from being sent. 189 190multimailhook.announceList 191 192 The list of email addresses to which emails about new annotated 193 tags should be sent, as RFC 2822 email addresses separated by 194 commas. This configuration option can be multivalued. The 195 default is the value in multimailhook.refchangelist or 196 multimailhook.mailinglist. Set this value to the empty string to 197 prevent annotated tag announcement emails from being sent. 198 199multimailhook.commitList 200 201 The list of email addresses to which emails about individual new 202 commits should be sent, as RFC 2822 email addresses separated by 203 commas. This configuration option can be multivalued. The 204 default is the value in multimailhook.mailinglist. Set this value 205 to the empty string to prevent notification emails about 206 individual commits from being sent. 207 208multimailhook.announceShortlog 209 210 If this option is set to true, then emails about changes to 211 annotated tags include a shortlog of changes since the previous 212 tag. This can be useful if the annotated tags represent releases; 213 then the shortlog will be a kind of rough summary of what has 214 happened since the last release. But if your tagging policy is 215 not so straightforward, then the shortlog might be confusing 216 rather than useful. Default is false. 217 218multimailhook.refchangeShowLog 219 220 If this option is set to true, then summary emails about reference 221 changes will include a detailed log of the added commits in 222 addition to the one line summary. The log is generated by running 223 "git log" with the options specified in multimailhook.logOpts. 224 Default is false. 225 226multimailhook.mailer 227 228 This option changes the way emails are sent. Accepted values are: 229 230 - sendmail (the default): use the command /usr/sbin/sendmail or 231 /usr/lib/sendmail (or sendmailCommand, if configured). This 232 mode can be further customized via the following options: 233 234 multimailhook.sendmailCommand 235 236 The command used by mailer "sendmail" to send emails. Shell 237 quoting is allowed in the value of this setting, but remember that 238 Git requires double-quotes to be escaped; e.g., 239 240 git config multimailhook.sendmailcommand '/usr/sbin/sendmail -t -F \"Git Repo\"' 241 242 Default is '/usr/sbin/sendmail -t' or '/usr/lib/sendmail 243 -t' (depending on which file is present and executable). 244 245 multimailhook.envelopeSender 246 247 If set then pass this value to sendmail via the -f option to set 248 the envelope sender address. 249 250 - smtp: use Python's smtplib. This is useful when the sendmail 251 command is not available on the system. This mode can be 252 further customized via the following options: 253 254 multimailhook.smtpServer 255 256 The name of the SMTP server to connect to. The value can 257 also include a colon and a port number; e.g., 258 "mail.example.com:25". Default is 'localhost' using port 259 25. 260 261 multimailhook.envelopeSender 262 263 The sender address to be passed to the SMTP server. If 264 unset, then the value of multimailhook.from is used. 265 266multimailhook.from 267 268 If set then use this value in the From: field of generated emails. 269 If unset, then use the repository's user configuration (user.name 270 and user.email). If user.email is also unset, then use 271 multimailhook.envelopeSender. 272 273multimailhook.administrator 274 275 The name and/or email address of the administrator of the Git 276 repository; used in FOOTER_TEMPLATE. Default is 277 multimailhook.envelopesender if it is set; otherwise a generic 278 string is used. 279 280multimailhook.emailPrefix 281 282 All emails have this string prepended to their subjects, to aid 283 email filtering (though filtering based on the X-Git-* email 284 headers is probably more robust). Default is the short name of 285 the repository in square brackets; e.g., "[myrepo]". 286 287multimailhook.emailMaxLines 288 289 The maximum number of lines that should be included in the body of 290 a generated email. If not specified, there is no limit. Lines 291 beyond the limit are suppressed and counted, and a final line is 292 added indicating the number of suppressed lines. 293 294multimailhook.emailMaxLineLength 295 296 The maximum length of a line in the email body. Lines longer than 297 this limit are truncated to this length with a trailing " [...]" 298 added to indicate the missing text. The default is 500, because 299 (a) diffs with longer lines are probably from binary files, for 300 which a diff is useless, and (b) even if a text file has such long 301 lines, the diffs are probably unreadable anyway. To disable line 302 truncation, set this option to 0. 303 304multimailhook.maxCommitEmails 305 306 The maximum number of commit emails to send for a given change. 307 When the number of patches is larger that this value, only the 308 summary refchange email is sent. This can avoid accidental 309 mailbombing, for example on an initial push. To disable commit 310 emails limit, set this option to 0. The default is 500. 311 312multimailhook.emailStrictUTF8 313 314 If this boolean option is set to "true", then the main part of the 315 email body is forced to be valid UTF-8. Any characters that are 316 not valid UTF-8 are converted to the Unicode replacement 317 character, U+FFFD. The default is "true". 318 319multimailhook.diffOpts 320 321 Options passed to "git diff-tree" when generating the summary 322 information for ReferenceChange emails. Default is "--stat 323 --summary --find-copies-harder". Add -p to those options to 324 include a unified diff of changes in addition to the usual summary 325 output. Shell quoting is allowed; see multimailhook.logOpts for 326 details. 327 328multimailhook.logOpts 329 330 Options passed to "git log" to generate additional info for 331 reference change emails (used only if refchangeShowLog is set). 332 For example, adding --graph will show the graph of revisions, -p 333 will show the complete diff, etc. The default is empty. 334 335 Shell quoting is allowed; for example, a log format that contains 336 spaces can be specified using something like: 337 338 git config multimailhook.logopts '--pretty=format:"%h %aN <%aE>%n%s%n%n%b%n"' 339 340 If you want to set this by editing your configuration file 341 directly, remember that Git requires double-quotes to be escaped 342 (see git-config(1) for more information): 343 344 [multimailhook] 345 logopts = --pretty=format:\"%h %aN <%aE>%n%s%n%n%b%n\" 346 347multimailhook.emailDomain 348 349 Domain name appended to the username of the person doing the push 350 to convert it into an email address (via "%s@%s" % (username, 351 emaildomain)). More complicated schemes can be implemented by 352 overriding Environment and overriding its get_pusher_email() 353 method. 354 355multimailhook.replyTo 356multimailhook.replyToCommit 357multimailhook.replyToRefchange 358 359 Addresses to use in the Reply-To: field for commit emails 360 (replyToCommit) and refchange emails (replyToRefchange). 361 multimailhook.replyTo is used as default when replyToCommit or 362 replyToRefchange is not set. The value for these variables can be 363 either: 364 365 - An email address, which will be used directly. 366 367 - The value "pusher", in which case the pusher's address (if 368 available) will be used. This is the default for refchange 369 emails. 370 371 - The value "author" (meaningful only for replyToCommit), in which 372 case the commit author's address will be used. This is the 373 default for commit emails. 374 375 - The value "none", in which case the Reply-To: field will be 376 omitted. 377 378 379Email filtering aids 380-------------------- 381 382All emails include extra headers to enable fine tuned filtering and 383give information for debugging. All emails include the headers 384"X-Git-Repo", "X-Git-Refname", and "X-Git-Reftype". ReferenceChange 385emails also include headers "X-Git-Oldrev" and "X-Git-Newrev"; 386Revision emails also include header "X-Git-Rev". 387 388 389Customizing email contents 390-------------------------- 391 392git-multimail mostly generates emails by expanding templates. The 393templates can be customized. To avoid the need to edit 394git_multimail.py directly, the preferred way to change the templates 395is to write a separate Python script that imports git_multimail.py as 396a module, then replaces the templates in place. See the provided 397post-receive script for an example of how this is done. 398 399 400Customizing git-multimail for your environment 401---------------------------------------------- 402 403git-multimail is mostly customized via an "environment" that describes 404the local environment in which Git is running. Two types of 405environment are built in: 406 407* GenericEnvironment: a stand-alone Git repository. 408 409* GitoliteEnvironment: a Git repository that is managed by gitolite 410 [3]. For such repositories, the identity of the pusher is read from 411 environment variable $GL_USER, and the name of the repository is 412 read from $GL_REPO (if it is not overridden by 413 multimailhook.reponame). 414 415By default, git-multimail assumes GitoliteEnvironment if $GL_USER and 416$GL_REPO are set, and otherwise assumes GenericEnvironment. 417Alternatively, you can choose one of these two environments explicitly 418by setting a "multimailhook.environment" config setting (which can 419have the value "generic" or "gitolite") or by passing an --environment 420option to the script. 421 422If you need to customize the script in ways that are not supported by 423the existing environments, you can define your own environment class 424class using arbitrary Python code. To do so, you need to import 425git_multimail.py as a Python module, as demonstrated by the example 426post-receive script. Then implement your environment class; it should 427usually inherit from one of the existing Environment classes and 428possibly one or more of the EnvironmentMixin classes. Then set the 429"environment" variable to an instance of your own environment class 430and pass it to run_as_post_receive_hook(). 431 432The standard environment classes, GenericEnvironment and 433GitoliteEnvironment, are in fact themselves put together out of a 434number of mixin classes, each of which handles one aspect of the 435customization. For the finest control over your configuration, you 436can specify exactly which mixin classes your own environment class 437should inherit from, and override individual methods (or even add your 438own mixin classes) to implement entirely new behaviors. If you 439implement any mixins that might be useful to other people, please 440consider sharing them with the community! 441 442 443Getting involved 444---------------- 445 446git-multimail is an open-source project, built by volunteers. We 447would welcome your help! 448 449The current maintainer is Michael Haggerty <mhagger@alum.mit.edu>. 450 451General discussion of git-multimail takes place on the main Git 452mailing list, 453 454 git@vger.kernel.org 455 456Please CC emails regarding git-multimail to me so that I don't 457overlook them. 458 459The git-multimail project itself is currently hosted on GitHub: 460 461 https://github.com/mhagger/git-multimail 462 463We use the GitHub issue tracker to keep track of bugs and feature 464requests, and GitHub pull requests to exchange patches (though, if you 465prefer, you can send patches via the Git mailing list with cc to me). 466 467Please note that although a copy of git-multimail will probably be 468distributed in the "contrib" section of the main Git project, 469development takes place in the separate git-multimail repository on 470GitHub! (Whenever enough changes to git-multimail have accumulated, a 471new code-drop of git-multimail will be submitted for inclusion in the 472Git project.) 473 474 475Footnotes 476--------- 477 478[1] http://www.python.org/dev/peps/pep-0394/ 479 480[2] Because of the way information is passed to update hooks, the 481 script's method of determining whether a commit has already been 482 seen does not work when it is used as an "update" script. In 483 particular, no notification email will be generated for a new 484 commit that is added to multiple references in the same push. 485 486[3] https://github.com/sitaramc/gitolite