Написание git post-receive для работы с конкретной веткой

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

7 ответов

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

Ловушка post-receive может получать несколько веток одновременно (например, если кто-то делает 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

Последний параметр, который хук после получения получает в 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

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

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

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

Ни одно из приведенных выше решений не помогло мне. После долгих отладок выясняется, что использование команды 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 долларом для меня.

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

Поэтому я создал эту альтернативную версию, которая работает для pre-commit, или на самом деле и hook. Это 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 заявления.

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

read refname
echo $refname

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

Я написал скрипт 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');
}
Другие вопросы по тегам