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