{"thread":{"id":"7860","subject":"[PATCH 2/2] post-receive-email example hook: detect rewind-only updates and output sensible message","startedAt":"2007-04-26T21:36:24Z","lastAt":"2007-04-26T21:36:24Z","messageCount":1,"participants":["Andy Parkins"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"40542","messageId":"200704262236.24764.andyparkins@gmail.com","threadId":"7860","inReplyTo":null,"subject":"[PATCH 2/2] post-receive-email example hook: detect rewind-only updates and output sensible message","fromName":"Andy Parkins","fromEmail":"andyparkins@gmail.com","sentAt":"2007-04-26T21:36:24Z","receivedAt":"2007-04-26T21:36:24Z","isPatch":true,"sender":{"key":"andyparkins@gmail.com","avatar":null},"body":"Sometimes a non-fast-forward update doesn't add new commits, it merely\nremoves old commits.  This patch adds support for detecting that and\noutputting a more correct message.\n\nSigned-off-by: Andy Parkins <andyparkins@gmail.com>\n---\n contrib/hooks/post-receive-email |   77 ++++++++++++++++++++++++++-----------\n 1 files changed, 54 insertions(+), 23 deletions(-)\n\ndiff --git a/contrib/hooks/post-receive-email b/contrib/hooks/post-receive-email\nindex edb30f6..e175b42 100644\n--- a/contrib/hooks/post-receive-email\n+++ b/contrib/hooks/post-receive-email\n@@ -327,36 +327,67 @@ generate_update_branch_email()\n \tif [ -z \"$fastforward\" ]; then\n \t\techo \"      from  $oldrev ($oldrev_type)\"\n \telse\n+\t\t#  1. Existing revisions were removed.  In this case newrev is a\n+\t\t#     subset of oldrev - this is the reverse of a fast-forward,\n+\t\t#     a rewind\n+\t\t#  2. New revisions were added on top of an old revision, this is\n+\t\t#     a rewind and addition.\n+\n+\t\t# (1) certainly happened, (2) possibly.  When (2) hasn't happened,\n+\t\t# we set a flag to indicate that no log printout is required.\n+\n \t\techo \"\"\n-\t\techo \"This update added new revisions after undoing old revisions.  That is to\"\n-\t\techo \"say, the old revision is not a strict subset of the new revision.  This\"\n-\t\techo \"situation occurs when you --force push a change and generate a\"\n-\t\techo \"repository containing something like this:\"\n-\t\techo \"\"\n-\t\techo \" * -- * -- B -- O -- O -- O ($oldrev)\"\n-\t\techo \"            \\\\\"\n-\t\techo \"             N -- N -- N ($newrev)\"\n-\t\techo \"\"\n-\t\techo \"When this happens we assume that you've already had alert emails for all\"\n-\t\techo \"of the O revisions, and so we here report only the revisions in the N\"\n-\t\techo \"branch from the common base, B.\"\n+\n+\t\t# Find the common ancestor of the old and new revisions and compare\n+\t\t# it with newrev\n+\t\tbaserev=$(git merge-base $oldrev $newrev)\n+\t\trewind_only=\"\"\n+\t\tif [ \"$baserev\" = \"$newrev\" ]; then\n+\t\t\techo \"This update discarded existing revisions and left the branch pointing at\"\n+\t\t\techo \"a previous point in the repository history.\"\n+\t\t\techo \"\"\n+\t\t\techo \" * -- * -- N ($newrev)\"\n+\t\t\techo \"            \\\\\"\n+\t\t\techo \"             O -- O -- O ($oldrev)\"\n+\t\t\techo \"\"\n+\t\t\techo \"The removed revisions are not necessarilly gone - if another reference\"\n+\t\t\techo \"still refers to them they will stay in the repository.\"\n+\t\t\trewind_only=1\n+\t\telse\n+\t\t\techo \"This update added new revisions after undoing existing revisions.  That is\"\n+\t\t\techo \"to say, the old revision is not a strict subset of the new revision.  This\"\n+\t\t\techo \"situation occurs when you --force push a change and generate a repository\"\n+\t\t\techo \"containing something like this:\"\n+\t\t\techo \"\"\n+\t\t\techo \" * -- * -- B -- O -- O -- O ($oldrev)\"\n+\t\t\techo \"            \\\\\"\n+\t\t\techo \"             N -- N -- N ($newrev)\"\n+\t\t\techo \"\"\n+\t\t\techo \"When this happens we assume that you've already had alert emails for all\"\n+\t\t\techo \"of the O revisions, and so we here report only the revisions in the N\"\n+\t\t\techo \"branch from the common base, B.\"\n+\t\tfi\n \tfi\n \n \techo \"\"\n-\techo \"Those revisions listed above that are new to this repository have\"\n-\techo \"not appeared on any other notification email; so we list those\"\n-\techo \"revisions in full, below.\"\n+\tif [ -z \"$rewind_only\" ]; then\n+\t\techo \"Those revisions listed above that are new to this repository have\"\n+\t\techo \"not appeared on any other notification email; so we list those\"\n+\t\techo \"revisions in full, below.\"\n \n-\techo \"\"\n-\techo $LOGBEGIN\n-\tgit rev-parse --not --branches | grep -v $(git rev-parse $refname) |\n-\tgit rev-list --pretty --stdin $oldrev..$newrev\n+\t\techo \"\"\n+\t\techo $LOGBEGIN\n+\t\tgit rev-parse --not --branches | grep -v $(git rev-parse $refname) |\n+\t\tgit rev-list --pretty --stdin $oldrev..$newrev\n \n-\t# XXX: Need a way of detecting whether git rev-list actually outputted\n-\t# anything, so that we can issue a \"no new revisions added by this\n-\t# update\" message\n+\t\t# XXX: Need a way of detecting whether git rev-list actually outputted\n+\t\t# anything, so that we can issue a \"no new revisions added by this\n+\t\t# update\" message\n \n-\techo $LOGEND\n+\t\techo $LOGEND\n+\telse\n+\t\techo \"No new revisions were added by this update.\"\n+\tfi\n \n \t# The diffstat is shown from the old revision to the new revision.  This\n \t# is to show the truth of what happened in this change.  There's no point\n-- \n1.5.2.rc0.704.gfe85\n"}]}