В данной заметке я расскажу о моём опыт работы с системами контроля версий, а также о том почему я выбрал git, как установил его и gitosis и как их настроил.
Пропустить теорию и перейти к практике.
1. Что такое git?
Git — распределённая система контроля версий файлов. Подробнее можно прочитать в Википедии.
Если же попытаться объяснить в двух словах зачем это нужно, то я бы сделал это так. Предположим вы один реализуете какой-то программный проект. Одна из ключевых стадий — кодирование. Предположим что вы сегодня внесли какие-то изменения в некий файл своего проекта, причём не добавили что-то, а наоборот удалили. Спустя два месяца, вы поняли то что вы когда-то удалили вам бы сейчас очень пригодилось. Если проект разрабатывался без системы контроля версий, то вам пришлось бы искать в резервных копиях (Кстати, а знаете ли вы что люди делятся на тех кто не делает резервные копии и тех кто уже делает резервные копии? Вы к кому относитесь?) нужный архив и из него восстанавливать нужный код. Но если же у вас была система контроля версий, то восстановить утерянный код не составит никакого труда, так как эти системы в общем (но не только) для этого и предназначены.
А теперь представьте что вы работает не один, а в команде. Как уследить за всеми изменениями, производимыми другими членами команды, и как не удалить их код своим? Правильно — нужно использовать систему управления версиями файлов.
Добавлено 4 марта 2011 04:41
Очень полезная статья для новичков Git меняет правила игры в распределенной Web-разработке.
1.1. Git не единственный?
Нет, конечно же git не единственная система контроля(управления) версиями файлов.
Об отличиях и преимуществах git над другими система данного класса написано много статей, а вся их суть, на мой взгляд, высказана на сайте Why Git is Better Then X (eng).
2. Для чего git понадобился мне
Я в силу своей профессии тоже пишу программный код. Есть проект над которым в данном направлении я работаю один, но из разных мест: офис, дом. И переносить исходный код с компьютера на компьютер в ручную мне надоело, да и делается это всё сложнее и сложнее в связи с разрастанием проекта.
Раньше в одном из проектов, над которым тоже работал один, я использовал svn. Но меня очень сильно раздражало наличие в каждом каталоге моего проекта папки .svn . Да и ветвление в svn мне не очень нравилось, хотя не исключаю что я его мог не правильно использовать.
В результате я решил использовать в текущем проекте git.
2.1. Начало знакомства
У git есть официальный сайт с гигантской документацией и не очень понятным учебным пособием, особенно если учесть что хотелось сначала не научиться пользоваться git, а понять как же я его смогу использовать в своём проекте.
На просторах Хабра я наткнулся на несколько статей, которые мне помогли разобраться с тем что такое git и как его правильно готовить за очень короткое время:
Без их прочтения и осмысления дальше лучше не идти.
3. Установка и настройка git и gitosis
В данном разделе я перескажу процесс установки git и gitosis, описанный на многих сайтах, с моими комментариями.
3.1. Подготовка к установке
В процессе установки нам понадобится сервер (server), две рабочие станции — компьютер (comp) и, предположим, ноутбук (note).
3.2. Установка git
3.2.1. Сам git устанавливается одной строчкой:
sudo apt-get install git-core
Установку нужно произвести на всех компьютерах, которые будут работать с git.
3.3. Установка и настройка gitosis на сервере
Для более удобной работы с git есть набор скриптов под названием gitosis, которые позволяют легко управлять несколькими хранилищами и ограничивать права доступа к ним разным людям.
Естественно, можно обойтись и без них, но после серии тестов я решил, что с ними работать удобнее.
Итак, приступим.
ЗАМЕЧАНИЕ: команды идут после знака $
3.3.1. Установим необходимые пакеты для работы с python скриптами:
serg@server:~$ sudo apt-get install python-setuptools
3.3.2. Создадим и перейдём в папку для хранения исходных кодов gitosis:
serg@server:~$ mkdir src serg@server:~$ cd src
3.3.3. Теперь получим исходные коды последней версии gitosis из официального хранилища проекта и перейдём в папку с ними:
serg@server:~/src$ git clone git://github.com/tv42/gitosis.git serg@server:~/scr$ cd gitosis
Обновление от 23 января 2013.
Раньше для клонирования gitosis использовалась команда: git clone git://eagain.net/gitosis.git
3.3.4. Устанавливаем скрипты gitosis в систему:
serg@server:~/src/gitosis$ sudo python setup.py install
3.3.4.а. В общем-то теперь можно вернуться в домашний каталог и удалить исходные коды, они нам больше не нужны:
serg@server:~/src/gitosis$ cd ~ serg@server:~$ rm -rf src
Теперь важный момент, который описывался только в одном руководстве по установке gitosis из множества, что я перечитал, но и то вскользь: есть пользователи ОС, а есть пользователи git. Это разные пользователи! Для ОС пользователи git не существуют! Пользователи git определяются ключами авторизации.
Во всех инструкциях по установке git я видел, что создаётся новый пользователь с именем git и потом все действия выполняются через него. На самом деле этого можно не делать и установить git в домашнюю директорию любого пользователя ОС. Но в этом случае в файле ~/.ssh/authorized_keys этого пользователя не должно быть никаких других записей или они должны быть закомментированы!
3.3.5. Если кто-то хочет, то может создать нового пользователя и домашний каталог для git:
serg@server:~$ sudo adduser --system --shell /bin/sh --gecos 'git version control' --group --disabled-password --home /home/git git
ЗАМЕЧАНИЕ: Если в настройках ssh (/etc/ssh/sshd_config) у вас есть список AllowUsers, то нужно туда добавить и этого пользователя (разделителем для разрешённых имён пользователя является пробел)! После этого нужно перезапустить ssh сервер: serg@server:~$ sudo /etc/init.d/ssh restart
3.3.6. Если у вас уже есть ключ авторизации для вашего пользователя, то можно перейти к следующему шагу, а если вы создали нового пользователя или хотите создать новый ключ авторизации, то выполняем:
serg@server:~$ ssh-keygen -t dsa
В ssh-keygen можно создавать ключи с алгоритмом dsa и rsa. dsa используются в качестве подписи, а rsa в основном для шифрования данных. Так как мы собираемся всего лишь отличать одного пользователя от другого, а не шифровать данные, то можно использовать dsa.
После того как ключи были созданы. можно устанавливать gitosis.
3.3.7.а. Если вы создали нового пользователя с именем git, то выполните:
serg@server:~$ sudo -H -u git gitosis-init < путь_к_папке_с_ключами/название_ключа.pub
3.3.7.б. Если же вы устанавливаете gitosis из под текущего пользователя, то вам подходит:
serg@server:~$ gitosis-init < путь_к_папке_с_ключами/название_ключа.pub
Ключ авторизации можно было создать и на клиентской машине, с которой будете управлять gitosis, а потом передать его публичную часть (.pub) на сервер. Но если вы создали ключи на сервере, то не забудьте забрать секретную часть ключа (без расширения) на клиентскую машину.
3.3.8. Теперь нужно установить правильные права доступа на определённый каталог (этот шаг необходим из-за особенностей python в разных дистрибутивах):
serg@server:~$ sudo chmod 755 /home/имя_пользователя/repositories/gitosis-admin.git/hooks/post-update
На этом установка и настройка сервера, по мнению многих руководств, завершена. Я бы посоветовал сделать ещё одно действие.
3.3.9. Установить уровень вывода информации gitosis в положение DEBUG:
serg@server:~$ sudo nano .gitosis.conf
Текст в этом файле должен выглядеть так:
[gitosis]
loglevel = DEBUG
[group gitosis-admin]
writable = gitosis-admin
members = serg@server
ЗАМЕЧАНИЕ: Если вы создавали пользователя, то путь к файлу будет другим! Но такой файл всё равно должен быть в корневой директории того пользователя в чью домашнюю папку устанавливался gitosis.
Вот теперь переходим на рабочую станцию, с которой будем управлять хранилищами.
3.4. Настройка gitosis на клиенте (рабочей станции)
Секретная часть ключа авторизации, который был создан на сервере (п.3.3.6.), должна быть в папке ~/.ssh/ пользователя рабочей станции от чьего имени будут управляться gitosis.
ЗАМЕЧАНИЕ: Если порт сервера отличается от стандартного или вы связываетесь с сервером в локальной сети по IP, а хотите по имени, то можно добавить в папку ~/.ssh/ конфигурационный файл config:
Host server User serg Port 9876 IdentityFile ~/.ssh/serg_dsa
В случае замены IP адреса на имя нужно ещё внести изменения в файл /etc/hosts на рабочей станции. В файле уже имеется пример как это правильно делается.
3.4.1. Теперь можно начать настраивать gitosis. Получаем копию репозитория с сервера и переходим в его папку:
serg@comp:~$ git clone git@YOUR_SERVER_HOSTNAME:gitosis-admin.git serg@comp:~$ cd gitosis-admin
Состав папки должен быть такой:
serg@comp:~/gitosis-admin$ ls -l итого 8 -rw-r--r-- 1 serg serg 176 2009-12-05 22:51 gitosis.conf drwxr-xr-x 2 serg serg 4096 2009-12-05 21:46 keydir
Файл gitosis.conf содержит настройки для gitosis. А в директории keydir находятся открытые части ключей пользователей, имеющих доступ к репозиториям:
serg@comp:~/gitosis-admin$ ls -l keydir итого 4 -rw-r--r-- 1 serg serg 609 2009-12-05 21:35 serg@server.pub
3.5. Добавление правил доступа для нового хранилища
Для того чтобы добавить новое хранилище test нужно добавить в конец файла gitosis.conf содержимое, подобное этому:
[group testers]
members = serg@server tester
writable = test
В строке members указывается какие пользователи будут иметь доступ к хранилищу (test) на чтение и запись (writable). Название группы (testers) нигде не используется, так что может быть абсолютно любым.
Добавлено 14 марта 2010: Название группы в файле gitosis.conf должно быть уникальным!
Предположим, что открытая часть ключа пользователя tester, который работает за другой рабочей станцией (note) уже помещена в папку keydir.
3.5.1. Теперь нужно отправить изменения на сервер:
serg@comp:~/gitosis-admin$ git add . serg@comp:~/gitosis-admin$ git commit -a -m &amp;quot;Созданы правила для нового хранилища test&amp;quot; serg@comp:~/gitosis-admin$ git push
Всё, данные ушли. Осталось создать само хранилище.
3.6. Создание нового хранилища
Так как пользователь gitosis tester также имеет право записи в хранилище test, как и пользователь serg@server, то создадим хранилище из под него. Хранилище может располагаться где угодно в области доступной пользователю.
serg@note:~$ mkdir test serg@note:~$ cd test serg@note:~/test$ git init serg@note:~/test$ git remote add origin git@имя_сервера:test.git serg@note:~/test$ git add * serg@note:~/test$ git commit -a -m &amp;quot;Создано пустое хранилище&amp;quot; serg@note:~/test$ git push origin master:refs/heads/master
ЗАМЕЧАНИЕ1: Обратите внимание на последнюю строку — это не простой push!
ЗАМЕЧАНИЕ2: В строке где указывается ссылка на внешнее хранилище (git remote add origin...) имя пользователя, то есть то что стоит до @ всегда должно быть такое же как имя пользователя ОС в чей домашней директории расположены хранилища на сервере! О том что в каталоге ~/.ssh текущего пользователя должна лежать секретная часть ключа авторизации в gitosis напоминать не надо? (Вторая часть ключа из допущения в п.3.5.)
3.7. Создание публичного доступа к хранилищу
Если нужно организовать публичный доступ к какому-либо хранилищу, то это делается следующим образом:
serg@server:~$ sudo -u имя_пользователя git-daemon --base-path=/home/имя_пользователя/repositories/ --export-all
Теперь доступ к хранилищу можно получить из любой части Сети (если компьютер к ней подключён и имеет имя/ip) следующим образом:
friend@home:~$ git clone git://имя_сервера/test.git
Надеюсь данный материал помог вам сэкономить несколько дней, которые понадобились мне чтобы во всём этом разобраться.
Спасибо, сегодня, думаю, попробую все это повторить!
Если на сервере есть несколько веток, то при клонировании получается только master. Пример результата клонирования:
$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/origin/branch1
remotes/origin/branch2
Для того чтобы получить и связать остальные ветки нужно проделать следующие операции:
$ git checkout -b branch1
$ git pull origin branch1
$ git checkout master
$ git checkout -b branch2
$ git pull origin branch2
В первой строке создаётся локальная ветка branch1. Переход к ней осуществляется автоматически.
Вторая строка получает содержимое branch1 с сервера в локальную branch1 и связывает локальную ветку с веткой на сервере.
В третьей строке происходит возврат к ветке мастер. Это нужно сделать для того чтобы в локальной branch2 не оказалось содержимое branch1. Скорее всего это костыль, но только из ветки master у меня получилось правильное создание веток.
Четвёртая строка создаёт локальную ветку branch2. Переход к ней осуществляется автоматически.
Пятая строка получает её содержимое с сервера и связывает локальную ветку с веткой на сервере.
ВАЖНОЕ ЗАМЕЧАНИЕ!!!
Связывание веток произошло только для получения данных с сервера. Для отправки данных на сервер нужно указывать все параметры push!
git push origin branch1:branch1
branch1 (до двоеточия) — локальная ветка.
branch1 (после двоеточия) — ветка на сервере.
Добавлено 10 февраля 2011
Как сделать, чтобы ветки автоматически корректно отправлялись на сервер читайте в комментарии от 10 февраля 2011.
Добавлено 6 декабря 2011
Обязательно проверяйте результат выполнения команды из пункта 3.3.8:
sudo chmod 755 /home/имя_пользователя/repositories/gitosis-admin.git/hooks/post-update
Если не установить права исполнения на скрипт post-update, то после добавления публичной части ключей пользователей в keydir (см.п.3.4.1.) и отправки их на сервер (git push) они не добавятся в файл ~/.ssh/authorized_keys пользователя на сервере, из под которого работает gitosis. Что в свою очередь приведёт к тому, что вместо или сразу после запроса passphrase будет запрашиваться пароль пользователя на сервере.
Очень нужна помощь!
Когда делаю:
fba@fbandrey:~/work/fl/qwe.ru$ git push origin master:refs/heads/master
Получаю ответ:
ERROR:gitosis.serve.main:Repository read access denied
fatal: The remote end hung up unexpectedly
В чем может быть проблема???
В gitosis.conf добавил:
[group fl]
members = fba@webdep1
writable = qwe.com
Ключи тоже вроде на месте.
Для Андрей
Обсуждение проблемы перенесено на форум в тему Проблема с git
Спасибо! Похоже, это самый понятный и удобный мануал из всех, которые я нашел.
Полезно к прочтению: проблема с gitosis.
Я отношусь к тем кто еще не делает резерные копии.
mpak, не могу сказать, что это умный поступок с вашей стороны. Кстати, что будете делать, когда произойдёт сбой?
Буду делать резервные копии
Для того чтобы локальные ветки корректно синхронизировались с хранилищем на сервере файл .git/config должен выглядеть примерно так:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = git@server:project.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[branch "develop"]
remote = origin
merge = refs/heads/develop
ergallm@lamp:~/src$ git clone git://eagain.net/gitosis.git
Initialized empty Git repository in /home/ergallm/src/gitosis/.git/
eagain.net[0: 208.78.102.120]: errno=Connection timed out
fatal: unable to connect a socket (Connection timed out)
ErgallM, и?
Zeboton, ладно, это я допру где этот пакет достать, а обычный новичек? что ему делать если пакет не грузится…выложите плиз альтерванивы или архив с gitosis )
ErgallM, а в чём проблема? У людей временно не работал сервер, а сейчас он работает. Бывает. Может у них профилактика была. Или почему-то Вы не можете подключиться к серверу, но это уже совершенно другой вопрос.
А у меня вот на этапе git push origin master:refs/heads/master
произошла ошибка:
ERROR:gitosis.serve.main:Repository read access denied
fatal: The remote end hung up unexpectedly
Что-то с правами?
nikita@server:/home/git/repositories$ ls -l
total 4
drwxr-x— 8 git git 4096 2011-07-02 18:59 gitosis-admin.git
Скорее всего проблема не с Unix-правами, а с правами в gitosis-файле.
Действительно полезняк! А то сколько не лазишь по нету сплошное бла бла бла. Но не тут, и это радует!
помогло в установке
В разделе «Создание нового хранилища» не хватает одной мелочи, которую нашел в другой статье.
Инициализируем репозиторий на сервере.
$mkdir ~/repositories/megaproject.git
$cd megaproject.git
$git --bare init
Без этого несколько часов пытался понять, почему не хочет работать
serg@note:~/test$ git push origin master:refs/heads/master
Ошибка на шаге 3.3.3
serg@server:~/src$ git clone git://eagain.net/gitosis.git
Cloning into ‘gitosis’…
fatal: unable to connect to eagain.net:
eagain.net[0: 50.56.185.182]: errno=Connection refused
Что не так?
Проект переехал на github. Теперь для клонирования gitosis необходимо выполнить:
git clone git://github.com/tv42/gitosis.git