GitHub

Что это такое

GitHub — сервис хостинга, построенный поверх git. Он достраивает к репозиторию то, что нужно, чтобы команда могла в нём работать: удалённые репозитории, pull request’ы, задачи, права и автоматические проверки. Модель самого репозитория при этом не меняется: удалённый репозиторий — всего лишь ещё одна копия графа объектов. Однако большинство повседневных решений живёт именно в слое совместной работы.

Почему это важно

Слой совместной работы — место, где код встречается с разговором и где становятся видны соглашения команды. Pull request здесь становится единицей ревью, площадкой для обсуждения дизайна и записью о том, почему изменение приняли. Задачи образуют бэклог, а связи между задачами и pull request’ами — историю проекта. Права и защищённые ветки не дают ошибке дойти до продакшена. Непрерывная интеграция тоже работает здесь, хотя сам конвейер — отдельная тема, и ей посвящён раздел об облаке и DevOps.

Ключевые идеи

Удалённый репозиторий — просто ещё один репозиторий

Пуш отправляет объекты, которых у удалённого репозитория нет, а фетч принимает те, которых нет у вас. И всё. Поэтому локальный репозиторий полностью работоспособен без сервера, и поэтому же роль удалённого сводится к координации, а не к власти. Отсюда и разрушительность перезаписи опубликованной истории: и удалённый репозиторий, и каждая клонированная копия хранят объекты, на которые ваша локальная копия больше не ссылается.

push:  отправить объекты, которых не хватает удалённому, затем сдвинуть ссылку ветки
fetch: получить новые объекты, затем обновить ссылку отслеживания

Pull request — это разговор, прикреплённый к ветке

Открывая pull request, вы предлагаете слить одну ветку в другую и даёте всем место, где можно прочитать дифф, прокомментировать строки и одобрить. Возможностью git это не является: так хостинг прикрепляет к ветке обсуждение и статус. А поскольку pull request — единица ревью, полезным его делают именно короткая ветка и маленький дифф.

feature/pricing -> main      ревью, комментарии, одобрение, слияние

Задачи — это бэклог, а связи — история

Задача фиксирует проблему или запрос, а pull request, который на неё ссылается, связывает их между собой. По этим связям сопровождающий через годы отвечает на вопрос «почему код такой?»: обсуждение остаётся в pull request’е, а причина — в задаче. Чтобы это стало возможно, причину и записывают в задачу, а не в приватный чат.

Форки, ветки и права

Если права на запись нет, участник делает форк репозитория, пушит в свой форк и открывает pull request между двумя копиями. Внутри команды ограждением служат права на ветки и защищённые ветки: они могут требовать проходящую проверку и ревью до слияния и запрещать прямой пуш в основную линию. От формы модели прав зависит, какая часть процесса обеспечена принудительно, а какая держится на доверии.

main: защищена, требует 1 одобрение и зелёную проверку
участник: форк -> пуш в форк -> pull request

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

Автоматические проверки — сборку, тесты, линтер — хостинг прогоняет против pull request’а и докладывает результат прямо в разговоре. Проектирование таких конвейеров, выбор runner’ов и управление секретами — отдельный навык; о нём речь идёт в разделе об облаке и DevOps вместе с инструментами автоматизации для репозиториев GitHub. Здесь же важно лишь то, что проверки появляются на pull request’е и их можно сделать обязательными до слияния.

pull request: 1 проверка идёт -> 2 прошло -> кнопка слияния доступна

Практика

Проведите изменение через pull request

Создайте ветку, внесите одно небольшое изменение, запушьте его и откройте pull request со ссылкой на задачу. Запросите ревью, ответьте на комментарий и выполните слияние.

Готово, когда: pull request показывает связанную задачу, разговор ревью и слитый коммит, и вы можете назвать, что из этого добавил хостинг, а не git.

Потребуйте проверку до слияния

В репозитории, который вы контролируете, защитите основную ветку: пусть pull request’у для слияния требуются как минимум одно одобрение и одна проходящая проверка.

Готово, когда: прямой пуш в main отклоняется, а pull request без одобрения слить нельзя.

Частые ошибки

  • Отношение к удалённому репозиторию как к единственной копии истины — локальная работа останавливается вместе с сетью, а перезаписи истории путают всех; исправить: помните, что удалённый репозиторий — лишь одна копия среди многих.
  • Pull request с огромным диффом — рецензенты пробегают глазами, и дефекты проходят насквозь; исправить: держите ветки короткими и разделяйте несвязанные изменения.
  • Обсуждение дизайна в приватном канале — рассуждение так и не доходит до репозитория; исправить: переносите вывод в pull request или в задачу.
  • Оставление основной ветки незащищённой — ошибку можно запушить прямо в историю продакшена; исправить: требуйте ревью и проходящую проверку перед слиянием.
  • Смешение автоматизации хостинга с git — репозиторий прекрасно работает без неё, а конвейер — отдельный навык; исправить: держите эти две темы раздельно и помещайте проектирование конвейера в раздел об облаке и DevOps.

Что читать дальше

  • Git (система контроля версий) (01-cs-fundamentals/12-git) — объектная модель и рабочий процесс, на которых построен этот сервис, поэтому читайте первым.
  • Стратегии ветвления в Git (01-cs-fundamentals/22-git-branching-strategies) — что означают ветки, когда единицей ревью стал pull request.
  • Код-ревью (01-cs-fundamentals/17-code-review) — как читать и писать разговор, который ведёт pull request.