Add a get_ref_ignore_list() function to allow refs to be ignored

Some deployments may have refs for which they don't want emails sent out
when they are updated.  However, if commits pushed to these refs are later
pushed to another ref, we do want emails for those commits at that time.
This means that these refs should be ignored both in terms of which
changes we should send out emails for, and when computing what commits are
considered new to the repository.

We set the default for this in the base Environment to ["refs/notes/"].
A default of [] would make sense if git_multimail had a specialized
formatting for commits made by git notes, but it currently doesn't.  In
particular, the commit messages of git notes are essentially meaningless
and "filenames" in git notes commits are merely an implementational
detail.  As such, sending emails for these commits, with our current
format, is suboptimal.

Notes are not the only reason for an exclusion, though.  For example,
Gerrit uses refs/changes/ to store commits that have not yet been vetted.
Users think of commits stored under refs/changes/ as being new to the
repository only when they are finally merged into a branch under
refs/heads/.  (There are a variety of reasons for this: (a) these commits
haven't undergone code review and thus are viewed as not yet having been
accepted, (b) Gerrit has a separate mechanism to handle things pushed to
refs/changes/ (emailing just a few relevant folks with a message along
the lines of "You have a Change Review that you need to look at; look at
this nifty web page to add your comments."), (c) only a small subset of
users are interested in any particular refs/changes/ push, whereas
hundreds of developers want to see what enters refs/heads/, (d), gerrit's
standard ref-updated hook, which is similar to git's update or
post-receive hooks, is not invoked for these refs.  It all adds up to
reasons to ignore this particular ref namespace.)  Another example is
Gerrit's refs/cache-automerge/, which is essentially just an
implementational detail that we clearly don't want to spam users about.

Signed-off-by: Elijah Newren <newren@palantir.com>
GerritEnvironment: Make git_multimail callable as Gerrit ref-updated hook

git_multimail has the ability to be directly called as either a git update
or git post-receive hook.  Add the ability for git_multimail to be called
as a Gerrit ref-updated hook (Gerrit does not implement the standard git
hooks), and provide a GerritEnvironment (similar to GitoliteEnvironment
or GenericEnvironment) with relevant defaults.

Gerrit users are probably slightly less likely to use git_multimail since
gerrit already has a built-in email capability.  However:
  * Gerrit's emails appear to only trigger for references submitted as CRs
    (e.g. pushed to the magic refspec refs/for/), not for commits directly
    pushed to the relevant branch.
  * Some sites may have multiple git servers installed (e.g. Gitolite,
    Gerrit, Atlassian Stash) and want similar email styles used regardless
    of which system the repository is hosted under.

Signed-off-by: Elijah Newren <newren@palantir.com>
GerritEnvironment: Skip merge commits created internally by Gerrit

Gerrit often creates a merge behind the scenes for an approved code
review.  Since it's a behind the scenes implementational detail, users
aren't necessarily interested in getting an individual email for each of
these.  Filter them out.

Signed-off-by: Elijah Newren <newren@palantir.com>
GerritEnvironment: Commits can enter repositories multiple ways

Since commits can both be directly 'pushed' to the repository, or first
be created as a patchset and then 'submitted' from the web UI (with the
latter far more common), claiming that all gerrit commits were 'pushed'
will confuse users.  Make an "update_method" value available for
templates so that emails can use the correct verb.

This would also apply to Stash, if it provided a way to differentiate
in its (Async)?PostReceiveRepositoryHook classes between being
triggered by a direct push and by the merge of a pull request.

Signed-off-by: Elijah Newren <newren@palantir.com>
GerritEnvironment: Work around rude discarding of submitter identity

We want to know who pushes/submits code to the repository, because that
information is included in the emails.  However, Gerrit often rudely
discards this information upon calling its ref-updated hook.  When Gerrit
doesn't provide this information directly, try to grab it indirectly.

Signed-off-by: Elijah Newren <newren@palantir.com>
StashEnvironment: New environment for being called from Atlassian Stash

Atlassian Stash can utilize a standard post-receive hook, and thus we
could use git_multimail as-is.  However, that is slightly suboptimal
because: (a) when pull requests are merged in stash, they are done on the
server and thus the normal post-receive hook is not triggered, (b)
everything runs as a single user similar to gitolite, but without a
GL_USER environment variable to rely on, and (c) although stash has
reasonable clone urls that having meaningful names for repositories, the
actual on-disk directories in which the repositories are stored are given
positive integers for names -- that results in a rather meaningless email
subject for the users ("[2093] branch master updated..." rather than
"[PROJ/REPO] branch master updated..."), since they will have no idea what
magic integer happened to be selected for their repository.

We can avoid these problems by making use of Stash's
AsyncPostReceiveRepositoryHook instead of a standard post-receive hook,
since it is triggered in all the right cases and has access to the
appropriate user and repo name.  Add a StashEnvironment for holding this
passed information, and add command line flags that can be passed with
the user and repo name.

Signed-off-by: Elijah Newren <newren@palantir.com>
GerritEnvironment, StashEnvironment: Make From=pusher by default

I see no value in getting emails from
   gerrit@<company-machine-no-one-needs-to-know-about>
or
   stash@<company-machine-no-one-needs-to-know-about>.localdomain
The default user.email setting is often far less than perfect, and having
to set multimailhook.from for every repository is not ideal either.

A default that makes more sense to me is that the email comes from the
person who pushed the change; for StashEnvironment we will always have
that information available and in GerritEnvironment we often will.

Signed-off-by: Elijah Newren <newren@palantir.com>
Atlassian Stash plugin: Initial version

This adds a plugin for Atlassian Stash that will run git_multimail as an
AsyncPostReceiveRepositoryHook (similar to a standard post-receive hook,
but also fires for merges of pull-requests; further, via Stash's Java API
such a hook has access to important data like user and repo name).

This plugin currently provides a single textbox entry of configuration at
the time that a repository owner enables the plugin, in which the
repository owner can provide a comma-separated list of email addresses
that they want the emails sent to.  Other multimail configuration options
are unexposed through the web UI, though they can be configured on a
repository-by-repository basis on the server if an admin sets the
appropriate multimailhook.* configuration setting in the git config file.

Signed-off-by: Elijah Newren <newren@palantir.com>
Atlassian Stash plugin: Add logging capability

Signed-off-by: Carl Myers <cmyers@palantir.com>
Signed-off-by: Elijah Newren <newren@palantir.com>
Atlassian Stash plugin: Providing scaffolding for tests

Signed-off-by: Carl Myers <cmyers@palantir.com>
Signed-off-by: Elijah Newren <newren@palantir.com>
Atlassian Stash plugin: Default recipients list on project settings page

Signed-off-by: Elijah Newren <newren@palantir.com>
Emit single pushed commit as just a single email

No need to send both a refchanged email and commit email.

In the sadly-all-too-frequent usecase of people pushing only one of their
commits at a time to a repository, users feel the reference change summary
emails are noise rather than important signal.  This is because there is a
reference change summary email for each new commit, and all these
summaries do is point out that there is one new commit -- something that
is obvious from the existence of the individual revision email that is
also sent.  In such cases, users prefer there to be no push summary email.

Some examples where this is particularly important:

    Sadly, gerrit's review mechanism essentially enforces a workflow where
    every commit is submitted individually (things can be directly pushed
    if permissions are set up to allow it, but those pushes bypass the
    code review mechanisms).  Users can push several commits at once for
    review, but each commit is reviewed and submitted individually, and it
    is upon submit that gerrit merges the commit onto the real branch.
    This serialization means that gerrit's equivalent to the post-receive
    hook (named ref-updated) gets fired off for just a single new commit
    (well, two commits if you count the implicit merge commit created by
    gerrit, but users find emails about the implicit gerrit merge commits
    to be noise as well).

    Lots of people haven't weaned themselves from a cvs- or svn-like
    workflow may also push each commit individually.  For people who
    predominantly only push a single new commit, the push summary emails
    are just noise.

However, even in repositories where 98% of uses are one of the above,
there are still other folks that might sometimes do large merges between
branches, or push several commits at once, or potentially force update
some branches.  In all of these cases, the reference summary emails are
very useful and we still want them to be sent, so we do not want to just
turn off the reference summary emails on a repo-by-repo basis.  We instead
want to have them turned off just for the particular pushes for which
users deem them to be noise.

Signed-off-by: Elijah Newren <newren@palantir.com>
Allow sending emails only for a subset of refs

Many projects use a pull-request model with a central repository, where
new changes are pushed to branches named e.g. feature/whizbang.  However,
users really don't view these branches as "part of the repository" until
they are merged into a 'real' branch, such as master.  And lots of users
are very annoyed at getting email notifications for pushes to these
branches; they only want to be notified when some subset of branches are
updated.

There's a slight complication, though: traditionally git-multimail has
only sent out commit emails for commits that are entirely new to the
repository, but this doesn't play well with this filtering feature.  So,
we need to instead have git-multimail only send out commit emails for
commits that are entirely new to the *relevant subset of the* repository.

Add multimailhook.refFilterInclusionRegex and
multimailhook.refFilterExclusionRegex configuration options, with related
--ref-filter-inclusion-regex and --ref-filter-exclusion-regex command
line options, which can be used to configure which refs are considered
relevant.  Mark ^refs/notes/ as irrelevant by default as git-multimail
emails make no sense for git notes.

Signed-off-by: Elijah Newren <newren@palantir.com>
Atlassian Stash plugin: Expose ref filtering from the web UI

Signed-off-by: Elijah Newren <newren@palantir.com>
RFC: Silence loud error messages going to the error log

This is the wrong way to do this.  For plain git installations, or
gitolite installations, these messages are useful feedback sent to the
user when they do a push.  For stash, these messages are simply thrown
away.  For gerrit, they spam the error log.  There's no way I know of to
change stash or gerrit to send these to the user, and as they aren't
warnings or errors but are just informational, it's really annoying to
have these spam the error log.  Having a more reasonable way to turn
these messages off would be nice.

Signed-off-by: Elijah Newren <newren@palantir.com>