Хуки Git

Хуки это короткие скрипты которые вы можете разместить в директории $GIT_DIR/hooks и которые будут запускаться по определенному событию. Когда выполняется git-init, то набор хуков идущих в комплекте с git копируется в директорию hooks нового репозитория, но по умолчанию они деактивированы. Чтобы активировать хуки, их следует переименовать, удалив их расширение .sample.

applypatch-msg

GIT_DIR/hooks/applypatch-msg

Этот хук вызывается скриптом git-am. Он принимает единственный параметр - имя файла, который содержит лог сообщение коммита. Выход с ненулевым статусом прерывает процесс выполнения команды git-am до наложения патча.

Хуку разрешается редактировать файл сообщение, и он может быть использован чтобы составить сообщение в особом формате, стандартном для проекта(если таковой формат имеется). Он также может быть использован чтобы отказаться от коммита после проверки файла сообщения. Хук по умолчанию applypatch-msg, когда разблокирован, запускает хук commit-msg, если последний разблокирован.

pre-applypatch

GIT_DIR/hooks/pre-applypatch

Этот хук вызывается git-am. Он не берет аргументы, и вызывается после того как патч уже наложен, но до того как будет выполнен коммит. Если он завершается с ненулевым статусом, тогда коммит рабочего дерева не будет выполнен после наложения патча.

Он может быть использован для проверки текущего рабочего дерева и может отказать в выполнении коммита если оно не пройдет определенные тесты. По умолчанию pre-applypatch хук, когда разблокирован, выполняет хук pre-commit, если последний разблокирован.

post-applypatch

GIT_DIR/hooks/post-applypatch

Этот хук вызывается 'git-am'. Он не берет параметров, и вызывается после того как наложен патч и выполнен коммит.

Назначение хука главным образом уведомление, и не может влиять на последствия выполнения 'git-am'.

pre-commit

GIT_DIR/hooks/pre-commit

Этот хук вызывается 'git-commit', и его вызов может быть отменен с помощью параметра \--no-verify. Он не берет параметров, и активируется до получения предложения лог-сообщения коммита и выполнения коммита. Завершение скрипта с ненулевым статусом прервет выполнение 'git-commit'.

Дефолтовый 'pre-commit' хук, когда разблокирован, ловит ввод строк с пробелами в окончании и прерывает коммит когда такая строка найдена.

Все хуки 'git-commit' вызываются с переменной окружения GIT_EDITOR=: если команда не вызывает редактор чтобы модифицировать сообщение-описпние коммита.

Здесь пример Ruby скрипта который выполняет тесты RSpec перед тем как позволить выполнить коммит.

  
html_path = "spec_results.html"  
`spec -f h:#{html_path} -f p spec` # run the spec. send progress to screen. save html results to html_path  

# find out how many errors were found  
html = open(html_path).read  
examples = html.match(/(\d+) examples/)[0].to_i rescue 0  
failures = html.match(/(\d+) failures/)[0].to_i rescue 0  
pending = html.match(/(\d+) pending/)[0].to_i rescue 0  

if failures.zero?  
  puts "0 failures! #{examples} run, #{pending} pending"  
else  
  puts "\aDID NOT COMMIT YOUR FILES!"  
  puts "View spec results at #{File.expand_path(html_path)}"  
  puts  
  puts "#{failures} failures! #{examples} run, #{pending} pending"  
  exit 1  
end

prepare-commit-msg

GIT_DIR/hooks/prepare-commit-msg

Этот хук активируется 'git-commit' сразу после подготовки дефолтного лога сообщения, и перед тем как откроется редактор.

Он берет от одного до трех параметров. Первый это имя файла содержащего сообщение-описание коммита. Второй источник сообщения коммита, и может быть: 'message' (если параметри -m или -F был передан ); template (если параметр -t был передан или установлен параметр настройки commit.template); merge (если коммит это слияние или существует файл .git/MERGE_MSG); squash (если существует файл .git/SQUASH_MSG); или commit, со следующим за ним SHA1 значением коммита (если передан параметр -c, -C или \--ammend)..

Если статус окончания работы ненулевой, выполнение 'git-commit' прервется.

Цель хука отредактировать файл сообщение на месте, и это не подавляется передачей параметра \--no-verify. Ненулевой статус окончания выполнения означает сбой хука и прерывание коммита. Он не должен быть использован как замена хука pre-commit.

Образец хука prepare-commit-msg который поставляется с комментариями git вне части Conflicts: сообщения описания коммита слияния.

commit-msg

GIT_DIR/hooks/commit-msg

Этот хук вызывается 'git-commit', и может быть обойден с помощью параметра \--no-verify. Он берет единственный параметр, имя файла который содержит предполагаемое сообщение описание коммита. Выход с ненулевым статусом прерывает выполнение 'git-commit'.

Этому хуку позоволяется редактировать файл сообщение на месте, и он может быть испльзован чтобы привести сообщение в стандартный вид для проекта(если таковой имеется). Он также может быть использован чтобы отказаться от коммита после проверки файла сообщения.

Хук по умолчания 'commit-msg', когда активирован, определяет дубликаты строк "Signed-off-by", и прерывает коммит если найдет таковую.

post-commit

GIT_DIR/hooks/post-commit

Этот хук вызывается 'git-commit'. Он не берет параметров, о вызывается после того как коммит уже завершен.

Назначение этого хука главным образом уведомление, и он не может повлиять на результат работы 'git-commit'.

pre-rebase

GIT_DIR/hooks/pre-rebase

Этот хук вызывается 'git-rebase' и может быть использован чтобы предотвратить выполнение операции ребазирования в ветке.

post-checkout

GIT_DIR/hooks/post-checkout

Этот хук вызывается когда 'git-checkout' выполняется после обновления рабочего дерева. Хук требуется три параметра: ссылка на предыдущую HEAD, ссылка на новую HEAD (которая возможно была изменена а возможно и нет), и флаг показывающий была ли операция checkout с веткой (смена ветки, flag=1) или она была проведена над файлом (получение файла из индекса, flag=0). Этот хук не может повлиять на результат 'git-checkout'.

Этот хук может быть использован чтобы выполнять проверки правильности репозитория валидность, автоматический показ отличий от предыдущей HEAD если отличается, или набор свойств метаданных рабочей директории.

post-merge

GIT_DIR/hooks/post-merge

Этот хук вызывается 'git-merge', что происходит когда 'git-pull' закончил свою работу в локальном репозитории. Хук берет единственный аргумент, флаг статуса определяющий было или нет выполненное слияние squash слиянием. Этот хук не может влиять на результат 'git-merge' и не выполняется если слияние потерпело неудачу вследствии конфликтов.

Этот хук может быть использован совместно с соотвествующим хуком pre-commit чтобы сохранять и восстанавливать метаданные ассоциированные с рабочим деревом в любой форме (в т.ч. разрешения/владение, ACLS и т.д.) Просмотрите contrib/hooks/setgitperms.perl чтобы на примере изучить как проделывать это.

pre-receive

GIT_DIR/hooks/pre-receive

Этот хук вызывается 'git-receive-pack' на удаленный репозиторий, что происходит когда заканчивается выполнение 'git-push' на локальном репозитории. Сразу после начала обновления refs(сслылок) на удаленном репозитории, вызывается хук pre-receive. Его статус выхода определяет успех или неудачу обновления.

Этот хук выполняется однажды для операции получения. Он не принимает аргументов, но чтобы обновить каждую ref(ссылку) он принимает в стандартный ввод строку след.формата:

SP SP LF

где <old-value> это старое имя объекта сохраненного в ref, <new-value> это имя нового объекта который будет сохранен в ref и <ref-name> это полное имя ref. Когда создается новая ref, <old-value> принимает значение 40 0.

Если хук завершает выполнение с ненулевым статусом, ни одна из refs(ссылок) будет обновлена. Если хук завершится с нулевым статусом, то обновление индивидуальных refs все еще можно предотвратить хуком <<update,'update'>>.

Оба стандарный вывод и стандартный вывод ошибок перенаправлены на 'git-send-pack' на другой стороне, так что вы можете просто посылать echo сообщения для пользователя.

Если вы написали его на Руби, вы можете получить аргументы след.образом:

rev_old, rev_new, ref = STDIN.read.split(" ")

Или в bash скрипт, аналогичный тому что ниже тоже будет работать:

#!/bin/sh
# <oldrev> <newrev> <refname>
# update a blame tree
while read oldrev newrev ref
do
    echo "STARTING [$oldrev $newrev $ref]"
    for path in `git diff-tree -r $oldrev..$newrev | awk '{print $6}'`
    do
      echo "git update-ref refs/blametree/$ref/$path $newrev"
      `git update-ref refs/blametree/$ref/$path $newrev`
    done
done

update

GIT_DIR/hooks/update

Этот хук вызывается 'git-receive-pack' на удаленном репозитории, что происходит когда выполнение 'git-push' завершилось на локальном репозитории. Перед самым обновлением ссылок на удаленном репозитории, вызывается хук обновления. Его статус окончания выполнения определяет успешно или неудачно обновилась ссылка.

Этот хук выполняется один раз для обновления каждой ссылки, и он принимает три параметра:

Нулевой выход из хука обновления позволяет обновиться ссылке. Выход с ненулевым статусом предотвратит обновление этой ссылки хуком 'git-receive-pack'

Этот хук может быть использован чтобы предотвратить 'forced(вынужденное)' обновление определенных ссылок, с помощью проверки что имени объекта соотвествует объект коммит, который является потомоком объекта коммита названного по имени старого объекта. Это для того чтобы заставить работать правило "только fast-forwarding".

Он также может быть использован что логгировать старый..новый статус. Как бы там ни было, он не знает все множество ветвей, и закончит посылая одно эл.сообщение на каждую обновленную ссылку, когда используется напрямую. Хук <<post-receive,'post-receive'>> лучше подходит для этого.

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

Оба стандартный вывод и стандартные вывод ошибок перенаправлены с другого конца в 'git-send-pack', так что вы легко можете посылать echo сообщения для пользователя.

Хук 'update' по умолчанию, когда активирован--и с включенным конфигурационным параметром hooks.allowunannotated--предотвращает выполнение push неаннотированных тагов.

post-receive

GIT_DIR/hooks/post-receive

Этот хук вызывается 'git-receive-pack' на удаленном репозитории, что происходит когда завершается 'git-push' на локальном репозитории. Он выполняется на удаленном репозитории один раз после того как все ссылки будут обновлены.

Этот хук выполняется один раз для операции получения. Он не принимает аргументов, но получает туже информацию что и хук <<pre-receive,'pre-receive'>> на его стандартный ввод.

Этот хук не влияет на результат 'git-receive-pack', так как он вызывается после того как работа фактически уже окончена.

Он замещает хук <<post-update,'post-update'>> таким образом, он получает оба старые и новые значения всех ссылок в добавок к их именам.

Оба стандартный вывод и стандартный вывод ошибок перенаправлены с другой стороны на 'git-send-pack', так что вы можете просто посылать echo сообщения пользователю.

Дефолтовый хук 'post-receive' пуст, но существует скрипт образец post-receive-email в директории contrib/hooks идущий по умолчанию в комплекте с git, который реализует отпраление коммитов по эл.почте.

post-update

GIT_DIR/hooks/post-update

Этот хук вызвается 'git-receive-pack' на удаленном репозитории, и происходит когда завершается выполнение 'git-push' на локальном репозитории. Он выполняется на удаленном репозитории один раз после того как все ссылки будут обновлены.

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

Это хук главным образом назначается для уведомлений, и не может повлиять на результат 'git-receive-pack'.

Хук 'post-update' может сообщить для каких HEAD было выполнена операция push, но он не знает каковы их оригинальные и обновленные значения, так что это не самое лучшее место чтобы логировать. Хук <<post-receive,'post-receive'>> получает оба оригинальные и обновленные значения ссылок. Вам лучше использовать его если они вам нужны.

Когда активирован, хук 'post-update' по умолчанию запускает 'git-update-server-info' чтобы поддерживать информацию обновленной использованную транспотными протоколами (e.g., HTTP). Если вы публикуете репозиториий git который доступен по протоколу HTTP, то возможно вы должны разрешить этот хук.

Оба стандартный вывод и стандартный вывод ошибок перенаправлены на 'git-send-pack' с другого конца, так что вы можете просто посылать echo сообщения для пользователя.

pre-auto-gc

GIT_DIR/hooks/pre-auto-gc

Это хук вызывается 'git-gc --auto'. Он не принимает параметров, и выход с ненулевым статусом из этого скрипта вызывает прекращение работы 'git-gc --auto'.

References

Git Hooks * http://probablycorey.wordpress.com/2008/03/07/git-hooks-make-me-giddy/

Недопереведено



github logo