subversion-hooks

В большинстве случаев, при разработке веб-проекта требуется автоматически обновлять рабочую версию, на помощь на приходят свн-хуки!

Начнем с того, что у нас есть веб-проект и нам необходимо создать для него репозиторий, как это сделать я рассказывал в статье «FreeBSD. Установка и настройка Subversion».

Далее, мы будем обновлять наш проект только через репозиторий!

Подготовка проекта

Сначала сделаем импорт веб-проекта в репозиторий:

# svn import /_project_ file:///svn/repos/_project_

Теперь удалим все файлы проекта (не забывайте делать бекапы на всякий случай), и сделаем чекаут:

# cd /_project
# rm -rf *
# svn checkout file:///svn/repos/_project_

Hooks

Хуки срабатывают на разные события Subversion, вот некоторые из них:

  • start-commit — запускается до начала транзакции, может быть использован для проверки прав.
  • pre-commit — запускается в конце транзакции, но до commit, часто используется для валидации данных, например для проверки не пустых лог-собщений.
  • post-commit — запускается после транзакции, может быть использовано для отправки e-mail или для резервирования хранилища.
  • pre-revprop-change — запускается до изменений в ревизии, могут быть использованы для проверки доступа.
  • post-revprop-change — запускается после изменений в ревизии, могут быть использованы для отправки e-mail или для резервирования изменений.

Есть еще «post-lock», «post-unlock», «pre-lock» и «pre-unlock», как видно из названий он срабатывают при блокировке. Я не буду их разбирать, потомучто они у меня интереса пока не вызвали.

Post-Commit Hook

Этот хук срабатывает после любого commit'a репозитория, для его активации надо скопировать шаблон и наделить правами на запуск:

# cd /svn/repos/_project_/hooks
# cp post-commit.tmpl post-commit
# chmod u+x post-commit

Далее, отредактируем файл post-commit, закомментируем все лишнее и добавим наши команды для обновления проекта:

cd /_project_ && /usr/local/bin/svn update

Примерного такой вид в результате будет иметь содержимое ваше хука:

#!/bin/sh

#
# ... тут куча комментариев ...
#

REPOS="$1"
REV="$2"

cd /_project_ && /usr/local/bin/svn update

#commit-email.pl "$REPOS" "$REV" commit-watchers@example.org
#log-commit.py --repository "$REPOS" --revision "$REV"

далее, проверим работает ли хук от имени под которым запущен Subversion и выполним его:

# su www
# ./post-commit

Если ответ примерно такой:

At revision тут_номер_ревизии

то все в порядке!

А если нет, то у вас ошибка в хуке, пишите в комментарии — помогу.

Собственно хук готов, теперь его необходимо проверить, сделайте commit и посмотрите, обновился ли ваш проект — если нет, то скорее всего проблемы с правами на запись файлов вашего проекта.

Необходимо разрешить права на запись файлов веб-проекта пользователю/группе от которой запущен subversion, скорее всего это www.

# cd /_project
# chown -R www:www *
# chown -R www:www .*
# chmod -R 775 *
# chmod -R 775 .svn

P.S. Спасибо дуду за помощь в тестировании хук :)


Комментарии (81) на запись «Subversion. Автоматическое обновление проекта при помощи хуков»

» Трекбеки скрыты, показать их?
  1. Юра Диденко | 16.07.2009 в 15:17

    У меня вопрос по поводу загадочной строчки

    «cd /_project_ && /usr/local/bin/svn update»

    если у меня репозитарий находтся в /var/svn а сам веб проект в /var/www

    то эту строчку я должен переписать так

    «cd /var/svn && /var/www update» ?

    а еще вот:

    root@server:/var/svn/hooks# su www-data

    $ ./post-commit

    sh: ./post-commit: Permission denied

    (пермишен денайд выдает)

    Что делаю не так? Спасибо!

  2. adw0rd | 16.07.2009 в 15:27

    В примере:

    свн репозиторий — /svn/repos/_project_/

    файлы проекта — /_project_

    Из это следует, что вам надо

    cd /var/www && /usr/local/bin/svn update

  3. adw0rd | 16.07.2009 в 15:28

    sh: ./post-commit: Permission denied

    покажите права на этот файл

  4. Юра Диденко | 16.07.2009 в 18:04

    root@server:/var/svn/hooks# ls -l post-commit

    -rwxr--r-- 1 root svn 2041 2009-07-16 16:13 post-commit

    я так понимаю сменить владельца надо? (спасибо вы мне очень помогаете)

  5. adw0rd | 16.07.2009 в 18:12

    Юра Диденко, да, смените права на файл и не забывайте, что надо обязательно иметь права на выполнение (x)

    зы. пожалуйста :)

  6. Юра Диденко | 16.07.2009 в 18:27

    root@server:/var/svn/hooks# chmod -R g+wsx post-commit

    root@server:/var/svn/hooks# ls -l post-commit

    -rwxrwsr-- 1 www-data svn 2041 2009-07-16 16:13 post-commit

    root@server:/var/svn/hooks# su www-data

    $ ./post-commit

    ./post-commit: 49: /usr/local/bin/svn: not found

    ./post-commit: 52: /usr/share/subversion/hook-scripts/commit-email.pl: not found

    $ exit

    я так понимаю первая проблема он не нашел репозиторий все правильно он у меня в /var/svn исправил, вторую опцию я просто закомментировал в файле post-commit

    запускаю

    root@server:/var/svn/hooks# su www-data

    $ ./post-commit

    ./post-commit: 49: /var/svn: Permission denied

    ./post-commit: 52: : Permission denied

    что-то как-то сложно с правами доступа

  7. adw0rd | 16.07.2009 в 18:36

    /var/svn — это у вас путь до репозитория или до приложения?

  8. Юра Диденко | 16.07.2009 в 19:06

    да это путь до репозитария

  9. adw0rd | 16.07.2009 в 19:13

    ну так надо не путь до репозитория, а путь до приложения

    * вы заходите в каталог где храниться рабочая копия (/var/www)

    * выполняете апдейт (whereis svn)

    нам путь до репозитория не нужен

  10. Юра Диденко | 16.07.2009 в 19:16

    svnadmin create /var/svn

    chown -R www-data:svn /var/svn

    chmod -R g+ws /var/svn

    Так был создан репозитарий (я создавал из примера habrahabr.ru/blogs/ubuntu/20525/)

  11. adw0rd | 16.07.2009 в 19:21

    1. У вас Ubuntu?

    2. Какой путь до программы svn? (whereis svn)

  12. Юра Диденко | 16.07.2009 в 19:22

    Если в файле post-commit записать так:

    cd /var/www && /usr/local/bin/svn update

    то получается следующее:

    $ ./post-commit

    ./post-commit: 50: /usr/local/bin/svn: not found

    ./post-commit: 53: : Permission denied

    Это понятно такого пути просто нет /usr/local/bin/svn , репозитарий находится в папке /var/svn веб каталог он же каталог проекта в папке /var/www

  13. adw0rd | 16.07.2009 в 19:24

    /usr/local/bin/svn — это путь до программы, а не репозитория, и нам нужен путь до программы, а не до репозитория!

    выполните комманду

    whereis svn

  14. Юра Диденко | 16.07.2009 в 19:27

    root@server:/var/svn/hooks# whereis svn

    svn: /usr/bin/svn /usr/share/man/man1/svn.1.gz

    я понимаю я туплю, еще раз спасибо вам, за то что нервов еще хватает на переписку со мной ;) спасибо

  15. adw0rd | 16.07.2009 в 19:27

    1. Вы устанавливали как модуль Apache?

    2. Используете путь вида «http://...»?

    3. Под каким пользователем и группой у вас работает Apache?

  16. adw0rd | 16.07.2009 в 19:28

    /usr/bin/svn — вот это ваш путь, замените «/usr/local/bin/svn» на «/usr/bin/svn»

    я понимаю я туплю, еще раз спасибо вам, за то что нервов еще хватает на переписку со мной ;) спасибо

    это все форум pyha.ru меня таким сделал, я все терплю :)
  17. Юра Диденко | 16.07.2009 в 19:31

    Уже лучше стало:

    root@server:/var/svn/hooks# su www-data

    $ ./post-commit

    Пропущено '.'

    ./post-commit: 53: : Permission denied

    ))

    Я вот так записал:

    cd /var/www && /usr/bin/svn update

  18. adw0rd | 16.07.2009 в 19:33

    ок, теперь зайдите в каталог

    cd /var/www

    и выполните

    /usr/bin/svn update

  19. Юра Диденко | 16.07.2009 в 19:34

    root@server:/var/svn/hooks# cd /var/www

    root@server:/var/www# /usr/bin/svn update

    Пропущено '.'

    Аааа что он хочет?)))

  20. adw0rd | 16.07.2009 в 19:35

    Юра Диденко, а вы делали чекаут?

  21. Юра Диденко | 17.07.2009 в 14:48

    да небыло чек аута, я пересоздал репозиторий выполнил чекаут но вот что получил

    root@server:/var/svn/hooks# ls -l post-commit

    -rwxr-xr-x 1 www-data svn 2030 2009-07-17 14:28 post-commit

    root@server:/var/svn/hooks# su www-data

    $ ./post-commit

    Type 'svn help' for usage.

    $

    ? почему

  22. adw0rd | 17.07.2009 в 14:50

    Покажи содержимое файла «post-commit» (только вырежи оттуда комментарии)

  23. Юра Диденко | 17.07.2009 в 14:56

    ---------------------------------------------------------

    #Все остальное что выше закоменченно!

    REPOS="$1"

    REV="$2"

    cd /var/www && /usr/bin/svn

    #/usr/share/subversion/hook-scripts/commit-email.pl \

    # «$REPOS» «$REV» commit-watchers@example.org

    ---------------------------------------------------------

    root@server:/var/svn/hooks# whereis svn

    svn: /usr/bin/svn /usr/share/man/man1/svn.1.gz

    рабочий каталог проекта /var/www

    чекаут делал вот так:

    svn checkout file:///var/svn/social /var/www

    (я чувствую где-то какая-то мелочь))

  24. adw0rd | 17.07.2009 в 15:18

    cd /var/www && /usr/bin/svn

    Куда «update» дел?

  25. Юра Диденко | 17.07.2009 в 18:00

    Как вас зовут? я выпью за ваше здоровье сегодня! Спасибо! Вы мне очень помогли!

    ---------------------------------------------------------

    п.с. выставил всем вложенным файлам и папкам владельца www-data.svn как так получилось, до сих пор не понял, мускул отвалился... еще кое-чего... сижу правлю руками, но твой хук;) работает, и мега круто работает! Спасибо еще раз!

  26. adw0rd | 17.07.2009 в 18:02

    Меня зовут Михаил Андреев :)

    >мускул отвалился... еще кое-чего

    Зарегистрируйтесь на pyha.ru/forum и я вам там помогу ;)

  27. Юра Диденко | 18.07.2009 в 18:05

    очень приятно Михаил!

    >я понял почему мускул отвалился и как владельца ошибочно установил...

    # cd /_project

    # chown -R www:www *

    # chown -R www:www .* <- зачем вот это делаем?

    # chmod -R 775 *

    # chmod -R 775 .svn

  28. adw0rd | 18.07.2009 в 21:09

    .*

    для скрытых файлов

  29. Darkside | 29.07.2009 в 10:59

    можно ли настроить посткоммит так, чтобы файлы сливались на другой сервер по ftp?

  30. adw0rd | 29.07.2009 в 11:57

    Darkside, можно

  31. Михаил | 23.10.2009 в 11:52

    Здравствуйте. Помогите пожалуйста написать хук.

    Мне нужно чтобы после команды update (после обновления номера ревизии) файлы из одной директории копировались в другую.

    Я так понимаю что нужно использовать хук post-revprop-change.bat. Нужно добавить в него строку xcopy D:\Repository\*.* /d D:\test /s /y > info.txt

    Что toe нужно добавить в хук чтобы он заработал?

    Спасибо!

  32. Михаил | 23.10.2009 в 11:56

    Забыл написать, что я это делаю на Windowx XP.

  33. adw0rd | 23.10.2009 в 12:51

    Михаил, а

    xcopy D:\Repository\*.* /d D:\test /s /y > info.txt

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

    Я под виндовс не делал хуков, только под FreeBSD и Linux

  34. Михаил | 23.10.2009 в 13:09

    Да. Если я вручную запускаю этот батник, то он все выполняет. А если я выполняю команду svn update, то номер ревизии меняется но этот хук не отрабатывает.

    Может там нужно прописать какие условия? И если они выполняются то выполнять копирование

  35. adw0rd | 23.10.2009 в 15:35

    А разве у вас нету хука «post-update»?

  36. Михаил | 23.10.2009 в 15:49

    Неа, нету.Вот все что есть:

    post-commit,post-lock,post-revprop-change,post-unlock,post-update,pre-commit,pre-lock,pre-revprop-change,pre-unlock,start-commit

    Если я сам сделаю батник с названием post-update.bat и туда вставлю строку копирования, будет работать?

  37. adw0rd | 23.10.2009 в 16:15

    Неа, нету.Вот все что есть:

    post-commit,post-lock,post-revprop-change,post-unlock,post-update,pre-commit,pre-lock,pre-revprop-change,pre-unlock,start-commit

    :)

  38. Михаил | 23.10.2009 в 16:27

    А не, сорри. Это я уже сам его создал руками. Его не было:)

    Я проверил, что если его вручную создать, то он не работает.

    Может я что то не правильно делаю.

    После команды svn update хук post-update должен автоматически срабаотывать без дополнительных команд и настроек?

  39. adw0rd | 23.10.2009 в 16:38

    Ну, в принципе вам подойдет «post-revprop-change», потестите его, впишите в хук:

    echo 'test' >> c:\test.log

    И посмотрите — срабатывает ли он. Также можете потестить методом тыка все хуки и узнать, какой вам понадобиться...

  40. Михаил | 23.10.2009 в 16:44

    Хуки если вручную запускаю отрабатывают как надо. а вот после update не работает:((

    Не знаю что еще придумать:(

  41. adw0rd | 23.10.2009 в 16:52

    Я говорю, впишите во все хуки, нечто

    echo 'HOOK_NAME' >> c:\test.log

    и узнаете, что выполнилось

  42. Михаил | 23.10.2009 в 17:20

    Я так и сделал. Ни один из хуков на update не сработал. Но зато срабатывает хук post-commit после команд delete и import

  43. Михаил | 28.10.2009 в 17:11

    А Вы не подскажете еще, на какие команды срабатывает хук post-revprop-change.

  44. vitaly | 05.11.2009 в 16:44

    Сделал как описанно выше, запуская hook скрипт и получаю

    Skipped '.'

    Что это может быть?

  45. adw0rd | 05.11.2009 в 16:50

    1. Скорее всего не там вызываете svn update, покажите хук (только без комментариев в файле).

    2. Вы его вручную сейчас выполняете?

  46. vitaly | 05.11.2009 в 17:01

    REPOS="$1"

    REV="$2"

    cd /var/www/vhosts/c2342/night && /usr/bin/svn update

    /var/www/vhosts/c2342/night — это мой хомяк :)

    и в ручную запускал хук и коппитить пробовал и видел ту же ошибку в логах свн клиента

  47. vitaly | 05.11.2009 в 17:10

    Собственно вот, запускаю в ручную из домашней дериктории (там, где проект должен лежать)

    linux $ /usr/bin/svn update

    Skipped '.'

  48. vitaly | 05.11.2009 в 17:15

    разобрался, моя ошибка.

    не сделал

    svn import /_project_ file:///svn/repos/_project_

    сейчас разбираюсь

  49. adw0rd | 05.11.2009 в 22:20

    Ну так проблема осталась или как?

  50. vitaly | 06.11.2009 в 10:12

    Пока да :(

    Если я в ручную скрипт запускаю — все выполняется корректно, а именно —

    если были коммиты — папка проекта обновляется, если небыло коммитов, то так, как написано у вас:

    At revision тут_номер_ревизии

    Но когда я коммичу, оно мне пишет ошибку

    post-commit hook failed (exit code 255) with no output.

    пока не могу поять в чем дело :(

  51. adw0rd | 06.11.2009 в 10:29

    1. Под кем выполняется subversion? Он имеет право писать данные в проект (update)?

    2. У хуков проставлены права на запуск?

  52. vitaly | 06.11.2009 в 10:43

    1 — не знаю, наверное попробую у хостера узнать. что я заметил, так это то, что на всех папках (в домашней дериктории и папка проекта и свн и прочее хранится) одинаковая группа (не знаю, имеет ли это значение).

    2 — да, я когда проверял запускал сам хук файл

  53. adw0rd | 06.11.2009 в 10:59

    vitaly, у вас svn установлен как модуль apache? В хук добавьте инструкцию touch/mkdir для того чтобы потом определить права у созданного файла/каталога

  54. vitaly | 06.11.2009 в 11:02

    > vitaly, у вас svn установлен как модуль apache?

    не знаю :) могу узнать у хостера.

    > В хук добавьте инструкцию touch/mkdir ...

    т.е. попробовать создать дерикторию, перейти в нее и там попробовать update сделать?

  55. adw0rd | 06.11.2009 в 11:03

    Через хук создайте директорию, после чего посмотрите какие у нее права (команда ls -la)

  56. vitaly | 06.11.2009 в 13:35

    прописал в хуковом скрипте создание дериктории — ничего не создало :( наверное прав нет (опять таки, запустил в ручную хуковый скрипт — все создало. значит ошибки в «синтаксисе» нет)

  57. adw0rd | 06.11.2009 в 16:17

    Да, скорее всего права, однако рекомендую прописать до программ полный путь, например /bin/mkdir, /bin/cp и т.д.

    Узнать можно их через команду whereis (whereis cp)

  58. e1da | 26.11.2009 в 21:42

    при выполнении

    svn import /var/www/ file:///var/svn/

    где /var/www/ — папка проекта

    file:///var/svn/ — папка репозитория

    файлы из базы репозитория появляются не в /var/www, а в /var/www/svn

    и при подключении с удаленного репозитория вылазиет ошибка :

    repository moved permanently...

  59. adw0rd | 26.11.2009 в 21:57

    А какие файлы у вас в /var/svn/ ?

  60. e1da | 26.11.2009 в 22:25

    Извините, всё напутал в попыхах )

    svn import

    /var/www/ file:///var/svn/

    проходит нормально, появляется содержимое репозитория, а вот после

    svn checkout file:///var/svn/

    как раз файлы из базы репозитория появляются не в

    /var/www, а в /var/www/svn

    В /var/svn директории :

    conf

    dav

    db

    hooks

    locks

  61. e1da | 26.11.2009 в 22:58

    Вроде разобрался(ОС Debian) :

    svn checkout file:///svn/repos/_project_

    для меня выглядит как :

    svn checkout file:///var/svn/

    только нужно ещё добавить в конце папку проекта /var/www

    то есть полностью команды выглядит так :

    svn checkout file:///var/svn /var/www

    После этого

    cd /var/www && /usr/bin/svn update

    выдает

    At revision 16.

  62. adw0rd | 27.11.2009 в 10:47

    e1da, ну вроде все хорошо :)

  63. e1da | 28.11.2009 в 00:33

    adw0rd, извините, забыл поблагодарить, многие говорили мне, что так работать с svn невозможно(видимо очень мало русскоязычных материалов).

  64. adw0rd | 28.11.2009 в 00:42

    e1da, вы о хуках, или о тех примерах команд которые скидывали?

  65. e1da | 28.11.2009 в 02:30

    я и о хуках в частности, и о синхронизации svn репозиториев на разных системах.

  66. Serge Kuznetsov | 16.12.2009 в 17:06

    А если репозиторий и рабочий проект на разных серверах.

    Вот пишем на продакшн-сервере:

    svn update

    Что то не видно тут hooks.

    Как можно отловить событие? Хук нашел только в репозитории.

  67. adw0rd | 16.12.2009 в 20:43

    В этом случае надо заходить на удаленный сервак и выполнять svn update. А как это вам решать.

    Вот еще почитайте wiki.agiledev.ru/doku.php...d_package_deploy , может заинтересуетесь.

  68. Serge Kuznetsov | 17.12.2009 в 13:55

    Допустим задача простая: на «обновленном|update» сайте в шаблоне прописать номер ревизии автоматом. Что бы визуально на разных копиях проекта можно было отследить версию. Наверное самое простое написать скрипт обновления.

  69. adw0rd | 17.12.2009 в 14:16

    Можете создать скрипт, который будет срабатывать при http-запросе. Он будет осведомлен о коммите, после чего будет запускать апдейт.

    Это самое простое и не красивое решение.

  70. Pandora | 01.07.2010 в 18:18

    много букф афтор жжот

    тут более понятно blog.plastilin.org.ua/200...svn-freebsd.html

  71. Pandora | 19.07.2010 в 02:55

    больше интересует как сделать игнорирование папок в хуках например у меня в СВН есть движок и папка files хочю пряму на сервере в СВН поместить рабочую копию минуя копирования папки files с 20 гб

  72. Pandora | 19.07.2010 в 03:28

    хуки до сих пор не автоматизированы в рабочей копии сайта хранится хлам '.svn'

  73. Pandora | 19.07.2010 в 03:32

    логично делать хук примерно такой конструкции

    svn co 'svn://site.ru/PandoraEngine_v1.0' '/home/thepirat/soundsite/www' --username 'Логин' --password 'Пароль'

  74. Pandora | 19.07.2010 в 03:33

    логично делать хук примерно такой конструкции

    svn co 'svn://site.ru/PandoraEngine_v1.0' '/home/thepirat/soundsite/www' --username 'Логин' --password 'Пароль'

  75. adw0rd | 20.07.2010 в 01:47

    больше интересует как сделать игнорирование папок в хуках например у меня в СВН есть движок и папка files хочю пряму на сервере в СВН поместить рабочую копию минуя копирования папки files с 20 г

    чего 20 гигов делают в свн? Сделайте для них

    svn ps svn:ignore "*" ./files/

  76. adw0rd | 20.07.2010 в 01:50

    хуки до сих пор не автоматизированы в рабочей копии сайта хранится хлам '.svn

    Это не хлам, это фича. Можно всегда откатить либо задиффить файлы, и т.д.

    Я средствами nginx лочу доступ ко всем файлам начинающиеся с «.*» и не вижу проблем с хранением «хлама», но если вам не нужно это, то делайте svn export.

  77. adw0rd | 20.07.2010 в 01:51

    логично делать хук примерно такой конструкции

    в чем смысл?
  78. Pandora | 22.07.2010 в 02:49

    чего 20 гигов делают в свн? Сделайте для них

    svn ps svn:ignore "*" ./files/

    # svn ps svn:ignore "*" ./files/
    svn: warning: 'files' is not under version control

  79. adw0rd | 22.07.2010 в 13:23

    ну что мне вам сказать, либо у вас нет каталога ./files/, либо он не под свн

  80. Pandora | 22.07.2010 в 15:50

    еще проблема после постинга в каталог сайта появляются .mine .r17 .r18 как от них избавтся например до актуальной версии

  81. adw0rd | 22.07.2010 в 21:21

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

Оставить комментарий