Введение в DevOps: Как пользоваться Git (на примере Gitlab)

Добрый день! Данная статья представляет собой краткий мануал как пользоваться Git в производственной среде. В прошлой статье я уже упоминал про развертывание Gitlab сервера внутри компании, считайте эту статью — продолжением.

Откуда черпать информацию:

Поставить Git можно на любую ОС — консольные и графические клиенты есть под любую операционку. 
Мое имхо — использование графических клиентов излишне, мне хватает консольного клиента, тем более в сети большинство примеров про него. Но если что — клиенты встроены во все популярные IDE.

Что надо обязательно знать и уметь использовать (я привожу их в случайном порядке):

  • branch — сделать ветку
  • checkout — переключиться на ветку
  • add — добавить файл в отслеживаемые
  • commit — сделать коммит (фиксацию)
  • merge — слить изменения веток
  • pull/push/fetch — стянуть или наоборот вытолкать свои изменения с сервера или на сервер
  • log — посмотреть кто и что начудил
  • stash — спрятать свои недонаработки
  • status — посмотреть текущее состояние локальной репы
  • reset — откатить ченджи
  • rm — удалить файл из отслеживаемых
  • clone — склонировать репозиторий

Итак, дорогой друг, ты решил попробовать эту странную штуку под названием Git, хотя ни разу ей не пользовался — погнали!

1. Сгенерируй себе ssh ключ.
Я понятия не имею какой ОС ты пользуешься так что загугли как это сделать (да, я даже облегчил тебе задачу). Я использую Linux, у меня он уже есть.

2. Настрой свой git клиент. Для этого есть опции config. Мне хватает 4-х:

П.С. Имя юзера и имейл должны совпадать с теми что у тебя в профиле (см далее)

Кстати, когда ты пользуешься опцией global — ты задаешь настройку для клиента глобально (кеп), а если ты введешь такие же команды в конкретном репозитории — ты настроишь параметры только для него.

3. Иди в Gitlab через веб интерфейс (либо публичный, либо свой, если разворачивали) и там заходи со своей учеткой.  И да если ты пользуешься своим Gitlab серверов, как это было в прошлой статье, не забудь выбрать вкладку LDAP:

Надеюсь ты смог залогиниться. 
Далее идем в настройки профиля (https://гит-сервер/profile):

Там настраиваем себе язык, цвет темы, цвет редактора, аватарку, черта лысого — развлекайся.
Главное- потом не забудь зайти в пункт SSH ключи (https://гит-сервер/profile/keys) и там добавить хотя бы 1 (но только публичную часть):

(если что, я тут сократил ключ чтобы весь не вставлять)

Плюс советую поиграться с настройкой тем и редактора: https://гит-сервер/profile/preferences

И настроить дефолтный дашборд:

Давай рассмотрим создание репозитория на примере репы для бекап-скриптов. Для этого я сделал отдельный неймспейс/группу OPS (Operations)

и теперь создадим тут сначала подгруппу (New Subgroup) а потом проект (New Project). Проект это и есть репозиторий. А группу я хочу сделать для большей гранулированности — чтобы скрипты для бекапов были в подгруппе «backups». Ну так выглядит симпатичней и навигация проще имхо.

Итак, мы получаем страничку пустого проекта (сиречь репозитория):

где нам не двусмысленно подсказывают как мы можем начать работу. Такая подсказка будет появляться у вас на экране КАЖДЫЙ раз при создании пустого проекта и висеть там ДО ТЕХ ПОР пока вы хоть 1 файл в проект не зальете. Так что не надо себе сохранять как памятку:

Подготовка

Итак, для примера у меня есть папка test в которой лежат пара скриптов для бекапа файлов — я хочу запихнуть их в этот репозиторий, инициировав его. Итак, что на входе:

Я не хочу чтобы в репозиторий попадали всякие мусорные файлы, как например скрытая папка «.directory», как тут. Для этого я делаю файл «.gitignore» в который вношу имена и маски имен объектов (файлов и каталогов) которые должны игнорироваться git-ом:

Инициализация и первый коммит

Теперь воспользуемся инструкцией из второго примера на нашей страничке пустого проекта «Existing folder»:

Теперь разберем по пунктам что я сделал:

  1. Я проинициализировал или создал пустой ЛОКАЛЬНЫЙ репозиторий
  2. Я связал его с удаленным репозиторием на сервере
  3. Я узнал статус репозитория и увидел что у меня есть 2 не отслеживаемых файла (заметьте что той ненужной папки в списке нет)
  4. Сказал добавить все файлы в обслуживаемые (флаг -А вообще опасная штука. Используйте его только если в выводе команды статус вы видите только те файлы, которые должны попасть в репозиторий и НИКАКИЕ другие. А то так и ключи, и пароли, и много что еще загружали люди в публичные репы)
  5. Делаю коммит или фиксацию состояния, сразу добавляя сообщение через флаг -m. Иначе откроется редактор в котором вам нужно будет написать пояснительное сообщение к коммиту. На счет стиля сообщений и как их писать будет ниже.
  6. Далее я настроил имя и имейл пользователя, от лица которого эти изменения будут улетать на сервер. Это можно было бы сделать и сразу, после инициализации репозитория. Обратите внимание — я не использовал флаг –global, а значит эти настройки применены только для данного репозитория. Почему я так сделал? Я работаю с большим числом разных гит серверов и на всех у меня разные учетные записи. Я не хочу перенастраивать клиент глобально каждый раз.
  7. Я еще раз запросил статус чтобы убедиться что я зафиксировал все что хотел и что я могу отправлять изменения на сервер
  8. Я отправил изменения на удаленный сервер, протолкнув (push) их.

Смотрим результат

Итак, возвращаемся в Web интерфейс гитлаба и что мы там видим:

  1. Видно кто из пользователей последним ( и как давно) влил изменения.
  2. Видим наши два файла и напротив них сообщение нашего коммита. Таким образом виден комментарий последнего изменения файла. Вот почему это важно. По умолчанию тут видно первую строку.
  3. Так же видно сколько всего коммитов, сколько веток, какая текущая, сколько форков, Теги и пр пр пр.

Создание веток и слияние

В гите есть понятие веток — это одна из основополагающих концепций и вам ПРИДЕТСЯ ее узнать и полюбить.

Основная идея такова — есть главная ветка, которую обычно зовут «мастер» и ряд других. Например «develop», «staging» и пр. В ряде случаев для имени ветки выбирается имя фичи или изменения над которым в ней работают. Когда разработчик хочет внести изменение в код — он должен «ответвиться» от мастера, поработать, внести свои наработки в свою ветку репозитория, протестировать их и только убедившись что все хорошо (хорошей практикой является демонстрация этих наработок и их тестирования коллегам) — «влить» изменения из своей ветки в мастер.

Такой подход зовется Git Flow и выглядит примерно вот так:

Его мы сейчас и попробуем реализовать (Правда в одно лицо, но для групповой работы схема будет примерно такой же). Мы забыли добавить очень важный файл, который должен являться неизменным атрибутом каждого репозитория — файл README. Как и все git хостинги, Gitlab ищет в каталоге репозитория этот файл и если находит- показывает его содержимое на главной странице репозитория сразу под списком файлов. Gitlab понимаем и умеет рендерить разметку markdown, правда с некоторыми своими условностями, поэтому советую почитать их документацию.

Если Вам лень учить синтаксис или ставить локальный редактор makrdown, или искать плагин к свой ide, воспользуйтесь вот этим сервисом — stackedit.io

Добавим простой файл Readme в котором опишем содержимое проекта:

Отлично, теперь давайте поработаем с git:

Что произошло:

  1. Я проверил с помощью команды status — какие изменения ждут моей реакции и что я сейчас нахожусь на ветке master ( еще это можно сделать командой branch)
  2. С помощью команды checkout с флагом -b я создал и сразу переключился на новую ветку. Имена веток кстати не могут содержать пробелов и еще много чего, поэтому я обычно использую нижнее подчеркивание. И да, если не использовать -b, мне сначала пришлось бы использовать команду branch чтобы сделать ветку, а только потом команду checkout для переключения.
  3. Я добавил файл README в число отслеживаемых
  4. И зафиксировал его коммитом
  5. После чего я попытался отправить изменения на сервер, на что gitlab ответил что такой ветки у него нет, но он же и подсказал как мне прямо из моего клиента ее создать при отправке
  6. Что я и сделал опцией –set-upstream
  7. Gitlab успешно принял изменения в новую ветку и сразу сгенерировал мне ссылку, пройдя по которой я могу запустить процедуру слияния (правда он няшка?)

Если мы теперь посмотрим на сервере, мы увидим что у нас появилась новая ветка — в которой присутствует наш файл README ( а в мастере его по прежнему нет):

Кстати и локально вы можете это увидеть ( а заодно потренируетесь в работе с ветками):

Вы можете и дальше работать в этой ветке над новой «фичей» пока не решите что она готова ( в нашем случае она готова сразу) — и просто отсылать свои изменения на сервер в эту ветку, коммит за коммитом. 
Но как только вы решили что вам пора «вливаться» в мастер — берем ту самую ссылку про которую я писал выше и проходим по ней ( слияние можно сделать и самому но раз уж нам все дают- почему бы нет):

Перед нами форма оформления «Запроса на слияние» — Merge request:

  1. Заполняем описание
  2. Выбираем ответственного (в данном случае я выбрал сам себя) — то есть того кто должен будет просмотреть изменения и утвердить что все хорошо, тем самым тоже вписаться в ответственность если изменение привнесет ошибку в код
  3. Отмечаем галочку «Remove source branch when merge request is accepted.» — если не хотим чтобы наша ветка существовала на сервер после слияния (нафиг копить мусор)
  4. Если есть желание- внизу есть ссылки на коммиты и изменения — мы можем еще раз просмотреть все то что наваяли в красивом виде.
  5. Нажимаем «submint merge request»

Получаем Сформированный запрос где жмем кнопку «merge»

Возвращаемся в репозиторий и видим результаты слияния на ветке мастер:

Остается только «подтянуть» у себя результаты слияния в мастер ветку и удалить нашу временную ветку если она более не нужна:

Что я сделал:

  1. Посмотрел список веток и на которой я сейчас ( отмечена звездочкой)
  2. Убедился что в этой ветке файл README есть
  3. Переключился на мастер
  4. Убедился что тут файла нет
  5. «Стянул» с сервера актуальную версию мастера командой pull
  6. Проверил что файл появился
  7. Удалил более не нужную ветку
  8. Проверил что в списке веток ее больше нет.
  • Не делайте коммиты «от балды» или лишь бы что то написать. Коммит сообщение — важная штука. Рекомендую ознакомиться вот с этой статьей — как и что делать: Лучшая практика создания Git Commit’ов от OpenStack
  • Не добавляйте в коммит кучу изменений разом — вы усложняете в будущем поиск и исправление проблемных ченджей. Коммит должен быть атомарным, фиксирующим одно логическое изменение. Например Вы изменили css стиль для заголовков( добавили новый цвет и шрифт), поправили скрипт работы с БД и изменили JS для фронтэнда — добавив туда новые кнопки и новый метод. Разбейте это на 4 коммита — css, база, js кнопки и js метод. В той же статье есть хорошие примеры коммитов — Лучшая практика создания Git Commit’ов от OpenStack