С того самого момента, когда я начал изучать Git, меня волновали методы практического применения этой DCVS, делающие работу с использованием этой DCVS удобней и проще, в частности, когда нет необходимости взаимодействовать с какими-то удаленными сервисами вроде GitHub и, в целом, делиться кодом с посторонними людьми. Так как большую часть времени я использую Git при разработке различных веб-ориентированных систем, первым рецептом, которым я хочу сегодня с вами поделиться, будет по-настоящему удобный и простой способ выгрузки исходных кодов и ресурсов сайта на любой сервер, на котором установлен Git.
В отличии от некоторых способов решения подобных проблем, в том числе описанных здесь на хабре, предлагаемый мною способ требует всего лишь одного удаленного репозитория на сервере, всего лишь одного хука и не требует ничего другого кроме самого Git. Конечно, он, может быть, не даёт всей гибкости, что дают другие методы, но это некоторое отсутствие гибкости, по-моему, полностью компенсируется простотой и удобством применения этого метода. Этот метод будет особенно удобен для небольших проектов.
На целевом сервере
Первым делом на целевом сервере в корне или, лучше, на уровень ниже корня сайта, создадим пустой репозитарий:
~/www$ git init
Initialized empty Git repository in /home/example.com/www/.git/
Так как мы работаем не с голым (bare) репозитарием, обязательно разрешим перезапись текущей ветки:
~/www$ git config receive.denyCurrentBranch ignore
Наконец, создадим хук .git/hooks/post-receive
, который и будет делать всю работу:
#!/bin/sh
cd ..
GIT_DIR='.git'
git reset --hard
Разрешим выполнение для этого хука:
~/www$ chmod +x .git/hooks/post-receive
Локально у разработчика
Затем расскажем локальному репозитарию о том, куда следует делать выгрузку:
$ git remote add --track master origin ssh://server.example.net/~/www/
И загрузим основную ветку на целевой сервер:
$ git push origin master
Вот и всё!
Что дальше?
В дальнейшем, для выгрузки основной ветки на сервер когда нам это будет нужно, вам достаточно будет делать:
$ git add htdocs/index.html
$ git commit -m "Ещё один коммит"
$ git push
Этот удаленный репозитарий можно использовать и для любых других целей коллективной разработки, для которых обычно используют Git, например, выгружать другие ветки в целях обмена между разработчиками. Также можно по-умолчанию выгружать на сервере не master-ветку, а, например, release-ветку:
~/www$ git checkout release
А что если я изменю файлы прямо на сервере...
В представленном выше варианте все незакоммиченные изменения, которые были внесены напрямую на сервере, будут удалены при очередном git push
, что, если вам достаточно не повезло, может быть неприемлемо. Если вам совершенно необходимо дать кому-то возможность менять файлы прямо на сервере, например, через FTP, вместо представленного выше хука post-receive
используйте следующий .git/hooks/pre-receive
:
#!/bin/sh
cd ..
GIT_DIR='.git'
git stash save --quiet
git stash show || true
Вместе с этим .git/hooks/post-receive
:
#!/bin/sh
cd ..
GIT_DIR='.git'
git reset --hard
git stash pop --quiet || git reset --hard
В этой усложнённой схеме, в случае конфликтов при git push
, вам нужно будет вручную сделать git stash pop
на сервере и разрешить конфликты.
Что ещё нужно знать?
Убедитесь, что посторонние не могут прочитать файлы в каталоге .git
в корне вашего сайта, либо размещайте корень репозитария на уровень ниже корня веб-сайта.
Автор: alexkbs
Спасибо огромное, как вы мне помогли… не связываться с Capistrano и прочим, что как атомной гравипушкой по воробьям