+# --- Email (all stdout will be the email)
+(
+# Generate header
+cat <<-EOF
+From: $committer
+To: $recipients
+Subject: ${EMAILPREFIX}$projectdesc $refname_type, $short_refname now at $describe
+X-Git-Refname: $refname
+X-Git-Reftype: $refname_type
+X-Git-Oldrev: $oldrev
+X-Git-Newrev: $newrev
+
+Hello,
+
+This is an automated email from the git hooks/update script, it was
+generated because a ref change was pushed to the repository.
+
+Updating $refname_type, $short_refname,
+EOF
+
+case "$refname_type" in
+ "tracking branch"|branch)
+ if expr "$oldrev" : '0*$' >/dev/null
+ then
+ # If the old reference is "0000..0000" then this is a new branch
+ # and so oldrev is not valid
+ echo " as a new $refname_type"
+ echo " to $newrev ($newrev_type)"
+ echo ""
+ echo $LOGBEGIN
+ # This shows all log entries that are not already covered by
+ # another ref - i.e. commits that are now accessible from this
+ # ref that were previously not accessible
+ git-rev-list --pretty $newref $(git-rev-parse --not --all)
+ echo $LOGEND
+ else
+ # oldrev is valid
+ oldrev_type=$(git-cat-file -t "$oldrev")
+
+ # Now the problem is for cases like this:
+ # * --- * --- * --- * (oldrev)
+ # \
+ # * --- * --- * (newrev)
+ # i.e. there is no guarantee that newrev is a strict subset
+ # of oldrev - (would have required a force, but that's allowed).
+ # So, we can't simply say rev-list $oldrev..$newrev. Instead
+ # we find the common base of the two revs and list from there
+ baserev=$(git-merge-base $oldrev $newrev)
+
+ # Commit with a parent
+ for rev in $(git-rev-list $newrev ^$baserev)
+ do
+ revtype=$(git-cat-file -t "$rev")
+ echo " via $rev ($revtype)"
+ done
+ if [ "$baserev" = "$oldrev" ]; then
+ echo " from $oldrev ($oldrev_type)"
+ else
+ echo " based on $baserev"
+ echo " from $oldrev ($oldrev_type)"
+ echo ""
+ echo "This ref update crossed a branch point; i.e. the old rev is not a strict subset"
+ echo "of the new rev. This occurs, when you --force push a change in a situation"
+ echo "like this:"
+ echo ""
+ echo " * -- * -- B -- O -- O -- O ($oldrev)"
+ echo " \\"
+ echo " N -- N -- N ($newrev)"
+ echo ""
+ echo "Therefore, we assume that you've already had alert emails for all of the O"
+ echo "revisions, and now give you all the revisions in the N branch from the common"
+ echo "base, B ($baserev), up to the new revision."
+ fi
+ echo ""
+ echo $LOGBEGIN
+ git-rev-list --pretty $newrev ^$baserev
+ echo $LOGEND
+ echo ""
+ echo "Diffstat:"
+ git-diff-tree --no-color --stat -M -C --find-copies-harder $newrev ^$baserev
+ fi