Обработка событий в GIT

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

 

Но все же лучше предотвращать попадание таких комитов в центральный репозиторий, нежели поспешно откатываться на предыдущую стабильную версию. Для реализации этой возможности в системе управления версиями GIT существуют хуки (hooks). Под катом приведен пример систем использующейся в одном из наших проектов.

Общее

В рамказ данной статьи рассмотрим “pre-receive“ хук. Он является наиболее интересным для нас, поскольку позволяет, при попытке разработчиком закомитить свои изменения, просмотреть их и отклонить, если не будет выполнятся какое-то из условий. Благодаря этому можно реализовать две простые, но очень полезные вещи:

  1. Проверка синтаксиса.
  2. Запрет комитита миграций БД, которые содержат в себе операции типа “ALTER”, “DELETE”, “DROP”, “TRUNCATE”.
Первое встечается не часто,но все же не приятно видеть проседания на графиках посещаемости вызванные банальными очепятками в коде.
Второе поможет нам уберечься от нежелательных изменений в нагруженных таблицах содержащих много данных (особенно важно для таблиц с несколькими десятками миллионами записей), которые могут привести к “залипанию” СУБД . И так, приступим.

Обработчик “pre-receive” события

Сам GIT позволяет для pre-recive события вызывать только один скрипт. Но нам ничего не мешает с этого скрипта вызывать другие, необходимые нам. Поместите данный скрипт в каталог с хуками.
Листинг “pre-receive хука:

#!/bin/sh

# Pre-receive hook executer

if [ -z “$GIT_DIR” ]; then

echo “Don’t run this script from the command line.” >&2

exit 1

fi

while read OLDREV NEWREV REFNAME ; do

for script in `find $PWD/hooks/pre-receive.d/ -perm -100 ! -type d`

do

$script “$OLDREV” “$NEWREV” “$REFNAME” || exit $?

done

done

exit 0

Проверка синтаксиса PHP

Далее создаем каталог pre-receive.d/ в папке с хуками, и в него помещаем нужные для нас скрипты. В данном случае – скрипт проверки синтаксиса PHP кода (php-syntax-check):

#!/bin/sh

# A pre-receive hook to disallow php syntax errors to be

# committed by running php -l (lint) on them.

EXT=”0″

NOREV=”0000000000000000000000000000000000000000″

OLDREV=$1

NEWREV=$2

REFNAME=$3

TMP_DT=$(mktemp /tmp/git.php-syntax-check.XXXXXX)

git diff-tree -r “$OLDREV” “$NEWREV” > $TMP_DT

while read old_mode new_mode old_sha1 new_sha1 status name

do

# Skip lines showing parent commit

if [ -z “$new_sha1” ]; then continue; fi

# Skip deletions

if [ “$new_sha1” = “$NOREV” ]; then continue; fi

# Check only .php files

if [ `echo $name | grep “\.php$” | wc -l` -ne 0 ]

then

CHK=`git cat-file blob $new_sha1 | /usr/local/bin/php -l`

RET=$?

if [ $RET -ne 0 ]

then

echo

echo “!!!! PUSH REJECTED !!!!”

echo

echo “Errors parsing $name.”

echo “LOL! Check your syntax.”

echo

EXT=”1″

fi

fi

done < $TMP_DT

rm -f $TMP_DT

exit “$EXT”

Проверка миграций mysql

И скрипт запрета накатывания нежелательных миграций (mysql-operations-check):

#!/bin/sh

# Pre-receive hook discarding DELETE, ALTER, DROP and TRUNCATE table migrations

EXT=”0″

NOREV=”0000000000000000000000000000000000000000″

OLDREV=$1

NEWREV=$2

REFNAME=$3

TMP_DT=$(mktemp /tmp/git.discard-alter-table.XXXXXX)

git diff-tree -r “$OLDREV” “$NEWREV” > $TMP_DT

while read old_mode new_mode old_sha1 new_sha1 status name

do

# Skip lines showing parent commit

if [ -z “$new_sha1” ]; then continue; fi

# Skip deletions

if [ “$new_sha1” = “$NOREV” ]; then continue; fi

# Check only .sql files

if [ `echo $name | grep “\.sql$” | wc -l` -ne 0 ]

then

if [ `git cat-file blob $new_sha1 | egrep -i “delete|alter|drop|truncate” | wc -l` -ne 0 ]

then

echo

echo “!!!! PUSH REJECTED !!!!”

echo

echo “DELETE, ALTER, DROP & TRUNCATE TABLE operations are not allowed.”

echo “Please contact system administrator.”

echo

EXT=”1″

fi

fi

done < $TMP_DT

rm -f $TMP_DT

exit “$EXT”

Источник

Leave a Reply