Coding → Простой способ синхронизации структуры и данных MySQL при работе с Mercurial
Привет. Недавно перевёл работу на Mercurial и встала задача организовать синхронизацию MySQL. Погуглив, ничего простого и надёжного не было найдено, поэтому пришлось самому решать эту задачу.
Решение оказалось на удивление простым. Разделим задачу на две части: сохранение изменений базы данных, с последующим коммитом и пушем в центральный репозиторий, и обновление структуры БД после апдейта. Тогда задание сводится к тому, чтобы перед коммитом(а точнее перед hg status) сделать дамп базы в определённый файл и закоммитить его. И затем после hg update нужно этот файл импортировать в базу, вместе с свежими изменениями.
Общее решение
Для решения проблемы воспользуемся хуками (подробнее). Заходим в папку .hg в нашем репозитории, и находим(или не находим, тогда создаём) там файл hgrс. Открываем его любимым редактором и вставляем туда следующий код:
[hooks]
pre-status = c:\path\to\mysql\bin\mysqldump.exe -u USERNAME -pUSERPSWD DBNAME > db\dump.sql
update = c:\path\to\mysql\bin\mysql.exe -u USERNAME -pUSERPSWD DBNAME < db\dump.sql
Если вы не понимаете указанные параметры, запустите mysqldump —help и почитайте мануал. Вкратце — заменяем USERNAME на имя пользователя MySQL(должен иметь права для дампа и импорта), USERPSWD — на пароль этого пользователя и DBNAME на имя базы данных. Если хотите, можете поменять место хранения дампа(db\dump.sql, относительно корня репозитория). Пользователям не-windows систем может потребоваться поменять ещё и разделитель директорий на «/».
Всё. Теперь можно запустить hg status и увидеть, что Mercurial заметил изменения в дампе(после первого запуска появится файл с дампом, не забудьте добавить его в репозиторий командой hg add):
Решение для TortoiseHg
При использовании TortoiseHg не срабатывает хук «pre-status». Вызвано это тем, что команда «status» там вообще не запускается. Я не смог выяснить, какая команда там запускается при формировании списка изменённых файлов в окне «commit», поэтому пришлось вешать хук на сам коммит. В итоге в файл hgrc там нужно добавить немного изменённый код:
[hooks]
commit.a = c:\path\to\mysql\bin\mysqldump.exe -u USERNAME -pUSERPSWD DBNAME > db\ep.sql
commit.b = hg status
update = c:\path\to\mysql\bin\mysql.exe -u USERNAME -pUSERPSWD DBNAME < db\temp.sql
Теперь коммит будет проходить в два этапа — сначала изменённые файлы, затем срабатывает хук, и сразу коммитим изменённый дамп. Чуть менее удобно, но пока другого решения я не нашёл. Апдейт работает так же, как и в первом случае.
Спасибо за внимание. Как обычно, буду рад любым улучшениям и предложениям.
Полезные ссылки:
- мануал по mercurial hooks
- mysqldump.exe версии 5.1.5 для пользователей Денвера(там урезанная версия MySQL и нет этого файла)

Здравствуйте.
Объясните а почему Вы не стали использовать хук pre-commit, вместо commit, ведь получается что дамп бд не «попадает» в текущий коммит и его необходимо коммитить одтельно? Или я что-то неправильно понял?
Да, я сначала хотел сделать именно так, и в первой части статьи подобным образом и сделано. Насколько я помню, в TortoiseHG (по крайней мере старых версий) странное поведение и хука pre-status и предложенного вами pre-commit, поэтому пришлось делать вот так, с двумя коммитами. Возможно сейчас всё работает правильно, тогда имеет смысл делать так, как вы предлагаете.