2 февраля, 2015

Git

Публикация в prime через bare-репозиторий, настройка на всех сторонах

Основано на статье Git и публикация сайта.

Очень кратко:

localUser@myPC ~
$ ssh myServer
serverUser@myServer ~/public_html $ git init
serverUser@myServer ~/public_html $ cat > .git/info/exclude
cgi-bin/
^C
serverUser@myServer ~/public_html $ git add .
serverUser@myServer ~/public_html $ git commit -m start
serverUser@myServer ~ $ mkdir bare/mysite.ru
serverUser@myServer ~ $ cd bare/mysite.ru/
serverUser@myServer ~/bare/mysite.ru $ git --bare init
serverUser@myServer ~/bare/mysite.ru $ cd ~/public_html/
serverUser@myServer ~/public_html $ git remote add bare ~/bare/mysite.ru
serverUser@myServer ~/public_html $ git push bare master
serverUser@myServer ~/public_html $ cd ~/bare/mysite.ru/hooks/
serverUser@myServer ~/bare/mysite.ru/hooks $ cat > post-update
#!/bin/sh
echo
echo "*** bare post-apdate hook ***"
echo
cd ~/public_html || exit
unset GIT_DIR
git pull bare master
exec git-update-server-info
^C
localUser@myPC /cygdrive/c/webprojects/my/mysite.ru
$ git clone myServer:~/bare/mysite.ru public_html/
$ ssh myServer
serverUser@myServer ~ $ cat > ~/public_html/.git/.htaccess
Order Deny,Allow
Deny from all
^C

Подробнее:

Сервер

Публичная папка нашего проекта на сервере /home/w/server/zlatov.net/git/public_html (выделил на время поддомен git.zlatov.net)

Ну и допустим что проект не пустой до создания git репозиториев и имеет файлы, достаточно одного index.html.

Клиент

Аналогичная, но пустая папка локально \zlatov.net\git\public_html

Prime

Prime — обычный репозиторий. Сайт запускается из рабочего каталога этого репозитория.

Любой мой день в bush начинается с двух команд:

/zlatov.net/git/public_html
$ eval `ssh-agent.exe`
Agent pid 1776

/zlatov.net/git/public_html
$ ssh-add
Enter passphrase for /c/Users/yadfewm/.ssh/id_rsa:
Identity added: /c/Users/yadfewm/.ssh/id_rsa (/c/Users/yadfewm/.ssh/id_rsa)

Откровенно говоря достала такая ситуация, настраивал всё это дело для того, чтобы пароли не вводить, а получаю аналогичную ситуацию с воодом чего-то другого…

Подключаемся:

$ ssh zlatov
Last login: Wed Aug 27 12:50:25 MSK 2014 from 178-167-52-100.dynvpn.flex.ru on pts/0
Переходим в папку проекта:
~ $ cd zlatov.net/git/public_html
Добавляем пустой репозиторий и добавляем в индекс все файлы:
~/zlatov.net/git/public_html $ git init
Initialized empty Git repository in /home/w/imuser/zlatov.net/git/public_html/
.git/
~/zlatov.net/git/public_html $ git add .
Смотрим что там в индесе:
~/zlatov.net/git/public_html $ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   cgi-bin/php4.cgi
#       new file:   cgi-bin/php5.cgi
#       new file:   cgi-bin/php52.cgi
#       new file:   cgi-bin/php53.cgi
#       new file:   index.html
#

Ой, а там мусор! Давайте сначало вычистим всё, потом добавим исключения на индексацию, опять добавим в индекс и посмотрим правильно ли сделали исключения.

Вычищаем:
~/zlatov.net/git/public_html $ git rm --cached cgi-bin/php4.cgi
rm 'cgi-bin/php4.cgi'
~/zlatov.net/git/public_html $ git rm --cached cgi-bin/php5.cgi
rm 'cgi-bin/php5.cgi'
~/zlatov.net/git/public_html $ git rm --cached cgi-bin/php52.cgi
rm 'cgi-bin/php52.cgi'
~/zlatov.net/git/public_html $ git rm --cached cgi-bin/php53.cgi
rm 'cgi-bin/php53.cgi'
~/zlatov.net/git/public_html $ git rm --cached index.html
rm 'index.html'
~/zlatov.net/git/public_html $ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       cgi-bin/
#       index.html
nothing added to commit but untracked files present (use "git add" to track)
Добавляем исключение, добавляем к индексу и смотрим результат:
~/zlatov.net/git/public_html $ cat > .gitignore
/cgi-bin/*
~/zlatov.net/git/public_html $ git add .
~/zlatov.net/git/public_html $ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   .gitignore
#       new file:   index.html
#

Хорошо, только вот появился дополнительный файл .gitignore, закроем пока на это глаза, а на будущее стоит покапаться в .git/info/exclude (этот файл не коммитуется и остается только в локальном репозитории) ну и на git config --global core.excludesfile ~/.gitexcludes обратить внимание.

Наполняем наш репозиторий существующими файлами содаём репозиторий из имеющихся файлов:

~/zlatov.net/git/public_html $ git commit -m "Импорт"
[master (root-commit) 315b5ba] Импорт
 2 files changed, 11 insertions(+), 0 deletions(-)
 create mode 100644 .gitignore
 create mode 100644 index.html

Hub

Hub — bare-репозиторий. Все репозитории разработчиков клонируются именно от него.

Где-нибудь вне рабочего каталога сайта (например, на уровень выше) создадим bare-репозиторий:

~/zlatov.net/git/public_html $ cd ..
~/zlatov.net/git $ mkdir html.git
~/zlatov.net/git $ cd html.git
~/zlatov.net/git/html.git $ git --bare init
Initialized empty Git repository in /home/w/imuser/zlatov.net/git/html.git/

Ну вот, ещё один пустой репозиторий, давайте наполним его, т.е. зайдём в прайм репозиторий добавим к нему удалённый репозиторий (hub) и вольем в него содержимое ветки master:

~/zlatov.net/git/html.git $ cd ../public_html
~/zlatov.net/git/public_html $ git remote add hub ~/zlatov.net/git/html.git
~/zlatov.net/git/public_html $ git remote
hub
~/zlatov.net/git/public_html $ git remote show hub
* remote hub
  Fetch URL: /home/w/imuser/zlatov.net/git/html.git
  Push  URL: /home/w/imuser/zlatov.net/git/html.git
  HEAD branch: (unknown)
~/zlatov.net/git/public_html $ git remote show
hub
~/zlatov.net/git/public_html $ git log
~/zlatov.net/git/public_html $ git log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short
~/zlatov.net/git/public_html $ git push hub master
Counting objects: 4, done.
Delta compression using up to 24 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 383 bytes, done.
Total 4 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
To /home/w/imuser/zlatov.net/git/html.git
 * [new branch]      master -> master

Хуки

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

Одно из основных правил при работе с Git — никогда не делайте push в репозтирий, у которого есть рабочая копия. Мы следуем этому правилу и создали репозиторий «Hub». Вместо того, чтобы делать push из Hub, который никак не повлияет на рабочую копию, мы будем использовать хук, который заставит Prime выполнить pull из Hub-репозитория.

Post-update — в Hub-репозитории

Как только в Hub поступит новая порция изменений, сразу будет выполнен этот скрипт. Мы переходим в рабочий каталог Prime-репозитория, и вытягиваем измениния из Hub'а. Проталкивание изменений (push) не изменяет состояния рабочего каталога репозитория, поэтому и нужно делать pull, находясь в рабочем каталоге.

Было:

#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".

exec git update-server-info

Стало:

#!/bin/sh

echo
echo "**** Вытягиваем изменения в Prime [Hub's post-update hook]"
echo

cd ~/zlatov.net/git/public_html || exit
unset GIT_DIR
git pull hub master

exec git update-server-info

Заходим в хуки переименовываем нужный файл и правим его:

~/zlatov.net/git/html.git $ cd hooks
~/zlatov.net/git/html.git/hooks $ ls
applypatch-msg.sample  post-update.sample     prepare-commit-msg.sample
commit-msg.sample      pre-applypatch.sample  update.sample
post-commit.sample     pre-commit.sample
post-receive.sample    pre-rebase.sample
~/zlatov.net/git/html.git/hooks $ mv post-update.sample post-update
~/zlatov.net/git/html.git/hooks $ ls
applypatch-msg.sample  post-update            prepare-commit-msg.sample
commit-msg.sample      pre-applypatch.sample  update.sample
post-commit.sample     pre-commit.sample
post-receive.sample    pre-rebase.sample
~/zlatov.net/git/html.git/hooks $ cat post-update
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".

exec git update-server-info
~/zlatov.net/git/html.git/hooks $ cat > post-update
#!/bin/sh

echo
echo "****    Prime [Hub's post-update hook]"
echo

cd ~/zlatov.net/git/public_html || exit
unset GIT_DIR
git pull hub master

exec git-update-server-info
~/zlatov.net/git/html.git/hooks $ cat post-update
#!/bin/sh

echo
echo "****    Prime [Hub's post-update hook]"
echo

cd ~/zlatov.net/git/public_html || exit
unset GIT_DIR
git pull hub master

exec git-update-server-info
~/zlatov.net/git/html.git/hooks $

Post-commit — в Prime-репозитори

Этот скрипт запускается после каждого коммита в Prime-репозитории и проталкивает изменения в Hub. В идеальном мире, конечно, мы вообще никогда ничего не будем править прямо на сервере. Но в нашем несовершенном мире возможно всё, что угодно, поэтому давайте автоматизируем процесс проталкивания изменений, чтобы не разрушать историю проекта и избежать возможных конфликтов.

Надо:

#!/bin/sh

echo
echo "**** pushing changes to Hub [Prime's post-commit hook]"
echo

git push hub

Делаем:

~/zlatov.net/git/html.git/hooks $ cd ../../public_html/.git/hooks
~/zlatov.net/git/public_html/.git/hooks $ ls
applypatch-msg.sample  post-update.sample     prepare-commit-msg.sample
commit-msg.sample      pre-applypatch.sample  update.sample
post-commit.sample     pre-commit.sample
post-receive.sample    pre-rebase.sample
~/zlatov.net/git/public_html/.git/hooks $ mv post-commit.sample post-commit
~/zlatov.net/git/public_html/.git/hooks $ cat post-commit
#!/bin/sh
#
# An example hook script that is called after a successful
# commit is made.
#
# To enable this hook, rename this file to "post-commit".

: Nothing
~/zlatov.net/git/public_html/.git/hooks $ cat > post-commit
#!/bin/sh

echo
echo "**** pushing changes to Hub [Prime's post-commit hook]"
echo

git push hub
~/zlatov.net/git/public_html/.git/hooks $ cat post-commit
#!/bin/sh

echo
echo "**** pushing changes to Hub [Prime's post-commit hook]"
echo

git push hub
~/zlatov.net/git/public_html/.git/hooks $

Решение конфликтов

Также я обнаружил, что если конфликт возникает вследствие того, что изменения в Prime не могут быть объединены с Hub'ом, то наилучшим решением будет протолкнуть текущее состояние Prime'а в новую ветку на Hub. Эта команда, выполненная из рабочего каталога Prime создаст удалённую ветку «fixme», основанную на текущем стоянии Prime-репозитория.

$ git push hub master:refs/heads/fixme

Закрыть доступ к каталогу .git на сервере

~ $ cd zlatov.net/git/public_html/.git
~/zlatov.net/git/public_html/.git $ ls
COMMIT_EDITMSG  HEAD       config       hooks  info  objects
FETCH_HEAD      ORIG_HEAD  description  index  logs  refs
~/zlatov.net/git/public_html/.git $ ls -la
total 56
drwxr-x---  7 imuser customers 4096 Aug 27 22:51 .
drwxr-xr-x  4 imuser customers 4096 Aug 27 21:00 ..
-rw-r--r--  1 imuser customers    0 Aug 27 22:51 .htaccess
-rw-r-----  1 imuser customers   13 Aug 27 18:21 COMMIT_EDITMSG
-rw-r--r--  1 imuser customers   98 Aug 27 21:00 FETCH_HEAD
-rw-r-----  1 imuser customers   23 Aug 27 12:59 HEAD
-rw-r--r--  1 imuser customers   41 Aug 27 21:00 ORIG_HEAD
-rw-r-----  1 imuser customers  197 Aug 27 18:40 config
-rw-r-----  1 imuser customers   73 Aug 27 12:59 description
drwxr-x---  2 imuser customers 4096 Aug 27 19:38 hooks
-rw-r--r--  1 imuser customers  192 Aug 27 21:00 index
drwxr-x---  2 imuser customers 4096 Aug 27 21:00 info
drwxr-x---  3 imuser customers 4096 Aug 27 18:21 logs
drwxr-x--- 14 imuser customers 4096 Aug 27 21:00 objects
drwxr-x---  5 imuser customers 4096 Aug 27 18:46 refs
~/zlatov.net/git/public_html/.git $ cat > .htaccess
Order Deny,Allow
Deny from all
~/zlatov.net/git/public_html/.git $ cat .htaccess
Order Deny,Allow
Deny from all

Клонируем Бар репозиторий на локальную машину

Подробнее о clone тут: 2.1 Основы Git - Создание Git-репозитория

/c/Servers/somepath/zlatov.net/git/public_html
$ git clone zlatov:~/zlatov.net/git/html.git ../public_html
Cloning into '../public_html'...
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (4/4), done.
Checking connectivity... done.

/c/Servers/somepath/zlatov.net/git/public_html (master)
$ git remote show origin
* remote origin
  Fetch URL: zlatov:~/zlatov.net/git/html.git
  Push  URL: zlatov:~/zlatov.net/git/html.git
  HEAD branch: master
  Remote branch:
    master tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

/c/Servers/somepath/zlatov.net/git/public_html (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean

Вносим изменения, коммитим:

/c/Servers/somepath/zlatov.net/git/public_html (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   index.html

no changes added to commit (use "git add" and/or "git commit -a")

/c/Servers/somepath/zlatov.net/git/public_html (master)
$ git add .

/c/Servers/somepath/zlatov.net/git/public_html (master)
$ git commit -m "buhaha"
[master 9caca6c] buhaha
 1 file changed, 9 insertions(+), 9 deletions(-)

/c/Servers/somepath/zlatov.net/git/public_html (master)
$ git hist
* 9caca6c 2014-08-27 | buhaha (HEAD, master) [Maksim Zlatov]
* 315b5ba 2014-08-27 | Импорт (origin/master, origin/HEAD) [Maksim Zlatov]

Пушим на Бар репозиторий:

/c/Servers/somepath/zlatov.net/git/public_html (master)
$ git push
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

When push.default is set to 'matching', git will push local branches
to the remote branches that already exist with the same name.

In Git 2.0, Git will default to the more conservative 'simple'
behavior, which only pushes the current branch to the corresponding
remote branch that 'git pull' uses to update the current branch.

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 395 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote:
remote: ****    Prime [Hub's post-update hook]
remote:
remote: From /home/w/imuser/zlatov.net/git/html
remote:  * branch            master     -> FETCH_HEAD
remote: Updating 315b5ba..9caca6c
remote: Fast-forward
remote:  index.html |   18 +++++++++---------
remote:  1 files changed, 9 insertions(+), 9 deletions(-)
To zlatov:~/zlatov.net/git/html.git
   315b5ba..9caca6c  master -> master

Смотрим на рабочий проект и убеждаемся что сработал хук.

Про удаление и переименование удалённых репозиториев тут: 2.5 Основы Git - Работа с удалёнными репозиториями


Добавить комментарий

2010–2018 Блог Максима Златова, контакты

PHP execution time: 0.0065 s.
SQL execution time: 0.0008 s. (select publication with comments)

Яндекс.Метрика