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

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

Ответ 1

Хук post-receive получает свои аргументы от stdin в форме <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

Ответ 2

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

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

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

Ответ 3

Ответ Stefan не работал у меня, но this сделал:

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

Ответ 4

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

ОБНОВЛЕНИЕ: на еще более незнакомой ноте крюк pre-receive принимает свой вход через stdin, поэтому читайте с помощью "read" (ничего себе, никогда не думал, что я скажу это). Ключ post-update по-прежнему работает с $1 для меня.

Ответ 5

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

Итак, я создал эту альтернативную версию, которая работает для pre-commit, или действительно, и зацепила. Это крюк pre-commit, который будет запускать husky script, если мы НЕ на ветке 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.

Ответ 6

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

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

Соберите этот файл на своем сервере, предпочтительно root репо и определите URL-адрес в веб-узлах github. Измените "allcommits" в строке 8 с именем вашей ветки и добавьте код/​​функцию в строку 18.

например.

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

Ответ 7

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

read refname
echo $refname

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