Change get_change() function into a static method ReferenceChange.create().
Record SHA1s rather than refnames in Push.other_refs.

SHA1s are more permanent, which can help if another push is
simultaneously changing some of the other references.
Explicitly include only tags and commits in commit computations.

Even though trees and blobs don't confuse "git rev-list", they aren't
helpful, either.  So only include branches and tags in the SHA1s
passed to "git rev-list" for computing the commits added or discarded
by a push.
Factor out some common code in Push.

* Extract a method Push._compute_rev_exclusion_spec()

* Use the new method to inline Push._compute_old_rev_exclusion_spec()
  and Push._compute_new_rev_exclusion_spec()

* Do not store other_refs as a member of Push, since it is unneeded
  after the constructor is done.

* Sort the SHA1s included in the output of
  Push._compute_rev_exclusion_spec() to make the results
  deterministic.
Improve comments.

Remove the big comment from
ReferenceChange.generate_revision_change_summary(), which was mostly
obsolete.  Instead, add a docstring for the Push class that explains
how it determines new/discarded commits.
Remove field Push.environment.

When it is needed, there is always a Change object around which also
knows the environment.
Add some tests of references in unusual namespaces.
Slightly improve the output for OtherReferenceChange.
Do not set pusher_email in the Environment constructor.

The derived classes should set it.
Add comment about the ConfigEnvironment recipient lists.

Document why it is OK for the ConfigEnvironment recipient lists to be
computed in the ConfigEnvironment constructor.
Inline read_updates() into run_as_post_receive_hook().