X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=scripts%2Fpost-receive-email-with-diffs;h=7723e58dc3bf0cdee6f13e795f1eafa432398be0;hb=HEAD;hp=6f42e95d63b714de76a75b9ff221731937534434;hpb=c27766370f41b21bd4e7b0087efc5ca55a71c3ca;p=infrastructure.git diff --git a/scripts/post-receive-email-with-diffs b/scripts/post-receive-email-with-diffs index 6f42e95..7723e58 100755 --- a/scripts/post-receive-email-with-diffs +++ b/scripts/post-receive-email-with-diffs @@ -63,137 +63,147 @@ # generate_email() { - # --- Arguments - oldrev=$(git rev-parse $1) - newrev=$(git rev-parse $2) - refname="$3" - - # --- Interpret - # 0000->1234 (create) - # 1234->2345 (update) - # 2345->0000 (delete) - if expr "$oldrev" : '0*$' >/dev/null + # --- Arguments + oldrev=$(git rev-parse $1) + newrev=$(git rev-parse $2) + refname="$3" + + # --- Interpret + # 0000->1234 (create) + # 1234->2345 (update) + # 2345->0000 (delete) + if expr "$oldrev" : '0*$' >/dev/null + then + change_type="create" + else + if expr "$newrev" : '0*$' >/dev/null then - change_type="create" + change_type="delete" else - if expr "$newrev" : '0*$' >/dev/null - then - change_type="delete" - else - change_type="update" - fi + change_type="update" fi + fi - # --- Get the revision types - newrev_type=$(git cat-file -t $newrev 2> /dev/null) - oldrev_type=$(git cat-file -t "$oldrev" 2> /dev/null) - case "$change_type" in + # --- Get the revision types + newrev_type=$(git cat-file -t $newrev 2> /dev/null) + oldrev_type=$(git cat-file -t "$oldrev" 2> /dev/null) + case "$change_type" in create|update) - rev="$newrev" - rev_type="$newrev_type" - ;; + rev="$newrev" + rev_type="$newrev_type" + ;; delete) - rev="$oldrev" - rev_type="$oldrev_type" - ;; - esac - - # The revision type tells us what type the commit is, combined with - # the location of the ref we can decide between - # - working branch - # - tracking branch - # - unannoted tag - # - annotated tag - case "$refname","$rev_type" in - refs/tags/*,commit) - # un-annotated tag - refname_type="tag" - short_refname=${refname##refs/tags/} - ;; - refs/tags/*,tag) - # annotated tag - refname_type="annotated tag" - short_refname=${refname##refs/tags/} - # change recipients - if [ -n "$announcerecipients" ]; then - recipients="$announcerecipients" - fi - ;; - refs/heads/*,commit) - # branch - refname_type="branch" - short_refname=${refname##refs/heads/} - ;; - refs/remotes/*,commit) - # tracking branch - refname_type="tracking branch" - short_refname=${refname##refs/remotes/} - echo >&2 "*** Push-update of tracking branch, $refname" - echo >&2 "*** - no email generated." - exit 0 - ;; - *) - # Anything else (is there anything else?) - echo >&2 "*** Unknown type of update to $refname ($rev_type)" - echo >&2 "*** - no email generated" - exit 1 - ;; - esac - - # Check if we've got anyone to send to - if [ -z "$recipients" ]; then - case "$refname_type" in - "annotated tag") - config_name="hooks.announcelist" - ;; - *) - config_name="hooks.mailinglist" - ;; - esac - echo >&2 "*** $config_name is not set so no email will be sent" - echo >&2 "*** for $refname update $oldrev->$newrev" - exit 0 - fi - - # Email parameters - # The email subject will contain the best description of the ref - # that we can build from the parameters - describe=$(git describe $rev 2>/dev/null) - if [ -z "$describe" ]; then - describe=$rev - fi - - generate_email_header - - # Call the correct body generation function - fn_name=general + rev="$oldrev" + rev_type="$oldrev_type" + ;; + esac + + # The revision type tells us what type the commit is, combined with + # the location of the ref we can decide between + # - working branch + # - tracking branch + # - unannoted tag + # - annotated tag + case "$refname","$rev_type" in + refs/tags/*,commit) # un-annotated tag + refname_type="tag" + short_refname=${refname##refs/tags/} + ;; + refs/tags/*,tag) # annotated tag + refname_type="annotated tag" + short_refname=${refname##refs/tags/} + # change recipients + if [ -n "$announcerecipients" ]; then + recipients="$announcerecipients" + fi + ;; + refs/heads/*,commit) # branch + refname_type="branch" + short_refname=${refname##refs/heads/} + ;; + refs/remotes/*,commit) # tracking branch + refname_type="tracking branch" + short_refname=${refname##refs/remotes/} + echo >&2 "*** Push-update of tracking branch, $refname" + echo >&2 "*** - no email generated." + exit 0 + ;; + *) # Anything else (is there anything else?) + echo >&2 "*** Unknown type of update to $refname ($rev_type)" + echo >&2 "*** - no email generated" + exit 1 + ;; + esac + + # Check if we've got anyone to send to + if [ -z "$recipients" ]; then case "$refname_type" in - "tracking branch"|branch) - fn_name=branch + "annotated tag") + config_name="hooks.announcelist" ;; - "annotated tag") - fn_name=atag + *) + config_name="hooks.mailinglist" ;; esac - generate_${change_type}_${fn_name}_email + echo >&2 "*** $config_name is not set so no email will be sent" + echo >&2 "*** for $refname update $oldrev->$newrev" + exit 0 + fi + + # Email parameters + # The email subject will contain the best description of the ref + # that we can build from the parameters + describe=$(git describe $rev 2>/dev/null) + if [ -z "$describe" ]; then + describe=$rev + fi + + generate_email_header + + # Call the correct body generation function + fn_name=general + case "$refname_type" in + "tracking branch"|branch) + fn_name=branch + ;; + "annotated tag") + fn_name=atag + ;; + esac + generate_${change_type}_${fn_name}_email - generate_email_footer + generate_email_footer +} + +# generate a pattern for testing if a string is a hash +hpat="";__=1; while [ $__ -le 40 ] ; do hpat=${hpat}'[0-9a-f]';__=$(($__+1)); done +function is_hash () { + local hash + hash=$1; shift + case $hash in $hpat) return 0;; *) return 1;; esac } generate_email_header() { - # --- Email (all stdout will be the email) - # optimize output for branch, master - local details - if [ "$refname_type" == branch -a "$short_refname" == master ] ; then - details="" - else - details="$refname_type, $short_refname," - fi - local shortrev - shortrev=$(echo $describe | cut -b1-8) - # Generate header - cat <<-EOF + # --- Email (all stdout will be the email) + # optimize output for branch, master + local details + if [ "$refname_type" == branch -a "$short_refname" == master ] ; then + details="" + else + details="$refname_type, $short_refname," + fi + # trying to improve the layout of $describe + # in some cases we get a plain hash, some other times we're getting a composite like + # TagName-NumOfCommitsAfterTag-Hash + # simple first idea: if it looks like a plain hash, truncate it, + # otherwise preserve as-is for now + local shortrev +# shortrev=$(awk -F - '{print $NF;}' <<< $describe) + shortrev=$describe + is_hash $shortrev && shortrev="$(cut -b1-8 <<< $shortrev).." + # Generate header + cat <<-EOF To: $recipients Subject: ${emailprefix}$projectdesc ${details}${change_type}d. ${shortrev} X-Git-Refname: $refname @@ -207,7 +217,7 @@ On $projectdesc, the $refname_type, $short_refname has been ${change_type}d generate_email_footer() { - cat <<-EOF + cat <<-EOF hooks/post-receive @@ -223,19 +233,19 @@ generate_email_footer() # generate_create_branch_email() { - # This is a new branch and so oldrev is not valid - echo " at $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 - # (see generate_update_branch_email for the explanation of this - # command) - git rev-parse --not --branches | grep -v $(git rev-parse $refname) | - git rev-list --pretty --stdin $newrev - echo $LOGEND + # This is a new branch and so oldrev is not valid + echo " at $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 + # (see generate_update_branch_email for the explanation of this + # command) + git rev-parse --not --branches | grep -v $(git rev-parse $refname) | + git rev-list --pretty --stdin $newrev + echo $LOGEND } # @@ -243,179 +253,178 @@ generate_create_branch_email() # generate_update_branch_email() { - # Consider this: - # 1 --- 2 --- O --- X --- 3 --- 4 --- N - # - # O is $oldrev for $refname - # N is $newrev for $refname - # X is a revision pointed to by some other ref, for which we may - # assume that an email has already been generated. - # In this case we want to issue an email containing only revisions - # 3, 4, and N. Given (almost) by - # - # git rev-list N ^O --not --all - # - # The reason for the "almost", is that the "--not --all" will take - # precedence over the "N", and effectively will translate to - # - # git rev-list N ^O ^X ^N - # - # So, we need to build up the list more carefully. git rev-parse - # will generate a list of revs that may be fed into git rev-list. - # We can get it to make the "--not --all" part and then filter out - # the "^N" with: - # - # git rev-parse --not --all | grep -v N - # - # Then, using the --stdin switch to git rev-list we have effectively - # manufactured - # - # git rev-list N ^O ^X - # - # This leaves a problem when someone else updates the repository - # while this script is running. Their new value of the ref we're - # working on would be included in the "--not --all" output; and as - # our $newrev would be an ancestor of that commit, it would exclude - # all of our commits. What we really want is to exclude the current - # value of $refname from the --not list, rather than N itself. So: - # - # git rev-parse --not --all | grep -v $(git rev-parse $refname) - # - # Get's us to something pretty safe (apart from the small time - # between refname being read, and git rev-parse running - for that, - # I give up) - # - # - # Next problem, consider this: - # * --- B --- * --- O ($oldrev) - # \ - # * --- X --- * --- N ($newrev) - # - # That is to say, there is no guarantee that oldrev is a strict - # subset of newrev (it 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. - # - # As above, we need to take into account the presence of X; if - # another branch is already in the repository and points at some of - # the revisions that we are about to output - we don't want them. - # The solution is as before: git rev-parse output filtered. - # - # Finally, tags: 1 --- 2 --- O --- T --- 3 --- 4 --- N - # - # Tags pushed into the repository generate nice shortlog emails that - # summarise the commits between them and the previous tag. However, - # those emails don't include the full commit messages that we output - # for a branch update. Therefore we still want to output revisions - # that have been output on a tag email. - # - # Luckily, git rev-parse includes just the tool. Instead of using - # "--all" we use "--branches"; this has the added benefit that - # "remotes/" will be ignored as well. - - # List all of the revisions that were removed by this update, in a - # fast forward update, this list will be empty, because rev-list O - # ^N is empty. For a non fast forward, O ^N is the list of removed - # revisions - fast_forward="" - rev="" - for rev in $(git rev-list $newrev..$oldrev) - do - revtype=$(git cat-file -t "$rev") - echo " discards $rev ($revtype)" - done - if [ -z "$rev" ]; then - fast_forward=1 - fi - - # List all the revisions from baserev to newrev in a kind of - # "table-of-contents"; note this list can include revisions that - # have already had notification emails and is present to show the - # full detail of the change from rolling back the old revision to - # the base revision and then forward to the new revision - for rev in $(git rev-list $oldrev..$newrev) - do - revtype=$(git cat-file -t "$rev") - echo " via $rev ($revtype)" - done - - if [ "$fast_forward" ]; then - echo " from $oldrev ($oldrev_type)" - else - # 1. Existing revisions were removed. In this case newrev - # is a subset of oldrev - this is the reverse of a - # fast-forward, a rewind - # 2. New revisions were added on top of an old revision, - # this is a rewind and addition. - - # (1) certainly happened, (2) possibly. When (2) hasn't - # happened, we set a flag to indicate that no log printout - # is required. - - echo "" - - # Find the common ancestor of the old and new revisions and - # compare it with newrev - baserev=$(git merge-base $oldrev $newrev) - rewind_only="" - if [ "$baserev" = "$newrev" ]; then - echo "This update discarded existing revisions and left the branch pointing at" - echo "a previous point in the repository history." - echo "" - echo " * -- * -- N ($newrev)" - echo " \\" - echo " O -- O -- O ($oldrev)" - echo "" - echo "The removed revisions are not necessarilly gone - if another reference" - echo "still refers to them they will stay in the repository." - rewind_only=1 - else - echo "This update added new revisions after undoing existing revisions. That is" - echo "to say, the old revision is not a strict subset of the new revision. This" - echo "situation occurs when you --force push a change and generate a repository" - echo "containing something like this:" - echo "" - echo " * -- * -- B -- O -- O -- O ($oldrev)" - echo " \\" - echo " N -- N -- N ($newrev)" - echo "" - echo "When this happens we assume that you've already had alert emails for all" - echo "of the O revisions, and so we here report only the revisions in the N" - echo "branch from the common base, B." - fi - fi + # Consider this: + # 1 --- 2 --- O --- X --- 3 --- 4 --- N + # + # O is $oldrev for $refname + # N is $newrev for $refname + # X is a revision pointed to by some other ref, for which we may + # assume that an email has already been generated. + # In this case we want to issue an email containing only revisions + # 3, 4, and N. Given (almost) by + # + # git rev-list N ^O --not --all + # + # The reason for the "almost", is that the "--not --all" will take + # precedence over the "N", and effectively will translate to + # + # git rev-list N ^O ^X ^N + # + # So, we need to build up the list more carefully. git rev-parse + # will generate a list of revs that may be fed into git rev-list. + # We can get it to make the "--not --all" part and then filter out + # the "^N" with: + # + # git rev-parse --not --all | grep -v N + # + # Then, using the --stdin switch to git rev-list we have effectively + # manufactured + # + # git rev-list N ^O ^X + # + # This leaves a problem when someone else updates the repository + # while this script is running. Their new value of the ref we're + # working on would be included in the "--not --all" output; and as + # our $newrev would be an ancestor of that commit, it would exclude + # all of our commits. What we really want is to exclude the current + # value of $refname from the --not list, rather than N itself. So: + # + # git rev-parse --not --all | grep -v $(git rev-parse $refname) + # + # Get's us to something pretty safe (apart from the small time + # between refname being read, and git rev-parse running - for that, + # I give up) + # + # + # Next problem, consider this: + # * --- B --- * --- O ($oldrev) + # \ + # * --- X --- * --- N ($newrev) + # + # That is to say, there is no guarantee that oldrev is a strict + # subset of newrev (it 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. + # + # As above, we need to take into account the presence of X; if + # another branch is already in the repository and points at some of + # the revisions that we are about to output - we don't want them. + # The solution is as before: git rev-parse output filtered. + # + # Finally, tags: 1 --- 2 --- O --- T --- 3 --- 4 --- N + # + # Tags pushed into the repository generate nice shortlog emails that + # summarise the commits between them and the previous tag. However, + # those emails don't include the full commit messages that we output + # for a branch update. Therefore we still want to output revisions + # that have been output on a tag email. + # + # Luckily, git rev-parse includes just the tool. Instead of using + # "--all" we use "--branches"; this has the added benefit that + # "remotes/" will be ignored as well. + + # List all of the revisions that were removed by this update, in a + # fast forward update, this list will be empty, because rev-list O + # ^N is empty. For a non fast forward, O ^N is the list of removed + # revisions + fast_forward="" + rev="" + for rev in $(git rev-list $newrev..$oldrev) + do + revtype=$(git cat-file -t "$rev") + echo " discards $rev ($revtype)" + done + if [ -z "$rev" ]; then + fast_forward=1 + fi + + # List all the revisions from baserev to newrev in a kind of + # "table-of-contents"; note this list can include revisions that + # have already had notification emails and is present to show the + # full detail of the change from rolling back the old revision to + # the base revision and then forward to the new revision + for rev in $(git rev-list $oldrev..$newrev) + do + revtype=$(git cat-file -t "$rev") + echo " via $rev ($revtype)" + done + + if [ "$fast_forward" ]; then + echo " from $oldrev ($oldrev_type)" + else + # 1. Existing revisions were removed. In this case newrev + # is a subset of oldrev - this is the reverse of a + # fast-forward, a rewind + # 2. New revisions were added on top of an old revision, + # this is a rewind and addition. + # (1) certainly happened, (2) possibly. When (2) hasn't + # happened, we set a flag to indicate that no log printout + # is required. echo "" - if [ -z "$rewind_only" ]; then - echo "" - echo $LOGBEGIN - git rev-parse --not --branches | grep -v $(git rev-parse $refname) | - git rev-list --pretty --stdin $oldrev..$newrev - - # XXX: Need a way of detecting whether git rev-list actually - # outputted anything, so that we can issue a "no new - # revisions added by this update" message - echo $LOGEND + # Find the common ancestor of the old and new revisions and + # compare it with newrev + baserev=$(git merge-base $oldrev $newrev) + rewind_only="" + if [ "$baserev" = "$newrev" ]; then + echo "This update discarded existing revisions and left the branch pointing at" + echo "a previous point in the repository history." + echo "" + echo " * -- * -- N ($newrev)" + echo " \\" + echo " O -- O -- O ($oldrev)" + echo "" + echo "The removed revisions are not necessarilly gone - if another reference" + echo "still refers to them they will stay in the repository." + rewind_only=1 else - echo "No new revisions were added by this update." + echo "This update added new revisions after undoing existing revisions. That is" + echo "to say, the old revision is not a strict subset of the new revision. This" + echo "situation occurs when you --force push a change and generate a repository" + echo "containing something like this:" + echo "" + echo " * -- * -- B -- O -- O -- O ($oldrev)" + echo " \\" + echo " N -- N -- N ($newrev)" + echo "" + echo "When this happens we assume that you've already had alert emails for all" + echo "of the O revisions, and so we here report only the revisions in the N" + echo "branch from the common base, B." fi + fi - # The diffstat is shown from the old revision to the new revision. - # This is to show the truth of what happened in this change. - # There's no point showing the stat from the base to the new - # revision because the base is effectively a random revision at this - # point - the user will be interested in what this revision changed - # - including the undoing of previous revisions in the case of - # non-fast forward updates. + echo "" + if [ -z "$rewind_only" ]; then echo "" - echo "Summary of changes:" - git diff-tree --stat --summary --find-copies-harder $oldrev..$newrev - echo - echo - echo "Changes between commits $(cut -b1-8 <<< $oldrev)..$(cut -b1-8 <<< $newrev)" - git diff $oldrev..$newrev + echo $LOGBEGIN + git rev-parse --not --branches | grep -v $(git rev-parse $refname) | + git rev-list --pretty --stdin $oldrev..$newrev + + # XXX: Need a way of detecting whether git rev-list actually + # outputted anything, so that we can issue a "no new + # revisions added by this update" message + + echo $LOGEND + else + echo "No new revisions were added by this update." + fi + + # The diffstat is shown from the old revision to the new revision. + # This is to show the truth of what happened in this change. + # There's no point showing the stat from the base to the new + # revision because the base is effectively a random revision at this + # point - the user will be interested in what this revision changed + # - including the undoing of previous revisions in the case of + # non-fast forward updates. + echo "" + echo "Summary of changes:" + git diff-tree --stat --summary --find-copies-harder $oldrev..$newrev + echo + echo + echo "Changes between commits $(cut -b1-8 <<< $oldrev)..$(cut -b1-8 <<< $newrev)" + git diff $oldrev..$newrev } # @@ -423,11 +432,11 @@ generate_update_branch_email() # generate_delete_branch_email() { - echo " was $oldrev" - echo "" - echo $LOGEND - git show -s --pretty=oneline $oldrev - echo $LOGEND + echo " was $oldrev" + echo "" + echo $LOGEND + git show -s --pretty=oneline $oldrev + echo $LOGEND } # --------------- Annotated tags @@ -437,9 +446,9 @@ generate_delete_branch_email() # generate_create_atag_email() { - echo " at $newrev ($newrev_type)" + echo " at $newrev ($newrev_type)" - generate_atag_email + generate_atag_email } # @@ -448,10 +457,10 @@ generate_create_atag_email() # generate_update_atag_email() { - echo " to $newrev ($newrev_type)" - echo " from $oldrev (which is now obsolete)" + echo " to $newrev ($newrev_type)" + echo " from $oldrev (which is now obsolete)" - generate_atag_email + generate_atag_email } # @@ -459,63 +468,60 @@ generate_update_atag_email() # generate_atag_email() { - # Use git for-each-ref to pull out the individual fields from the - # tag - eval $(git for-each-ref --shell --format=' + # Use git for-each-ref to pull out the individual fields from the tag + eval $(git for-each-ref --shell --format=' tagobject=%(*objectname) tagtype=%(*objecttype) tagger=%(taggername) tagged=%(taggerdate)' $refname - ) + ) - echo " tagging $tagobject ($tagtype)" - case "$tagtype" in + echo " tagging $tagobject ($tagtype)" + case "$tagtype" in commit) - # If the tagged object is a commit, then we assume this is a - # release, and so we calculate which tag this tag is - # replacing - prevtag=$(git describe --abbrev=0 $newrev^ 2>/dev/null) + # If the tagged object is a commit, then we assume this is a + # release, and so we calculate which tag this tag is + # replacing + prevtag=$(git describe --abbrev=0 $newrev^ 2>/dev/null) - if [ -n "$prevtag" ]; then - echo " replaces $prevtag" - fi - ;; + if [ -n "$prevtag" ]; then + echo " replaces $prevtag" + fi + ;; *) - echo " length $(git cat-file -s $tagobject) bytes" - ;; - esac - echo " tagged by $tagger" - echo " on $tagged" + echo " length $(git cat-file -s $tagobject) bytes" + ;; + esac + echo " tagged by $tagger" + echo " on $tagged" - echo "" - echo $LOGBEGIN + echo "" + echo $LOGBEGIN - # Show the content of the tag message; this might contain a change - # log or release notes so is worth displaying. - git cat-file tag $newrev | sed -e '1,/^$/d' + # Show the content of the tag message; this might contain a change + # log or release notes so is worth displaying. + git cat-file tag $newrev | sed -e '1,/^$/d' - echo "" - case "$tagtype" in + echo "" + case "$tagtype" in commit) - # Only commit tags make sense to have rev-list operations - # performed on them - if [ -n "$prevtag" ]; then - # Show changes since the previous release - git rev-list --pretty=short "$prevtag..$newrev" | git shortlog - else - # No previous tag, show all the changes since time - # began - git rev-list --pretty=short $newrev | git shortlog - fi - ;; + # Only commit tags make sense to have rev-list operations + # performed on them + if [ -n "$prevtag" ]; then + # Show changes since the previous release + git rev-list --pretty=short "$prevtag..$newrev" | git shortlog + else + # No previous tag, show all the changes since time began + git rev-list --pretty=short $newrev | git shortlog + fi + ;; *) - # XXX: Is there anything useful we can do for non-commit - # objects? - ;; - esac + # XXX: Is there anything useful we can do for non-commit objects? + ;; + esac - echo $LOGEND + echo $LOGEND } # @@ -523,11 +529,11 @@ generate_atag_email() # generate_delete_atag_email() { - echo " was $oldrev" - echo "" - echo $LOGEND - git show -s --pretty=oneline $oldrev - echo $LOGEND + echo " was $oldrev" + echo "" + echo $LOGEND + git show -s --pretty=oneline $oldrev + echo $LOGEND } # --------------- General references @@ -538,9 +544,9 @@ generate_delete_atag_email() # generate_create_general_email() { - echo " at $newrev ($newrev_type)" + echo " at $newrev ($newrev_type)" - generate_general_email + generate_general_email } # @@ -549,10 +555,10 @@ generate_create_general_email() # generate_update_general_email() { - echo " to $newrev ($newrev_type)" - echo " from $oldrev" + echo " to $newrev ($newrev_type)" + echo " from $oldrev" - generate_general_email + generate_general_email } # @@ -560,27 +566,27 @@ generate_update_general_email() # generate_general_email() { - # Unannotated tags are more about marking a point than releasing a - # version; therefore we don't do the shortlog summary that we do for - # annotated tags above - we simply show that the point has been - # marked, and print the log message for the marked point for - # reference purposes - # - # Note this section also catches any other reference type (although - # there aren't any) and deals with them in the same way. - - echo "" - if [ "$newrev_type" = "commit" ]; then - echo $LOGBEGIN - git show --no-color --root -s $newrev - echo $LOGEND - else - # What can we do here? The tag marks an object that is not - # a commit, so there is no log for us to display. It's - # probably not wise to output git cat-file as it could be a - # binary blob. We'll just say how big it is - echo "$newrev is a $newrev_type, and is $(git cat-file -s $newrev) bytes long." - fi + # Unannotated tags are more about marking a point than releasing a + # version; therefore we don't do the shortlog summary that we do for + # annotated tags above - we simply show that the point has been + # marked, and print the log message for the marked point for + # reference purposes + # + # Note this section also catches any other reference type (although + # there aren't any) and deals with them in the same way. + + echo "" + if [ "$newrev_type" = "commit" ]; then + echo $LOGBEGIN + git show --no-color --root -s $newrev + echo $LOGEND + else + # What can we do here? The tag marks an object that is not + # a commit, so there is no log for us to display. It's + # probably not wise to output git cat-file as it could be a + # binary blob. We'll just say how big it is + echo "$newrev is a $newrev_type, and is $(git cat-file -s $newrev) bytes long." + fi } # @@ -588,19 +594,23 @@ generate_general_email() # generate_delete_general_email() { - echo " was $oldrev" - echo "" - echo $LOGEND - git show -s --pretty=oneline $oldrev - echo $LOGEND + echo " was $oldrev" + echo "" + echo $LOGEND + git show -s --pretty=oneline $oldrev + echo $LOGEND } send_mail() { - COMMITTER=$(git-for-each-ref --format='%(committer)' --sort=-committerdate count=1 refs/heads) - COMMITTERNAME=$(cut -d'<' -f1 <<< $COMMITTER) + COMMITTER=$(git-for-each-ref --format='%(committer)' --sort=-committerdate count=1 refs/heads) + COMMITTERNAME=$(cut -d'<' -f1 <<< $COMMITTER) + if [ -n "$envelopesender" ] ; then + COMMITTERMAIL=$envelopesender + else COMMITTERMAIL=$(cut -d'<' -f2 <<< $COMMITTER |cut -d'>' -f1) - /usr/sbin/sendmail -t -f "$COMMITTERMAIL" -F "$COMMITTERNAME" + fi + /usr/sbin/sendmail -t -f "$COMMITTERMAIL" -F "$COMMITTERNAME" } # ---------------------------- main() @@ -614,20 +624,20 @@ LOGEND="-----------------------------------------------------------------------" # variable. GIT_DIR=$(git rev-parse --git-dir 2>/dev/null) if [ -z "$GIT_DIR" ]; then - echo >&2 "fatal: post-receive: GIT_DIR not set" - exit 1 + echo >&2 "fatal: post-receive: GIT_DIR not set" + exit 1 fi if [ -f "$GIT_DIR/description" ]; then - projectdesc=$(sed -ne '1p' "$GIT_DIR/description") + projectdesc=$(sed -ne '1p' "$GIT_DIR/description") else - projectdesc=$(git-config gitweb.description) + projectdesc=$(git-config gitweb.description) fi # Check if the description is unchanged from it's default, and shorten it to # a more manageable length if it is if expr "$projectdesc" : "Unnamed repository.*$" >/dev/null then - projectdesc="UNNAMED PROJECT" + projectdesc="UNNAMED PROJECT" fi recipients=$(git config hooks.mailinglist) @@ -639,13 +649,13 @@ emailprefix=$(git config hooks.emailprefix || echo '[SCM] ') # Allow dual mode: run from the command line just like the update hook, or # if no arguments are given then run as a hook script if [ -n "$1" -a -n "$2" -a -n "$3" ]; then - # Output to the terminal in command line mode - if someone wanted to - # resend an email; they could redirect the output to sendmail - # themselves - PAGER= generate_email $2 $3 $1 + # Output to the terminal in command line mode - if someone wanted to + # resend an email; they could redirect the output to sendmail + # themselves + PAGER= generate_email $2 $3 $1 else - while read oldrev newrev refname - do - generate_email $oldrev $newrev $refname | send_mail - done + while read oldrev newrev refname + do + generate_email $oldrev $newrev $refname | send_mail + done fi