Организация Git-репозитория

Небольшая памятка по организации локального Git-репозитория и работе с ним. Поможет вам в повседневной работе до момента, пока вы не запомните многие вещи до автоматизма. Данные правила описывались мной для себя, и моих разработчиков, поэтому не могут являться аксиомой. Если вы найдете ошибку - напишите мне. Если решите что можете сделать лучше - сделайте это!

Инсталляция Git

Вне зависимости от того, планируете ли вы использовать git в качестве сервера или локально, процедура инсталляции во всех случаях будет одинакова:
# apt-get install git

Создание нового сетевого репозитория

Работы по созданию сетевого репозитория выполняются на Git-сервере, организованном по принципам, изложенным в статье о системы прав доступа. Для создания репозитория с нуля требуется выполнить следующие манипуляции на сервере:
  • придумать название
  • создать группу проекта
  • назначить разработчиков проекта
  • создать каталог репозитория проекта с необходимыми правами
  • выполнить инициализацию репозитория
Основная масса операций выполняется под пользователем root.

Название проекта

В качестве названия проекта выбирается слово или фраза, записанная по английски в wiki-нотации - это когда все слова пишутся слитно, и первые буквы слов пишутся заглавными. например: ReRouting, ExtractMail и т.п.

Группа проекта

Группа проекта - обычная системная группа пользователей, создаваемая на сервере Git. Имя группы формируется путем добавления к названию проекта префикса "project". Таким образом получаем группы с именами projectReRouting, projectExtractMail:
# groupadd projectReRouting

Разработчики проекта

Разработчики проекта - обычные системные пользователи сервера. Соответственно для их включения в состав команды проекта достаточно включить их в группу проекта. Выполняется это так:
# usermod -a -G projectReRouting baydakov
# usermod -a -G projectReRouting vitalkadrug

Если пользователей в системе еще не существует - создавать их там тоже необходимо с учетом определенной специфики.

Каталог репозитория проекта

Каталог репозитория проекта создается в корневом каталоге репозиториев /opt/git. При этом он получает имя аналогичное названию проекта с добавлением суффикс ".git":
# cd /opt/git
# mkdir ReRouting.git

После созданию каталогу необходимо выставить корректные права доступа и владельца
  • 0770 - для закрытого репозитория
  • 0775 - для публичного репозитория
  • пользователем каталога должен быть root
  • группой каталога должна быть группа проекта

# chown root:projectReRouting /opt/git/ReRouting.git
# chmod 0775 /opt/git/ReRouting.git

Инициализация репозитория

Инициализация репозитория должна ОБЯЗАТЕЛЬНО выполняться пользователем, являющимся участником проекта. Тогда все создаваемые каталоги и файлы получат корректные права доступа. Поэтому для инициализации из под пользователя root нам потребуется использовать команду su, явно указывая альтернативный шелл, т.к. для наших пользователей стандартным является git-shell.
root@git:~# cd /opt/git/ReRouting.git
root@git:/opt/git/ReRouting.git# su -s /bin/bash vitalkadrug
vitalkadrug@git:/opt/git/ReRouting.git$ git init --bare --shared
Initialized empty shared Git repository in /opt/git/ReRouting.git/
vitalkadrug@git:/opt/git/ReRouting.git$ exit
exit
root@git:/opt/git/ReRouting.git#
Обратите внимание на использование параметра "--shared" - без него файлы и каталоги репозитория не получат требуемых групповых прав доступа, и репозиторием сможет пользоваться только его создатель!

После инициализации мы имеем пустой сететвой репозиторий с основной веткой master по умолчанию.

Управление пользователями на сервере Git

Создание пользователя проекта

Пользователь проекта - обычный системный пользователь, созданный по следующим правилам:
  1. В комментариях необходимо указать имя и фамилию разработчика
  2. Основной группой выставляется группа git
  3. Оболочкой выставляется /usr/bin/git-shell

# useradd -c "Vitaly Druzhinin" -g git -m -s /usr/bin/git-shell vitalkadrug
Однако полноценно работать он сможет только если подключится к хосту. Подключение выполняется по протоколу ssh, поэтому наш пользователь должен уметь делать это. Обычно достаточно задать пользователю пароль, или разместить в его домашнем каталоге публичный ключ ssh:
# su -s /bin/bash vitalkadrug
$ cd ~/
$ mkdir .ssh
$ vi .ssh/authorized_keys
$ chmod 0700 .ssh/authorized_keys

Включение пользователя в проект

Для включения пользователя в проект достаточно сделать его членом группы проекта:
# usermod -a -G projectReRouting vitalkadrug

Исключение пользователя из проекта

Для исключения пользователя из проекта достаточно исключить его из группы проекта. Однако, выполнить это не так просто. У команды usermod нет соответствующей опции, поэтому удалить пользователя из группы так-же элегантно, как мы его туда добавляли, увы нельзя. Здесь придется либо вручную отредактировать файл /etc/group, изменив состав пользователей нужной группы, либо использовать usermod для явного указания перечня всех допустимых для пользователя групп, из которого исключить нашу. Первый путь проще, поэтому будем рихтовать /etc/group...

Начальный коммит

Свежепроинициализированным сетевым репозиторием еще нельзя пользоваться полноценно - необходимо внести в него первые изменения, так называемый начальный коммит. Изменения вводятся главным разработчиком в своем свежесозданном локальном репозитории и публикуются в свежесозданном сетевом репозитории:

Создание нового локального репозитория

Процедура создания нового локального сетевого репозитория выполняется один раз для всего проекта главным разработчиком проекта при первоначальной инициализации репозитория. Локальный репозиторий создается практически так-же как и сетевой, однако здесь нет каких либо жестких требований к созданию групп или пользователей, а так-же к соблюдению прав доступа к файлам и каталогам. Т.е. все гораздо проще:
  • создается пустой каталог - это будет будущий каталог локального репозитория, который является рабочим каталогом проекта. В нем будут размещаться, правиться и удаляться рабочие файлы проекта.
  • в этом каталоге запускается команда инициализации репозитория
Например:
$ mkdir ReRouting
$ cd ReRouting
$ git init
После инициализации мы имеем пустой локальный репозиторий с основной веткой master по умолчанию.

Настройка нового локального репозитория

По большому счету репозиторий Git не нуждается в какой-либо настройке и может использоваться сразу же после инициализации. Однако ряд настроек позволит нам немного упорядочить работу в нем. Как минимум следует указать свое имя и контактный email через команду git config. Запускать ее необходимо находясь в рабочем каталоге локального репозитория. Например:
$ cd ReRouting
$ git config user.name "Vitaly Druzhinin"
$ git config user.email "VitalkaDrug@gmail.com"
Дополнительный параметр --global заставляет git сохранить настройки не в рабочем каталоге проекта, а в домашнем каталоге пользователя. В этом случае они будут работать для всех локальных репозиториев, управляемых из под данного пользователя:
$ cd ReRouting
$ git config --global user.name "Vitaly Druzhinin"
$ git config --global user.email "VitalkaDrug@gmail.com"

Начальный коммит

Возьмите за правило хорошего тона первым файлом проекта делать игнор-лист - списка файлов, которые крайне не рекомендуется хранить в репозитории. А именно:
  • временные файлы
  • скомпилированные бинари, собираемые из других файлов проекта
  • файлы журналов
  • конфигурационные файлы
  • любые другие файлы, которые создаются автоматически или не имеют никакого значения для остальных разработчиков
Конфигурационные файлы не стоит пихать в репозиторий из-за того, что у каждого разработчика эти файлы, скорее всего, будут свои. Т.е. каждый разработчик будет вносить в них свои правки, которые наверняка абсолютно не интересны другим. Поэтому лучше всего иметь в репозитории шаблоны конфигурационных файлов - это конфигурационные файлы с суффиксом .orig.

Список исключений хранится в файле .gitignore. Он может иметь вот такой вид:
*.tmp
*.[oa]
*~
*.conf
*.log

Вот так, например, может выглядеть начальный коммит::
$ cd ReRouting
$ vi .gitignore
$ git add .gitignore
$ git commit

Теперь мы имеем полностью рабочий локальный репозиторий проекта. Остается связать его с сетевым.

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

Для установки связи нового локального репозитория с таким-же новым сетевым репозиторием осуществляем привязку. Для этого добавляем к локальному репозитоарию ссылку на внешний сетевой репозиторий. При этом указывается имя сетевого репозитория и путь до него:
$ git remote add origin ssh://vitalkadrug@solnce.local.git/opt/git/ReRouting.git
Здесь origin - имя сетевого репозитория, под которым мы добавили его себе в настройки. Это имя может быть любым, и под разными именами можно подключить к своему локальному репозиторию проекта кучу других сетевых репозиториев. Но обычно главный сетевой репозиторий, в котором хранится основная ветка проекта, называют именно так - origin.

Публикация начального коммита в сетевом репозитории

Последний шаг - публикация изменений локального репозитория в сетевом. Все выполняется одной командой:
$ git push origin master
Здесь origin - это имя сетевого репозитория, под которым он был добавлен в конфигурацию на предыдущем шаге. А master - имя ветки локального репозитория, которую мы публикуем.

Клонирование сетевого репозитория

Клонирование - процедура создания локального репозитория как полной копии существующего сетевого. Клонирование сетевого репозитория допустимо только если в него были ранее добавлены какие-либо файлы, т.е. он не пустой. С операции клонирования начинается работа любого нового разработчика проекта. Для этого выполняют команду git clone находясь в каталоге, в котором будет создаваться каталог с локальным репозиторием, имеющий имя аналогичное названию проекта. Например:
$ cd ~/MyProjects
$ git clone -v ssh://vitalkadrug@solnce.local.git/opt/git/ReRouting.git
В результате такой команды в текущем каталоге будет создан рабочий каталог проекта (в нашем случае - ReRouting, без суффикса .git!), в котором будет содержимое нашего сетевого репозитория. Можно с ним работать.

Обычная работа с репозиторием

Обычно внесение разработчиками изменений в репозиторий осуществляется примерно по следующему алгоритму:
  1. актуализация состояния локального репозитория через git pull или git clone
  2. модификация файлов рабочего каталога проекта (используем привычные средства - текстовый редактор :))
  3. анализ произведенных модификаций через git status
  4. добавление модифицированных версий файлов в локальный репозиторий через git add FILENAME
  5. удаление ненужных файлов из локального репозитория через git rm FILENAME
  6. применение изменений в локальном репозитории через git commit. При этом создается новая версия проекта в локальном репозитории
  7. публикация изменений локального репозитория в сетевом репозитории через git push origin master

Однако такая схема хорошо работает только если вы являетесь одним единственным разработчиком проекта, поскольку все работы выполняются с основной веткой проекта master. Если вас несколько, то принято основную ветку master проекта трогать как можно реже, публикуя в ней только хорошо проверенные и протестированные РЕЛИЗЫ проекта. Для тренировок, тестов, разработки патчей, исправления ошибок, создания нового функционала и т.п. следует использовать другие ветки проекта. И только после полной готовности переводить состояние проекта из альтернативной ветки в основную. Более того, если речь идет о тестах или исправлениях ошибок, альтернативное ветвление рекомендуется осуществлять в рамках своего локального репозитория, не публикуя в сетевом содержимое своих веток, которые в большинстве своем временные.

Использование веток вносит изменения и в алгоритм работы с репозиторием. Теперь он будет выглядеть так:
  1. создание новой ветки в локальном репозитории через git branch NEWBRANCH
  2. переключение в новую ветку через git checkout NEWBRANCH
  3. модификация файлов рабочего каталога проекта (используем привычные средства - текстовый редактор :))
  4. анализ произведенных модификаций через git status
  5. добавление модифицированных версий файлов в локальный репозиторий через git add FILENAME
  6. удаление ненужных файлов из локального репозитория через git rm FILENAME
  7. применение изменений в локальном репозитории через git commit. При этом создается новая версия проекта в ветке NEWBRANCH локального репозитория
  8. переключение в основную ветку master через git checkout master
  9. актуализация состояния основной ветки master локального репозитория с основной веткой master сетевого рпеозитория через git pull origin
  10. слияние состояния локальной ветки master с состоянием локальной ветки NEWBRANCH через git merge NEWBRANCH
  11. публикация изменений основной ветки master локального репозитория в основной ветке master сетевого репозитория через git push origin master
  12. удаление теперь уже не нужной ветки NEWBRANCH из локального рпеозитория через git branch -D NEWBRANCH

-- VitalyDruzhinin - 2012-02-23
Topic revision: r1 - 2013-08-28, VitalyDruzhinin
 

This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback