Я хотів би виконати одиничні тести перед кожним натисканням git, і якщо тести не вдаються, скасуйте натискання, але я навіть не можу знайти гачок попереднього натискання, є лише попередня фіксація та попередня перезавантаження.
Я хотів би виконати одиничні тести перед кожним натисканням git, і якщо тести не вдаються, скасуйте натискання, але я навіть не можу знайти гачок попереднього натискання, є лише попередня фіксація та попередня перезавантаження.
Відповіді:
Я б скоріше запустив тест у попередній зачіпці. Тому що зміни вже фіксуються при здійсненні. Натисніть і витягніть лише обмін інформацією про вже записану зміну. Якщо тест не вдасться, у вашому сховищі вже буде "зламана" версія. Ви натискаєте на це чи ні.
Git отримав pre-push
гачок у 1.8.2
релізі.
Приклад pre-push
сценарію: https://github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample
1.8.2 нотатки до випуску, що розповідають про новий попередній натиск: https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt
Git отримав гачок перед натисканням у версії 1.8.2.
Гачки попереднього натискання - це те, що мені потрібно разом з гачками, які попередньо здійснюють фіксацію. Крім захисту гілки, вони також можуть забезпечити додаткову безпеку в поєднанні з гачками, які попередньо здійснюють.
І для прикладу того, як використовувати (взяті та прийняті та покращені з цього приємного запису )
Простий приклад, щоб увійти до бродячого, запустити тести і потім натиснути
#!/bin/bash
# Run the following command in the root of your project to install this pre-push hook:
# cp git-hooks/pre-push .git/hooks/pre-push; chmod 700 .git/hooks/pre-push
CMD="ssh vagrant@192.168.33.10 -i ~/.vagrant.d/insecure_private_key 'cd /vagrant/tests; /vagrant/vendor/bin/phpunit'"
protected_branch='master'
# Check if we actually have commits to push
commits=`git log @{u}..`
if [ -z "$commits" ]; then
exit 0
fi
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
if [[ $current_branch = $protected_branch ]]; then
eval $CMD
RESULT=$?
if [ $RESULT -ne 0 ]; then
echo "failed $CMD"
exit 1
fi
fi
exit 0
Як ви бачите, у прикладі використовується захищена гілка, що підлягає гачку перед натисканням.
Якщо ви використовуєте командний рядок, найпростіший спосіб зробити це - написати push-скрипт, який запускає ваші одиничні тести, і, якщо вони досягли успіху, завершує натиск.
Редагувати
Станом на git 1.8.2 ця відповідь застаріла. Дивіться відповідь манольдса вище.
Для цього немає гачка, тому що push не є операцією, яка модифікує ваше сховище.
Ви можете робити перевірки на приймальній стороні, хоча, на post-receive
гачку. Саме там ви зазвичай відхиляєте вхідний поштовх. Виконання тестів на одиниці може бути трохи інтенсивним, але це залежить від вас.
Для запису є патч до Git 1.6, який додає гачок перед натисканням . Я не знаю, чи працює це проти 1.7.
Замість того, щоб возитися з цим, ви можете запустити push-сценарій, як @kubi рекомендується. Ви також можете зробити це завдання Rake замість цього, щоб це було у вашому репо. ruby-git може допомогти у цьому. Якщо ви перевіряєте цільове репо, ви можете запускати тести лише під час натискання на виробниче репо.
Нарешті, ви можете запустити свої тести у pre-commit
гачку, але перевірте, до якої галузі займається. Тоді ви можете мати, скажімо, production
відділення, яке вимагає пройти всі тести, перш ніж прийняти зобов’язання, але вас master
не хвилює. limerick_rake може бути корисний у цьому сценарії.
Скрипт пов'язує високо-голосування відповісти показує параметри і т.д. на pre-push
гак ( $1
це ім'я віддаленого, $2
URL) , і як отримати доступ до фіксацій (рядки read
зі стандартного вводу мають структуру <local ref> <local sha1> <remote ref> <remote sha1>
)
#!/bin/sh
# An example hook script to verify what is about to be pushed. Called by "git
# push" after it has checked the remote status, but before anything has been
# pushed. If this script exits with a non-zero status nothing will be pushed.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If pushing without using a named remote those arguments will be equal.
#
# Information about the commits which are being pushed is supplied as lines to
# the standard input in the form:
#
# <local ref> <local sha1> <remote ref> <remote sha1>
#
# This sample shows how to prevent push of commits where the log message starts
# with "WIP" (work in progress).
remote="$1"
url="$2"
z40=0000000000000000000000000000000000000000
while read local_ref local_sha remote_ref remote_sha
do
if [ "$local_sha" = $z40 ]
then
# Handle delete
:
else
if [ "$remote_sha" = $z40 ]
then
# New branch, examine all commits
range="$local_sha"
else
# Update to existing branch, examine new commits
range="$remote_sha..$local_sha"
fi
# Check for WIP commit
commit=`git rev-list -n 1 --grep '^WIP' "$range"`
if [ -n "$commit" ]
then
echo >&2 "Found WIP commit in $local_ref, not pushing"
exit 1
fi
fi
done
exit 0