Поднимаем http-репозитарий для git
После покупки ноутбука и организации небольшой домашней сети появилась проблема — как синхронизировать проекты на разных комьютерах? Решение очевидно — сделать из одного из них центральный хаб.
Git предоставляет несколько способов организации общего доступа к хранилищам. Сначала я попробовал способ с gitosis — не понравился. Там используется довольно мутный механизм авторизации и организации хранилища. В общем, остановился на Apache + gitweb.
В данном способе apache используется git для доступа к хранилищам по протоколу http, а gitweb организует удобный просмотр проектов через браузер. Способ привлек минимумом необходимых компонентов. Apache и git у меня и так установлены, а gitweb — это всего лишь скрипт на perl и входит стандартную поставку git. Кстати, вместо него можно ипользовать cgit — то же самое, только написан на C.
Руководств по настройке подобной связки в интернете полно. Но вопросы все равно возникают. Поэтому в статье я попытаюсь дать помимо готовых настроек еще и методики поиска проблем и некоторый объем теории.
1. Для Apache понадобятся дополнительные модули mod_rewrite, mod_dav, mod_dav_fs, mod_env. Остальные, вроде mod_auth — по желанию
2. Настраиваем базовый виртуальный хост, у меня www.github.local
3. Cоздаем в DOCUMENT_ROOT виртуального хоста каталог для проектов. Я назвал его ./git
Для базовой работы с git достаточно, но это не интересно. Все, что будем делать в дальнейшем нужно для развязывания обращений git к репозитариям и браузера к gitweb. Другими словами, необходимо чтобы на запросы git к репозитарию не отвечал gitweb и наоборот.
Это довольно неочевидный момент, который практически не упоминают в руководствах. Я долго был уверен, что gitweb как раз и обрабатывает подключения git-клиентов, а возможность просмотра репозитариев — просто приятное дополнение.
Обратите внимание, uri всех дополнительных файлов gitweb (стили, лого, скрипты) указываются относительно каталога gitweb и при настройке хостинга мы укажем соответствущий алиас.
В качестве альтернативы можно предложить просто скопировать gitweb в DOCUMENT_ROOT хоста, тогда бы все это делать не пришлось, но потерялась бы возможность автоматического обновления.
Далее стоит проверить, чтобы в конфигрурации apache была задан путь для базы данных mod_dav — DAVLockDB, такой файл существует и доступен для записи. Обычно с этим все в порядке, но проверить не помешает.
Первые несколько строк должны быть понятны — просто настройка путей и имен.
Дальше уже интереснее — устанавливаем переменную окружения GITWEB_CONFIG, которая сообщает gitweb расположение файла конфигурации и создаем алиас на реальный каталог gitweb.
Теперь самое важное. Настройка RewriteEngine.
Главную страничку будет генерировать gitweb:
Смысл следующих строк в том, что apache должен выполнять скрипт gitweb для всех запросов, кроме тех, что направлены непосредственно к реальным файлам каталогам проектов.
Теоретически, для этого было бы достаточно !-f !-d, но это не совсем так и я потратил довольно много времени на выяснение причин. Дело в том, что при выполнении push-а в удаленный репозитарий git отправляет запросы к mod_dav на блокировку некоторых файлов и каталогов, но они не всегда в этот момент существуют! А раз их нет, то apache с полным правом перенаправляет эти запросы к gitweb и в результате получаем ерунду. Так что третье RewriteCond нужно использовать обязательно!
Для авторизованного доступа к репозитариям необходимо в раздел Location следующие строки:
Но после этого необходимо зайти в myproject.git/hooks и скопировать (или перименовать) файл post-update.example в post-update. Проверьте, чтобы он был исполняемым. Это задаст обработчик, вызываемый после обновления репозитария. Если этого не сделать, при выполнении push изменения в хранилище передадутся, но все указатели HEAD не изменятся, что потом может привести к конфликтам.
1. Включите логирование всего с максимальной подробностью (в конфиге выше это сделано)
2. Попробуйте работу git-а без всяких RewriteRule, чтобы убедиться что все доступы и базовые настройки выполенены паравильно
3. После добавления RewriteRule, в случае каких-либо проблем изучайте лог mod_rewrite. Особенно стоит обращать внимание на служебные запросы git — MKCOL, LOCK, UNLOCK и т.п. Подавляющее большинство ошибок, по крайней мене у меня, состояло в том, что такие запросы обрабатывал gitweb, вместо самого apache
4. Если вы используете авторизованный доступ — попробуйте его отключить на время
Также, я думаю, можно упростить и конфигурационный файл apache, в частности, избавиться от RewriteCondition вообще, а все необходимые условия указывать сразу в RewriteRule.
Но, надеюсь, помог кому-нибудь разобраться с основными принципами, и теперь настроить все необходимое самостоятельно не стоставит труда.
https://git.wiki.kernel.org/index.php/Gitweb — официальный сайт gitweb. Есть подробные описания и примеры настроек.
Git предоставляет несколько способов организации общего доступа к хранилищам. Сначала я попробовал способ с gitosis — не понравился. Там используется довольно мутный механизм авторизации и организации хранилища. В общем, остановился на Apache + gitweb.
В данном способе apache используется git для доступа к хранилищам по протоколу http, а gitweb организует удобный просмотр проектов через браузер. Способ привлек минимумом необходимых компонентов. Apache и git у меня и так установлены, а gitweb — это всего лишь скрипт на perl и входит стандартную поставку git. Кстати, вместо него можно ипользовать cgit — то же самое, только написан на C.
Руководств по настройке подобной связки в интернете полно. Но вопросы все равно возникают. Поэтому в статье я попытаюсь дать помимо готовых настроек еще и методики поиска проблем и некоторый объем теории.
Начало
Устанавливаем, если еще нет, Apache, git1. Для Apache понадобятся дополнительные модули mod_rewrite, mod_dav, mod_dav_fs, mod_env. Остальные, вроде mod_auth — по желанию
2. Настраиваем базовый виртуальный хост, у меня www.github.local
3. Cоздаем в DOCUMENT_ROOT виртуального хоста каталог для проектов. Я назвал его ./git
Немного теории
В принципе, на этом можно было бы остановиться.Для базовой работы с git достаточно, но это не интересно. Все, что будем делать в дальнейшем нужно для развязывания обращений git к репозитариям и браузера к gitweb. Другими словами, необходимо чтобы на запросы git к репозитарию не отвечал gitweb и наоборот.
Это довольно неочевидный момент, который практически не упоминают в руководствах. Я долго был уверен, что gitweb как раз и обрабатывает подключения git-клиентов, а возможность просмотра репозитариев — просто приятное дополнение.
Настраиваем gitweb
Здесь ничего сложного нет, просто создаем файл со следующим содержанием:my_uri = "http://www.github.local/git"; # адрес репозиториев $site_name = "www.github.local"; # название сайта, отображается в заголовке $projectroot = "/home/www/github/git/"; # путь к репозиториям git на жёстком диске $git_temp = "/tmp"; $home_link = $my_uri; # ссылка на «домашнюю страничку» $projects_list = $projectroot; $stylesheet = "/gitweb/static/gitweb.css"; $logo = "/gitweb/static/git-logo.png"; $favicon = "/gitweb/static/git-favicon.png"; $projects_list_description_width = 40; $javascript = "/gitweb/static/gitweb.js"; $feature{'pathinfo'}{'default'} = [1];Я назвал его gitweb.conf и поместил в DOCUMENT_ROOT. Не самое удачное решение, но у меня локальная сеть из 2-х компьютеров и проблем с безопасностью я не ожидаю.
Обратите внимание, uri всех дополнительных файлов gitweb (стили, лого, скрипты) указываются относительно каталога gitweb и при настройке хостинга мы укажем соответствущий алиас.
В качестве альтернативы можно предложить просто скопировать gitweb в DOCUMENT_ROOT хоста, тогда бы все это делать не пришлось, но потерялась бы возможность автоматического обновления.
Далее стоит проверить, чтобы в конфигрурации apache была задан путь для базы данных mod_dav — DAVLockDB, такой файл существует и доступен для записи. Обычно с этим все в порядке, но проверить не помешает.
Настраиваем Apache
Файл с настройкой виртуального хоста выглядит так:<VirtualHost *:80> DocumentRoot "/home/www/github" ServerName www.github.local ErrorLog "/var/log/httpd/github-error_log" CustomLog "/var/log/httpd/github-access_log" combined LogLevel debug SetEnv GITWEB_CONFIG /home/www/github/gitweb.conf Alias /gitweb /usr/share/gitweb/ RewriteEngine On RewriteLogLevel 9 RewriteLog "/var/log/httpd/github-rewrite_log" RewriteRule ^/$ /cgi-bin/gitweb.cgi [L,PT] # Переписываем не для реальных файлов и каталогов. По идее, должно работать и без DOCUMENT_ROOT, но почему-то не работает RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d # исключаем из подстановки системные объекты git - к ним обращаемся непосредственно RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !/git/[a-zA-Z0-9-]+\.git/(HEAD|info|objects|refs) # PT - очень важно! Иначе не происходит подстановка Alias-а, и все ссылается на каталог DocumentRoot RewriteRule ^/git/(.*) /cgi-bin/gitweb.cgi/$1 [PT] # Эта штука обязательно после RewriteRule - почему, см. выше ScriptAlias /cgi-bin/ /usr/share/gitweb/ <Directory "/home/www/github/"> Options Indexes FollowSymlinks ExecCGI Order allow,deny Allow from all </Directory> <Location "/git"> Dav On </Location> </VirtualHost>
Первые несколько строк должны быть понятны — просто настройка путей и имен.
Дальше уже интереснее — устанавливаем переменную окружения GITWEB_CONFIG, которая сообщает gitweb расположение файла конфигурации и создаем алиас на реальный каталог gitweb.
Теперь самое важное. Настройка RewriteEngine.
Главную страничку будет генерировать gitweb:
RewriteRule ^/$ /cgi-bin/gitweb.cgi [L,PT]
Смысл следующих строк в том, что apache должен выполнять скрипт gitweb для всех запросов, кроме тех, что направлены непосредственно к реальным файлам каталогам проектов.
Теоретически, для этого было бы достаточно !-f !-d, но это не совсем так и я потратил довольно много времени на выяснение причин. Дело в том, что при выполнении push-а в удаленный репозитарий git отправляет запросы к mod_dav на блокировку некоторых файлов и каталогов, но они не всегда в этот момент существуют! А раз их нет, то apache с полным правом перенаправляет эти запросы к gitweb и в результате получаем ерунду. Так что третье RewriteCond нужно использовать обязательно!
# Переписываем не для реальных файлов и каталогов. По идее, должно работать и без DOCUMENT_ROOT, но почему-то не работает RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d # исключаем из подстановки системные объекты git - к ним обращаемся непосредственно RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !/git/[a-zA-Z0-9-]+\.git/(HEAD|info|objects|refs) # PT - очень важно! Иначе не происходит подстановка Alias-а, и все ссылается на каталог DocumentRoot RewriteRule ^/git/(.*) /cgi-bin/gitweb.cgi/$1 [PT]Здесь везде используются флаги PT для RewriteRule. Этот флаг означает, что Apache после подстановки адреса в самом правиле также применит и следующую команду из конфиг-а. В данном случае это ScriptAlias /cgi-bin/ /usr/share/gitweb/. Т.о. эта опция обязательно должна идти после всех RewriteRule.
Для авторизованного доступа к репозитариям необходимо в раздел Location следующие строки:
AuthType Basic AuthName "Git" AuthUserFile "/home/www/github/passwd.git" <LimitExcept GET HEAD PROPFIND OPTIONS REPORT> Require valid-user </LimitExcept>B создать файл паролей. Также может потребоваться создать файл .netrc в домашнем каталоге пользователя для получения доступа к серверу вообще, а не к репозитариям. Правда нет смысла требовать авторизацию при доступе на чтение, т.к. содержимое проектов можно получить и через gitweb.
Создание репозитария
Здесь есть одна тонкость. Cам репозитарий содается, как обычноgit init --bare myproject.git
Но после этого необходимо зайти в myproject.git/hooks и скопировать (или перименовать) файл post-update.example в post-update. Проверьте, чтобы он был исполняемым. Это задаст обработчик, вызываемый после обновления репозитария. Если этого не сделать, при выполнении push изменения в хранилище передадутся, но все указатели HEAD не изменятся, что потом может привести к конфликтам.
Отладка
Все это замечательно, но, как правило, сразу все не заработает, и нужно будет искать причину. Вот несколько советов.1. Включите логирование всего с максимальной подробностью (в конфиге выше это сделано)
2. Попробуйте работу git-а без всяких RewriteRule, чтобы убедиться что все доступы и базовые настройки выполенены паравильно
3. После добавления RewriteRule, в случае каких-либо проблем изучайте лог mod_rewrite. Особенно стоит обращать внимание на служебные запросы git — MKCOL, LOCK, UNLOCK и т.п. Подавляющее большинство ошибок, по крайней мене у меня, состояло в том, что такие запросы обрабатывал gitweb, вместо самого apache
4. Если вы используете авторизованный доступ — попробуйте его отключить на время
Заключение
Некоторые моменты в этой статье я не осветил. В частности, почти не затронуты вопросы авторизации, возможности доступа не по паролю, а по ключу.Также, я думаю, можно упростить и конфигурационный файл apache, в частности, избавиться от RewriteCondition вообще, а все необходимые условия указывать сразу в RewriteRule.
Но, надеюсь, помог кому-нибудь разобраться с основными принципами, и теперь настроить все необходимое самостоятельно не стоставит труда.
Ссылки
http://habrahabr.ru/blogs/Git/43806/ — отсюда я начал свои попытки настроить сервер, и отсюда же взял основы для файлов конфигурации.https://git.wiki.kernel.org/index.php/Gitweb — официальный сайт gitweb. Есть подробные описания и примеры настроек.
0 комментариев