Написание git post-receive hook для работы с конкретной веткой - PullRequest
101 голосов
/ 08 сентября 2011

Вот мой текущий хук в голом репо, который живет на сервере компании: git push origin master Этот хук подталкивает к Ассембле.Что мне нужно, это нажать только одну ветку (в идеале master), когда кто-то передает изменения в эту ветку на нашем сервере, и игнорировать нажатия на другие ветви.Можно ли выбрать ветку из чистого репозитория и отправить только эту ветку в Assembla?

Ответы [ 7 ]

372 голосов
/ 25 октября 2012

Хук пост-получения получает свои аргументы от стандартного ввода в форме <oldrev> <newrev> <refname>. Поскольку эти аргументы поступают из стандартного ввода, а не из аргумента командной строки, вам нужно использовать read вместо $1 $2 $3.

Хук пост-получения может получать несколько веток одновременно (например, если кто-то делает git push --all), поэтому нам также нужно обернуть read в цикл while.

Рабочий фрагмент выглядит примерно так:

#!/bin/bash
while read oldrev newrev refname
do
    branch=$(git rev-parse --symbolic --abbrev-ref $refname)
    if [ "master" == "$branch" ]; then
        # Do something
    fi
done
8 голосов
/ 08 сентября 2011

Последний параметр, который хук после получения получает в stdin, это то, что ref был изменен, так что мы можем использовать его, чтобы проверить, было ли это значение "refs /head / master".Немного рубина, похожего на то, что я использую в хуке после получения:

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

Обратите внимание, что он получает строку для каждого реферала, который был выдвинут, так что если вы нажали больше, чем просто мастер, он все равно будетработа.

6 голосов
/ 11 сентября 2012

Ответ Стефана у меня не сработал, но этот сделал:

#!/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"
3 голосов
/ 21 ноября 2013

Ни одно из приведенных выше решений не помогло мне. После долгих отладок выясняется, что использование команды read не работает - вместо этого, синтаксический анализ аргументов командной строки работает нормально.

Вот точный хук после обновления, который я только что успешно протестировал на 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

ОБНОВЛЕНИЕ: на еще более странной ноте хук предварительного получения получает свой ввод через stdin, поэтому читается с «read» (вау, я никогда не думал, что скажу это). Хук после обновления все еще работает для меня за 1 доллар.

1 голос
/ 26 сентября 2017

Ответ от @pauljz прекрасно работает для некоторых хитов git, таких как pre-push, но pre-commit не имеет доступа к этим переменным oldrev newrev refname

Итак, я создал эту альтернативную версию, которая работает для предварительной фиксации, или на самом деле и ловушка. Это хук pre-commit, который запускает скрипт husky, если мы НЕ на ветке master.

#!/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

Надеюсь, это кому-нибудь поможет. Вы можете легко изменить в соответствии со своими потребностями все, что находится между операторами if и fi.

0 голосов
/ 03 декабря 2015

Простой подход, в git hook написать

read refname
echo $refname

Простой - больше информации по этой замечательной ссылке Система подключения

0 голосов
/ 01 декабря 2013

Я написал PHP-скрипт для себя, чтобы выполнить эту функцию.

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

Разместите этот файл на своем сервере, желательно, чтобы он был root, и определите URL в github webhooks. Замените «allcommits» в строке 8 на имя вашего филиала и добавьте свой код / ​​функцию в строке 18.

, например

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