Как работает Git
Система контроля версий преследует две основные функции.
Первая. Позволяет отслеживать историю изменения файлов. Изменения хранятся в коммитах, считай, это ячейки сохранений в играх. Благодаря им, можно просматривать прошлые изменения в коде или откатывать проект назад, если что-то пошло не так. Разработчики создают коммиты, когда достигнут какой-то логический этап решения задачи. Обычно в сообщении коммита пишется описание проделанной работы, чтобы было легко читать историю в последствии.
Вторая функция системы, вытекающая из первой. Это возможность разрабатывать проект в команде. Гит позволяет создавать ветки. Есть много анимированных видео для упрощения понимания, но я, чтоб сильно не растягивать, расскажу тезисно. Если коммиты это просто набор разных сохранений состояний кода проекта, то ветки это то, что группирует эти коммиты по какому-то логическому принципу.
Например, в проекте есть, как правило основная ветка master или main. В нее попадают те версии программы (или тот набор коммитов), которые уже проверены тимлидом и тестировщиками. Эта версия финальная и эти изменения увидят пользователи в сторах. В дополнительных ветках разработчики работают над своими кусками кода большого проекта. Изменения в них видны только участникам проекта. Это позволяет обезопасить проект от публикации некачественного кода и не аффектить друг друга, если вдруг их изменения будут пересекаться. После завершения работ их версии проекта проходят проверку и сливаются с основной веткой.
Как правило жизненный цикл ветки кода соответствует жизненному циклу бизнес-задачи. Чтобы лучше понять, как код доходит до финальной версии и зачем нужны другие ветки, здесь придется быстро затронуть жизненный цикл задачи. Это похоже на наше взаимодействие в спринте по Kotlin.
Жизненный цикл задачи
- Задача ставится бизнесом в каком-нибудь инструменте управления проектами типа Jira (описываются условия, ожидаемый результат и так далее) и назначается разработчику.
- Задача уходит в работу. В системе контроля версий разработчик создает ветку специально под эту таску. У задачи помимо остального есть, как правило, номер и название. Эта информация указывается в названии ветки, чтобы можно было найти потом ее полное описание и посмотреть подробности.
- Задача висит в статусе “В прогрессе”. Разработчик делает коммиты, разделяя изменения в коде по смыслу.
- Разработчик по окончании работы создает Pull Request (”запрос на слияние” в основную ветку). Задача переходит в статус “Ревью”.
- Старший разработчик берет задачу и исследует Pull Request. В нем отображены все данные по задаче. Ветка-источник, ветка-назначение, какие изменения были внесены в код и кем. Он делает код-ревью в специальном интерфейсе репозитория. Проверяет и оставляет фидбек, комментарий можно оставить даже к конкретной строке кода, чтобы явно указать на ошибку.
- После ревью принимается решение разрешить слияние или отправить код на доработку. Если все хорошо, код можно слить (или смержить) в назначенную основную ветку. Если нужны доработки, устанавливается статус “Запрос изменений” и разработчику приходит соответствующее изменение. Код дорабатывается, коммитится и пушится в ту же рабочую ветку и pull request обновляется. Новый запрос в таком случае создавать не нужно.
Добавлю пару слов про репозиторий. Гит-репозиторий – это и есть хранилище кода с вашим проектом. Это хранилище (по сути папка) может существовать локально на компьютере, также используя систему контроля версий. Или может быть “запушена” (отправлена) в удаленный гит-репозиторий, как раз для совместной разработки. Такие хранилища предоставляются разными сервисами, один из них GitHub. Вам уже нужно иметь там аккаунт, если что это бесплатно.
Git в IDEA
Окей. Создаем новый проект для задач в Idea.
- Нет необходимости переключать вкладки слева, остаемся на самой первой. В том списке можно увидеть Kotlin Multiplatform, но это не то, что нам потребуется сейчас.
- С адресом размещения проекта на компьютере объяснять не нужно. Следите только за правильностью пути под окном адреса размещения и не используйте кириллицу. Ни в названии проекта, ни в имени пользователя системы. Вообще нигде, это может нарушить работу среды разработки.
- Язык Kotlin.
- Систему сборки рекомендую Gradle, она используется для сборки Android проектов
- JDK оставляем по умолчанию или при его отсутствии скачиваем последнюю версию из предложенных. Если вдруг при нажатии Create появится сообщение о несоответствии установленной версии Gradle и JDK, снизьте уровень до рекомендуемого в сообщении.
- Язык для Gradle файлов оставляем Kotlin
Мы создали проект, сейчас это просто папка с файлами на компьюторе. В эту папку нужно подключить систему контроля версий, чтобы файлы начали отслеживаться. Вообще есть множество разных гит клиентов, но в Idea встроен собственный. Жмем на пункт меню Version Control System и выбираем активацию контроля версий. В окне выбора системы оставляем Git и жмем окей.
Обратите внимание, в правом нижнем углу появилось название созданной по умолчанию главной ветки master. В будущем нажимая на ту область можно будет переключаться между вашими остальными ветками.
gitignore
Теперь смотрим на иерархию файлов. Они окрасились в красноватый цвет, это значит, что система отслеживания их видит, но пока еще не отслеживает. Иначе можно сказать эти файлы еще не в стейдже. В зависимости от состояния файлов (добавлен в стейдж, создан новый, изменен, закомичен) они будут менять свой цвет.
Окей, создадим первый коммит. Он необходим, чтобы закоммитить исходную версию проекта, чтобы создать первую точку сохранения. Напомню, пока мы работаем с нашим собственным локальным репозиторием, не обращаясь к гихабу. Чтобы открыть окно создания коммита, можно выбрать его во вкладке слева или использовать хоткей.
Видим список файлов, которые еще не участвуют в контроле версий (изначально это все файлы). Однако, Идея предлагает начать отслеживать много лишнего. Вернемся во вкладку Project. При создании/открытии проекта генерируется ряд файлов. Папки и файлы с точкой вначале – это скрытые папки, системные. Там хранятся файлы, описывающий ваш проект. Как правило, все файлы, которые генерируются, не хранятся в репозитории. Папки .gradle и .idea нам не нужны (для отслеживания). Поэтому нужно сообщить гиту, чтобы он игнорировал их, если внутри будут какие-то изменения.
Для этого в корневой папке локального репозитория (в папке с проектом) нужно создать файл .gitignore. Внутри него описываются файлы и папки, которые не нужно отслеживать. Можно создать руками, а можно с помощью клика правой кнопки мыши по папке выбрать Git → Add to .gitignore.
Среда разработки сначала предложит создать файл в случае его отсутствия. Потом предложит добавить созданный файл в отслеживание. Здесь можно установить галку “Больше не спрашивать”, таким образом все новые файлы автоматически будут добавляться в отслеживание (или в стейдж).
Хорошо, открылся созданный .gitignore с добавленной папкой. Пропишем туда еще и папку с настройками Idea. Но остался еще один штрих. Если нажать на знак молотка – запустится сборка проекта. Она всегда запускается перед тем, как вы запускаете какой-либо код. После сборки появится новая сгенерированная папка build. Она нам тоже не нужна для отслеживания, добавим в игнор, чтобы не захламлять стейдж.
Великолепно. Возвращаемся во вкладку Commit и жмем обновить. Остались только нужные файлы. Отмечаем все, что осталось. Теперь можем создать первый коммит в нашем локальном репозитории. Пишем его название в окне ниже. Как правило он так и называется First Commit или Initial Commit. Жмем кнопку.
Мы сделали первый коммит в основную и единственную ветку master. Все коммиты проекта можно увидеть, нажав на раздел Git внизу, в панели инструментов. Там будут все ветки, все коммиты и информация по изменениям файлов для конкретного коммита.
Публикация репозитория на GitHub
Едем дальше. Пришло время опубликовать локальный репозиторий на гитхаб. Напомню, к этому моменту у вас уже должен быть создан там аккаунт. Сначала мы подключим GitHub к среде разработки, затем опубликуем наш проект. Таким образом там создастся удаленный репозиторий с полной синхронизацией с проектом на компьютере. Со всеми ветками и комитами.
Выбираем в меню вкладку Git, далее GitHub → Share Project. Выбираем название удаленного репозитория, рекомендуется оставлять такое же. Origin – это пометка по умолчанию для удаленного сервера, оставляем как есть. Репозиторий можно сделать приватным, чтобы он был доступен только вам и приглашенным пользователям GitHub (эту опцию можно позже изменить в настройках репозитория гитхаб). Share by – здесь должен быть список подключенных аккаунтов, при их отсутствии жмем “Добавить аккаунт” → Log In используя GitHub. В браузере откроется страница с запросом на доступ к аккаунту и дополнительными разрешениями. Все подтверждаем, возвращаемся в среду разработки и шерим проект.
Заходим на гитхаб в раздел репозитории и видим проект, который запушили. Здесь указывается название последнего коммита, с которым были внесены изменения. Можно походить по файлам. Созданный .gitignore тоже залился, благодаря чему здесь отсутствуют лишние файлы настроек, необходимые для локальной сборки.
Окей. Переходим в рабочий флоу и сейчас стоят такие цели:
- создать ветку для выполнения задачи
- внести какие-то изменения и закомитить их
- создать пулл реквест и отправить на проверку
- влить успешно выполненное задание в мастер
Создание ветки
Делается это в пару кликов, но при создании ветки нужно убедиться, что мы “бранчимся” от правильной ветки. Мы сейчас в “мастере”, все ок. Но в будущем при создании веток для других задач не забывайте переключаться на мастер, прежде чем создавать новую ветку. Если вы делаете задачи параллельно, вам придется делать это часто. Жмем на New Branch. Название также рекомендуется делать осмысленное, связанное с названием задачи. Предположим мы собрались делать первую задачу первого урока. Слова разделяются дефисом. Галка checkout говорит о том, что после создания мы переключимся на эту ветку.
Нейминг комитов
Теперь внесем какой-то код в качестве решения. Я рекомендую организовывать код для наших задач так: отдельный пакет для урока, отдельный файл для задачи.
Далее оставляем осмысленный коммит. Кстати, просматривая измененные файлы можно полностью откатывать изменения выбрав Rollback из контекстного меню файла. Название коммита у меня будет таким KS-1-1
, сначала обычно пишется краткое обозначение проекта, в нашем случае это Kotlin Sprint, далее порядковый номер урока и задачи, чтобы можно было удобно навигироваться. Наконец, осмысленный короткий текст, что было сделано. Желательно на английском, но не обязательно. Главное – в едином стиле в рамках всего репозитория. Все, не забываем отметить нужные файлы галкой и сразу пушим эту ветку на сервер GitHub, в свой удаленный репозиторий.
Создание Pull request
Круто, идем на гитхаб. Во-первых запушенную ветку можно уже увидеть в списке и проверить изменения в ней. Во-вторых заигноренные файлы не попали в репозиторий. В-третьих теперь мы видим предложение сервиса создать запрос на слияние рабочей ветки в основную. Можно нажать на Compare & Pull request отсюда. Или можно перейти в раздел с пулл реквестами и создать ПР самостоятельно. Тут выбираем откуда-куда. Справа указывается ветка “откуда”. Выбираем рабочую ветку, подсветились какие изменения в ней будут влиты в мастер, подтверждаем. Название пулл реквеста оставляем по названию осмысленного коммита, при необходимости добавляем свои вопросы или комментарии. Создаем.
Код-ревью
Отлично. Вот так выглядит страница созданного pull request. Такой ее увидит проверяющий. Копируем ссылку на него из браузера и отсылаем в бот для конкретной задачи конкретного урока и ждем обратной связи. После принятия решения бот пришлет уведомление, нужно ли вам внести правки или решение принято. Как правило в продуктовой разработке тоже есть разного рода интеграции с чатами (слаком, телеграммом и прочим). Они уведомляют о новых ревью и необходимости правок или влития. В простом случае – можно пользоваться письмами в электронной почте.
Ок. Если нужны будут правки, все комментарии к коду я оставлю прямо в рамках пулл реквеста. Вам нужно будет доработать код и сделать еще один коммит с правками в эту же ветку (не перепутайте). Pull request обновится и ссылку на него нужно будет заново прислать в боте к этой же задаче. Новый PR в рамках одной задачи создавать уже не нужно, но на случай, если вы вдруг ошибочно удалили PR, предусмотрена отправка другой ссылки.
Мердж
Только после принятия задачи нажимайте кнопку Merge pull request. Тогда изменения из рабочей ветки вольются в основную production ветку master. На всякий случай проверяем все на основной вкладке. Все работает. Для выполнения новых задач не забывай переключаться на master в Idea и только от нее создавать новые ветки.
Реальная практика тебя ждет в боте, заходи.
Для тех, кто собрался стать Android-разработчиком
Пошаговая
схема
Описание процесса обучения от основ Kotlin до Android-разработчика
Бесплатные
уроки
Авторский бесплатный курс по основам языка программирования Kotlin
Обучающий
бот
Тренажер и самоучитель по Котлин – бесплатные тесты и практика