Allow the emailPrefix to be suppressed.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Define Config.__contains__().

This fixes a breakage in migrate-mailhook-config, which used to use

    old.has_key(name)

but was changed in 09d0d5b922 to use

    name in old

.

Reported-by: Azat Khuzhin <a3at.mail@gmail.com>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
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>
Fix formatting
Extract a method ReferenceChange.adds_single_commit()

This simplifies the code flow in Push.send_emails().
Return early from BranchChange.adds_single_commit() when possible
Avoid an error if old..new doesn't contain any commits
BranchChange.adds_single_commit: split lines as they are read
Add a test for a push including just a single commit

Signed-off-by: Elijah Newren <newren@palantir.com>
Update CHANGES file
Add infrastructure for sending a combined refchange/revision email

Instead of omitting refchange emails when only a single revision has been
pushed, we want to send a combined refchange/revision email.  This adds
some scaffolding to do so, though it currently still sends just the single
revision email.

Signed-off-by: Elijah Newren <newren@gmail.com>
ReferenceChange: Control template selection by class variables

Store the selection of header, intro, and footer templates in variables,
so that we can override the choice in the case where we want to send a
combined refchange/revision email.

Signed-off-by: Elijah Newren <newren@gmail.com>
Add templates for combined refchange/revision emails

This adds subject, header, intro, and footer templates which can be used
for combined emails.  The actual email body, for now, is simply the
standard ReferenceChange email body; this will be corrected in a subsequent
commit.

Signed-off-by: Elijah Newren <newren@gmail.com>
Add logic for handling combined refchange/revision email body

Signed-off-by: Elijah Newren <newren@gmail.com>
Do not combine refchange & revision emails if recipients differ

Signed-off-by: Elijah Newren <newren@gmail.com>
Avoid omitting merges with interesting non-trivial-merge changes

We try to combine refchange and revision emails if only one new revision
email was added in a push.  However, since many development teams have a
workflow of having all revisions uploaded to a review site (e.g. Gerrit
or Atlassian Stash) and then being merged in, the combined email should
really still be sent even if there is a merge commit on top -- users
generally see the merge made by these review tools as an uninteresting
implementational detail and often consider emails about them to be spam.

HOWEVER, if a merge commit is present and it doesn't represent a trivial
conflict-free merge (because its creation involved conflict resolutions or
had other interesting changes), then we absolutely do want a special email
about the merge commit.  Make sure it is sent by avoiding the combined
refchange/revision email codepath.

Signed-off-by: Elijah Newren <newren@gmail.com>
Update tests to handle combined refchange/revision email

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