Есть рабочий сайт, на этом же сервере есть гит-сервер (gitstack).
Как создать на сервере репозиторий с данным рабочим сайтом?
Т.е. нужно создать репозиторий, его я клонирую на локальный компьютер, что-то дорабатываю, делаю пуш, и после этого - то что я только что запушил должно быть сразу видно на рабочем сайте.
Ясно что лучше иметь отдельно сервер для разработки, отдельно или автоматом деплоить все, но увы - такие условия как я изложил.
Ответ
Развертывание напрямую, без удаленного репозитория и Git-сервера
Требования:
доступ к серверу по SSH
на локальной машине установлен git, а также rsync или git-sync
на сервере Git не нужен
Что делать?
Не обязательно устанавливать Git на сервере или копировать туда папку .git. Чтобы обновить сервер из git-репозитория, вы можете использовать вот такую команду:
git ls-files -z | rsync --files-from - --copy-links -av0 . user@server.com:/var/www/project
Эта команда копирует все файлы. rsync использует ssh (secure shell), который в любом случае установлен на сервере.
Но при этом вам, вероятно, придется вручную удалить файлы, которые были удалены из проекта (т.е. не изменились, а перестали существовать в очередном коммите).
Вместо rsync можно использовать утилиту git-sync, написанную Яном Бикингом. Как утверждает автор, она работает с Git быстрее, чем rsync.
Почему это хороший способ?
Чем меньше ПО установлено у вас на сервере, тем более он защищен и тем проще его администрировать и документировать. Кстати, это еще и исключает небоходимость хранить на сервере полный Git-репозиторий со всей историей. Это только усложнило бы задачу по обеспечению безопасности сервера.
(Написано на основе ответа @Christian, блога Ian Bicking)
Развертывание через удаленный репозиторий на сервере.
Этот способ сопряжен с риском утечки данных!
Были получены исходники 3300 глобальных интернет-проектов
Требования:
доступ к серверу по SSH
на сервере установлен Git.
на сервере установлен Git-сервер, например Gitlab или Gitstack
на локальной машине установлен Git.
Если вы начинаете с сервера с файлами и без репозитория
На сервере в папке с проектом выполните:
git init
git add --all
git commit -m'сообщение, описывающее текущее состояние проекта'
И переходите к следующему пункту.
Если вы начинаете с сервера с файлами и репозиторием
Выберите на локальной машине папку, где будет располагаться проект. Выполните там:
git clone -o production username@webserver:/path/to/htdocs/.git
Если вы начинаете с локального репозитория
Скопируйте свою локальную папку .git на сервер.
В локальной копии откройте .git/config и добавьте ваш сервер как remote
[remote "production"]
url = username@webserver:/path/to/htdocs/.git
Общая часть
На сервере замените .git/hooks/post-update на код, приведенный ниже в этом ответе.
На сервере добавьте этому файлу права на запись:
chmod +x .git/hooks/post-update
Теперь, когда вы делаете git push с локального репозитория, репозиторий на сервере должен автоматически обновлять рабочую директорию:
git push production
Полезные ссылки по теме:
http://toroid.org/ams/git-website-howto
https://www.digitalocean.com/community/tutorials/how-to-set-up-automatic-deployment-with-git-with-a-vps
post-update hook:
Git-hook нашел на этом сайте
#!/bin/sh
#
# This hook does two things:
#
# 1. update the "info" files that allow the list of references to be
# queries over dumb transports such as http
#
# 2. if this repository looks like it is a non-bare repository, and
# the checked-out branch is pushed to, then update the working copy.
# This makes "push" function somewhat similarly to darcs and bzr.
#
# To enable this hook, make this file executable by "chmod +x post-update".
git-update-server-info
is_bare=$(git-config --get --bool core.bare)
if [ -z "$is_bare" ]
then
# for compatibility's sake, guess
git_dir_full=$(cd $GIT_DIR; pwd)
case $git_dir_full in */.git) is_bare=false;; *) is_bare=true;; esac
fi
update_wc() {
ref=$1
echo "Push to checked out branch $ref" >&2
if [ ! -f $GIT_DIR/logs/HEAD ]
then
echo "E:push to non-bare repository requires a HEAD reflog" >&2
exit 1
fi
if (cd $GIT_WORK_TREE; git-diff-files -q --exit-code >/dev/null)
then
wc_dirty=0
else
echo "W:unstaged changes found in working copy" >&2
wc_dirty=1
desc="working copy"
fi
if git diff-index --cached HEAD@{1} >/dev/null
then
index_dirty=0
else
echo "W:uncommitted, staged changes found" >&2
index_dirty=1
if [ -n "$desc" ]
then
desc="$desc and index"
else
desc="index"
fi
fi
if [ "$wc_dirty" -ne 0 -o "$index_dirty" -ne 0 ]
then
new=$(git rev-parse HEAD)
echo "W:stashing dirty $desc - see git-stash(1)" >&2
( trap 'echo trapped $$; git symbolic-ref HEAD "'"$ref"'"' 2 3 13 15 ERR EXIT
git-update-ref --no-deref HEAD HEAD@{1}
cd $GIT_WORK_TREE
git stash save "dirty $desc before update to $new";
git-symbolic-ref HEAD "$ref"
)
fi
# eye candy - show the WC updates :)
echo "Updating working copy" >&2
(cd $GIT_WORK_TREE
git-diff-index -R --name-status HEAD >&2
git-reset --hard HEAD)
}
if [ "$is_bare" = "false" ]
then
active_branch=`git-symbolic-ref HEAD`
export GIT_DIR=$(cd $GIT_DIR; pwd)
GIT_WORK_TREE=${GIT_WORK_TREE-..}
for ref
do
if [ "$ref" = "$active_branch" ]
then
update_wc $ref
fi
done
fi
Ответ написан на основе ответов с англоязычного StackOverflow. Дополнил, переработал, собрал в один ответ.
Комментариев нет:
Отправить комментарий