Writing a git post-receive hook to deal with a specific branch

主宰稳场 提交于 2019-11-26 11:03:42

A post-receive hook gets its arguments from stdin, in the form <oldrev> <newrev> <refname>. Since these arguments are coming from stdin, not from a command line argument, you need to use read instead of $1 $2 $3.

The post-receive hook can receive multiple branches at once (for example if someone does a git push --all), so we also need to wrap the read in a while loop.

A working snippet looks something like this:

#!/bin/bash
while read oldrev newrev refname
do
    branch=$(git rev-parse --symbolic --abbrev-ref $refname)
    if [ "master" == "$branch" ]; then
        # Do something
    fi
done
ebneter

The last parameter that a post-receive hook gets on stdin is what ref was changed, so we can use that to check if that value was "refs/heads/master." A bit of ruby similar to what I use in a post-receive hook:

STDIN.each do |line|
    (old_rev, new_rev, ref_name) = line.split
    if ref_name =~ /master/
         # do your push
    end
end

Note that it gets a line for each ref that was pushed, so if you pushed more than just master, it will still work.

Stefan's answer didn't work for me, but this did:

#!/bin/bash

echo "determining branch"

if ! [ -t 0 ]; then
  read -a ref
fi

IFS='/' read -ra REF <<< "${ref[2]}"
branch="${REF[2]}"

if [ "master" == "$branch" ]; then
  echo 'master was pushed'
fi

if [ "staging" == "$branch" ]; then
  echo 'staging was pushed'
fi

echo "done"

Neither of the solutions above worked for me. After much, much debugging, it turns out that using the 'read' command doesn't work -- instead, parsing command line arguments the usual way works fine.

Here is the exact post-update hook that I just successfully tested now on CentOS 6.3.

#!/bin/bash

echo "determining branch"

branch=`echo $1 | cut -d/ -f3`

if [ "master" == "$branch" ]; then
    echo "master branch selected"
fi

if [ "staging" == "$branch" ]; then
    echo "staging branch selected"
fi

exec git update-server-info

UPDATE: on an even stranger note, the pre-receive hook takes its input via stdin, therefore read with 'read' (wow, never thought I'd say that). The post-update hook still works with $1 for me.

The answer from @pauljz works fine for certain git hooks like pre-push, but pre-commit does not have access to those variables oldrev newrev refname

So I created this alternate version which works for pre-commit, or really and hook. This is a pre-commit hook that will run a husky script if we're NOT on the master branch.

#!/bin/bash
# git 'commit' does not have access to these variables: oldrev newrev refname
# So get the branch name off the head

branchPath=$(git symbolic-ref -q HEAD) # Something like refs/heads/myBranchName
branch=${branchPath##*/}      # Get text behind the last / of the branch path

echo "Head: $branchPath";
echo "Current Branch: $branch";

if [ "master" != "$branch" ]; then

   # If we're NOT on the Master branch, then Do something
   # Original Pre-push script from husky 0.14.3

   command_exists () {
     command -v "$1" >/dev/null 2>&1
   }

   has_hook_script () {
     [ -f package.json ] && cat package.json | grep -q "\"$1\"[[:space:]]*:"
   }

   cd "frontend" # change to your project directory, if .git is a level higher

   # Check if precommit script is defined, skip if not
   has_hook_script precommit || exit 0

   # Node standard installation
   export PATH="$PATH:/c/Program Files/nodejs"

   # Check that npm exists
   command_exists npm || {
     echo >&2 "husky > can't find npm in PATH, skipping precommit script in package.json"
     exit 0
   }

   # Export Git hook params
   export GIT_PARAMS="$*"

   # Run npm script
   echo "husky > npm run -s precommit (node `node -v`)"
   echo

   npm run -s precommit || {
     echo
     echo "husky > pre-commit hook failed (add --no-verify to bypass)"
     exit 1
   }
fi

I hope that helps someone. You can easily modify for your needs, anything in between the if and fi statements.

I had written a PHP script for myself to do this functionality.

https://github.com/fotuzlab/githubdump-php

Host this file on your server, preferably repo root and define the url in github webhooks. Change 'allcommits' on line 8 with your branch name and add your code/function at line 18.

e.g.

function githubdump($payload_object) {
    // Write your code here.
    exec('git push origin master');
}

Simple approach, in git hook write

read refname
echo $refname

Simple - more info on this great link hooking system

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!