Skip processing Git changes in post-receive host that have already been processed

I have a post-receive git hook that retrieves all the revisions that were added during git push and does some processing on each of them (like sending email notifications). This works great except in cases of merging; eg:.

  • I make some commits on branch1, and then push branch1. Post-capture capture processes transactions correctly.
  • I merge branch1 into branch2, and then push branch2. The post-receive handler intercepts all merged transactions a second time.

How can i avoid this? The following is the beginning of my hook after receiving, when I retrieve the commits that need to be processed (at the end of $ COMMITS contains a list of commits to process).

#!/bin/sh

REPO_PATH=`pwd`
COMMITS=''

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# for each ref that was updated during the push
while read OLD_REV NEW_REV REF_NAME; do
  OLD_REV="`git rev-parse $OLD_REV`"
  NEW_REV="`git rev-parse $NEW_REV`"
  if expr "$OLD_REV" : '0*$' >/dev/null; then
    # if the branch was created, add all revisions in the new branch; skip tags
    if ! expr "$REF_NAME" : 'refs/tags/' >/dev/null; then
      REF_REV="`git rev-parse $REF_NAME`"
      REF_NAME="`git name-rev --name-only $REF_REV`"
      COMMITS="$COMMITS `git rev-list $REF_NAME | git name-rev --stdin | grep -G \($REF_NAME.*\) | awk '{ print $1 }' | tr '\n' ' '`"
    fi

  elif expr "$NEW_REV" : '0*$' >/dev/null; then
    # don't think branch deletes ever hit a post-receive hook, so we should never get here
    printf ''
  else
    # add any commits in this push
    COMMITS="$COMMITS `git rev-parse --not --all | grep -v $(git rev-parse $REF_NAME) | git rev-list --reverse --stdin $(git merge-base $OLD_REV $NEW_REV)..$NEW_REV | tr '\n' ' '`"
  fi
done
+3
4

$(prefix)/share/git-core/contrib/hooks/post-receive-email, , ( ) . git for-each-ref , , - , , :

if [ "$change_type" = create ]
then
    # Show all revisions exclusive to this (new) branch.
    revspec=$newrev
else
    # Branch update; show revisions not part of $oldrev.
    revspec=$oldrev..$newrev
fi

other_branches=$(git for-each-ref --format='%(refname)' refs/heads/ |
     grep -F -v $refname)
git rev-parse --not $other_branches | git rev-list --pretty --stdin $revspec

( , . : $change_type is create, $oldrev - , update; $oldrev - rev SHA1 , stdin; $newrev - rev SHA1, $refname - , refs/heads/topic.)

+6

, . , , , , . , , .

, , , , .

+1

, , ( ). , , "" . , , .

0

hook-post-receive. trac , , . TRAC_HEAD git , .

It is recommended that you run cat refs/heads/* > TRAC HEADin your directory .gitbefore enabling hook.

#!/bin/sh
#
# Reads and notifies trac of only new commits that have not yet been dealt with.
#
# The "post-receive" script is run after receive-pack has accepted a pack
# and the repository has been updated.  It is passed arguments in through
# stdin in the form
#  <oldrev> <newrev> <refname>
# For example:
#  aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
#

TRAC_PATH="/path/to/trac/env"

# Read the standard input
while read oldrev newrev refname ; do

        echo "Processing branch: $refname"

        # Read the last revisions for each branch from TRAC_HEAD
        exclusions=$(cat TRAC_HEAD | uniq |  sed -e 's/^/^/' -e 's/ / ^/g' | xargs echo)

        echo "Exclusion list: $exclusions"

        git rev-list --reverse $newrev $exclusions | while read rev ; do
                trac-admin $TRAC_PATH changeset added '(default)' $rev
                echo "Processed: $rev"
        done

        # Add to the exclusions file the latest revision from this branch
        echo $newrev >> TRAC_HEAD

done

# Update the TRAC_HEAD file
cat refs/heads/* > TRAC_HEAD
0
source

All Articles