Git – это распределённая система контроля версий (Version Control System или же VCS). На первый взгляд может показаться, что её можно использовать только в применении к программированию, но это не совсем так.

Да, заниматься программированием без какой-либо системы VCS – это признак низкой квалификации. Можно провести аналогию между таким программистом и системным администратором, не делающим резервные копии своих серверов. Оба имеют работу только до первой потери данных.

Но применение VCS вообще и Git в частности гораздо шире, чем область программирования. Если что-то требует слежения за версионностью, то потенциально к нему можно использовать VCS. В качестве примера могу привести систему etckeeper, которая хранит в VCS (git, bazaar, mercurial, etc) изменения в конфигурационных файлах /etc.

При применении VCS нужно использовать здравый смысл – желательно не хранить в VCS часто изменяемые большие бинарные данные вроде видео.

Для git очень желательно использовать внешний репозиторий (можно хранить данные в локальном репозитории, находящемся в каталоге с данными, но в случае выхода из строя диска никакая версионность не спасёт).

Я использовал для этого популярный сервис GitHub. При всех достоинствах у него есть и недостатки. Если вы работаете над публичными проектами, то он бесплатен. Но если же вы хотите иметь приватный репозиторий, к которому не будет иметь доступ любой желающий, то за это уже нужно платить. Самый дешёвый план Micro с 5 приватными репозиториями и не слишком большим дисковым пространством (сейчас на странице заказа не указывается размер, раньше вроде было порядка 600 MB) стоит $7 в месяц.

Деньги небольшие, но если по какой-то причине нужно хранить гораздо больше данных (например, web-сайт с файлами изображений), то придётся раскошелиться.

Решение есть. Можно организовать “self-hosted git repository” используя gitosis.

Внешний репозиторий подразумевает запуск его на внешнем сервере. К сожалению, у меня нет сервера под Mac OS X, располагающемся на внешнем хостинге, поэтому я нарушу тематику блога и расскажу, как установить gitosis на Ubuntu Server 9.04. Если вам нужен именно Mac OS X, то посмотрите, например, статью “Разворачиваем сервер git на Mac OS X Leopard”.

Я проводил настройку, отталкиваясь от книги “Pro Git. Professional version control“. Она бесплатна и рекомендована сервисом GitHub для ознакомления с git.

Установка

Итак, начинаем. Напоминаю – я использую Ubuntu Server 9.04, но процесс практически такой же и для других версий или дистрибутивов Debian (должен сказать, что на Debian Sid я не смог добавить первый публичный ключ через gitosis-init).

Обновляем пакеты и ставим нужные пакеты. python-setuptools поставил за компанию, достаточно было бы поставить просто gitosis.

$ sudo aptitude update
$ sudo aptitude install python-setuptools
$ sudo aptitude install gitosis

Первые настройки я буду производить с самого сервера, где стоит gitosis. Я делаю “sudo -s”, так как у меня были некоторые странности при добавлении первого ключа под обычным пользователем. Вместо /home/ctrld/.ssh/id_rsa.pub подставьте свой публичный ключ. Если вы его ещё не сгенерировали, то можете сделать это по инструкции под Linux или Mac OS X.

$ sudo -s
# sudo -H -u gitosis gitosis-init < /home/ctrld/.ssh/id_rsa.pub
Initialized empty Git repository in /srv/gitosis/repositories/gitosis-admin.git/
Reinitialized existing Git repository in /srv/gitosis/repositories/gitosis-admin.git/

Проверяем. Если получен “ERROR:gitosis.serve.main”, то всё в порядке:

$ ssh gitosis@git.host.com
ERROR:gitosis.serve.main:Need SSH_ORIGINAL_COMMAND in environment.
Connection to git.host.com closed.

Настройка

Перед началом работы с Git на клиентской стороне очень желательно настроить окружение. Об этом можно прочитать в моей статье “Установка Git под Mac OS X“.

Настройка заключается в клонировании системного репозитория gitosis-admin с настройками, их изменение, а затем возвращение их обратно.

$ mkdir ~/tmp
$ cd ~/tmp
$ git clone gitosis@git.host.com:gitosis-admin.git
$ cd gitosis-admin

Добавляем проект, например, Notes

$ vim gitosis.conf
[group writers]
writable = Notes
members = oserdyukov@gmail.com

Я создал группу writers, куда будут иметь люди, работающие с проектом Notes.

Записываем изменения в конфигурации обратно на сервер.

$ git commit -am 'add project Notes and group writers'
$ git push

Создание проекта

$ mkdir ~/Notes
$ cd ~/Notes
$ git init
$ touch Readme
$ git add Readme
$ git commit -a -m "Initial commit"

Указание внешнего репозитория и push проекта в него:

$ git remote add origin gitosis@git.host.com:Notes.git
$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 214 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To gitosis@git.host.com:Notes.git
 * [new branch]      master -> master

Добавление пользователя

Для добавления пользователя нужно внести изменения в системный репозиторий, а именно добавить публичный ключ и внести пользователя в gitosis.conf.

$ cd tmp/gitosis-admin/
$ git pull origin master

Я записал публичный ключ пользователя в файл ~ctrld/ole-desktop.pub. Добавляю его:

$ cp ~ctrld/ole-desktop.pub keydir/ole\@ole-desktop.host.com.pub
$ git add keydir/ole\@ole-desktop.host.com.pub

В gitosis имя пользователя определяется по имени файла в keydir, поэтому именование зависит от администратора. Я указал псевдо-email вида ole@ole-desktop.host.com.

Добавляем нового пользователя в группу (обратите внимание на то, что пользователи разделяются пробелами, а не запятыми):

$ vim gitosis.conf
[group writers]
writable = Notes
members = oserdyukov@gmail.com ole@ole-desktop.host.com

Commit и push в удалённый репозиторий:

$ git commit -am 'add user ole@ole-desktop.host.com and assign him to project Notes'
$ git push origin master

Проверяем под видом нового пользователя с его компьютера:

$ ssh gitosis@git.host.com
ERROR:gitosis.serve.main:Need SSH_ORIGINAL_COMMAND in environment.
Connection to git.host.com closed.

Новый пользователь клонирует репозиторий и начинает работу с ним:

$ git clone gitosis@git.host.com:Notes.git
$ cd Notes
$ echo "Hello, I am ole@deskop" >> Readme
$ git status
#       modified:   Readme
$ git commit -a -m "ole@desktop changes"
$ git push origin master

На другой системе проверяем, внеслись ли изменения:

$ cd ~/Notes
$ git pull origin master
...
Fast forward
 Readme |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
$ cat Readme
Hello, I am ole@deskop

Всё работает, можно пользоваться.

Для улучшения безопасности в конфигурации sshd можно разрешить только определённых пользователей, включая gitosis (имена тоже разделяются пробелами, а не запятыми):

$ vim /etc/ssh/sshd_config
AllowUsers ctrld gitosis

Если вы используете сервере sshd на нестандартном порту, то нужно прописать это в .ssh/config:

$ vim ~/.ssh/config
Host git.host.com
        Port 2222