November 29, 2020

От пустого места до пулл-реквеста 2.0

Или повесть о настоящем терминале

В продолжение предыдущей статьи о Git, которая по объективным причинам может понравиться не всем. В этом кратком руководстве не будет ничего о теории git, о состояниях файлов и прочей, без сомнения полезной для дальнейшей работы информации. Пошаговая инструкция по внесению правок в проект и предложению своих изменений к ревью, посредством механизма pull-request. С небольшими комментариями к каждому шагу.

Естественно, что любой графический клиент для git - это ни что иное, как набор нарисованных кнопок и полей, выполняющих те или иные терминальные команды приложения git. Также естественно, что зачастую есть необходимость работать с системами контроля версий не только в удобном графическом интерфейсе, но и в терминале, например, на серверах, где разворачивается инфраструктура или приложение. Помимо этого в терминале, естественно, можно осуществлять и разработку приложения.

О том, какие команды нужно выполнить, чтобы начать разрабатывать приложение в безоконной среде и поговорим. Сразу оговорюсь, что в треугольных скобках будет указан аргумент, или часть аргумента, который нужно изменить, чтобы инструкция подходила именно для Вас, например, если написано, что нужно выполнить git commit -m "<your-comment>", то нужно будет выполнить в терминале команду git с аргументом commit и ключом -m после которого в кавычках нужно будет написать Ваш комментарий. Итак, к делу, по пунктам:

  1. Создаём новый проект, или берём существующий, который нужно версионировать. В терминале в папку проекта можно перейти, выполнив команду cd <absolute-path-to-project-directory>, где абсолютный - означает путь от корня файловой системы
  2. Инициализируем в папке новый локальный гит репозиторий командой git init
  3. Добавляем в папку проекта новый файл .gitignore (на UNIX-подобных операционных системах, командой touch .gitignore) и открываем его на редактирование любым текстовым редактором (например, nano .gitignore)
  4. В файл игнорирования нужно вписать все файлы и папки, которые не должны попасть во внешний (удалённый) репозиторий. Их нужно перечислить на отдельных строках. Например, для проекта, написанного в IntelliJ IDEA это должны быть папки .idea/ и out/ а также файл проекта *.iml и таким образом в файле .gitignore можно быть три строки. Сохраняем файл игнорирования.
  5. На сайте github.com создаём новый репозиторий. Это не повторение уже проделанной работы, а создание именованного места хранения Вашего репозитория. Важно помнить, что удалённый репозиторий, созданный на Github'e всегда следует считать основным. После создания у этого репозитория появится свой адрес вида https://github.com/<your-account-name>/<your-repository-name>.git именно этот адрес нам понадобится для дальнейшей работы, скопируем его в буфер обмена.
  6. Нам необходимо добавить в наш локальный репозиторий информацию о том, что его копия будет храниться удалённо, для этого нужно выполнить команду git remote add origin <remote-repository-address> которая добавит удалённый репозиторий под именем origin. Удалённых копий репозитория может быть несколько, главное, чтобы их имена не повторялись.
  7. Мы находимся в локальной ветке master и нам необходимо зафиксировать (сделать коммит) все текущие изменения (те, что уже были в папке на момент инициализации репозитория). Для этого нужно выполнить две команды
    git add . git commit -a -m "initial commit"
    Особенное внимание следует обратить на то, что в первой команде на конце стоит точка, и это означает, что нужно добавить к версионированию вообще все файлы (кроме игнорируемых) из текущей директории и всех её поддиректорий. Вторая команда может содержать любой текст в сообщении коммита, но обычно пишут, что это начальный, инициализирующий коммит.
  8. Для отправки локального репозитория в удалённый (создания общедоступной копии) необходимо выполнить команду git push -u origin master. То есть указать действие, куда и что нужно "запушить". Ключ -u означает, что в удалённом репозитории на момент выполнения команды push нет ветки с названием master, и мы хотим не только её создать, но и явно указать, что это полная копия нашей локальной ветки master. Установить связь этих веток.
  9. Мы готовы вносить правки. Это принято делать в отдельных ветках, чтобы ненароком не сломать ничего в основной (мастер) ветке. Чтобы создать ветку и переключиться в неё нужно выполнить команды
    git branch <branch-name> git checkout <branch-name>
    Для навигации по веткам можно использовать git branch -a - команду, которая выведет на экран список всех существующих локально веток проекта, и git checkout <branch-name> - команду, которая переключает ветки.
  10. Здесь, в новой ветке, можно вносить правки в проект без опасения нанести вред основному проекту. Важно помнить, что пока пользователь не зафиксирует свои изменения - они не появятся в git, и пока пользователь сам, явно, ничего из git не удалит - оно никуда не пропадёт. Чем чаще мы будем делать фиксации (коммиты) при работе - тем лучше, таким образом мы сможем точнее отследить момент, например, когда всё перестало работать или сможем случайно удалить меньшее количество данных.
  11. После внесения правок в проект, мы готовы сливать изменения из текущей ветки с основной веткой проекта. В простых проектах, которые обычно пишутся "для себя" это делается командой git merge с указанием веток, которые необходимо слить. В нашем случае, мы хотим, чтобы слияние произошло после ревью изменений другим человеком, для этого нужно опубликовать внесённые изменения. Это делается уже знакомой нам командой git push -u origin <your-branch-name>
  12. На сайте github.com создаём новый pull-request для нашего репозитория. В нём указываем источник изменений - нашу ветку, и назначение изменений - ветку master. В создаваемом запросе на слияние появится несколько вкладок, демонстрирующих какие именно изменения предлагается внести, сколько коммитов понадобилось для написания этих правок и так далее. С точки зрения ревью наиболее интересная вкладка Files, на ней отображаются конкретные изменения конкретных файлов с возможностью комментирования каждой строки.
  13. Важно помнить, что запросы на слияние создаются для веток, а не для конкретных коммитов, поэтому для внесения дополнительных правок после ревью можно осуществлять в уже существующей ветке, и эти правки будут сразу видны в пулл-реквесте. Но у этой особенности есть и обратная сторона - если закрыть пулл-реквест, но не слить ветки проекта - следующий запрос на слияние будет содержать правки всех предыдущих. Поэтому, по завершении работы над веткой, её нужно слить с основной веткой проекта (github позволяет сделать это нажатием кнопки merge) и удалить локально. Новые правки должны вноситься только в новой ветке, см. п. 9.
  14. Для того, чтобы обновить состояние локального репозитория необходимо выполнить команду git pull -a которая скачает из удалённого репозитория текущую версию проекта. Ключ означает, что нужно скачать все ветки.
  15. Если по какой то причине локальная ветка с изменениями не слилась с основной веткой репозитория, следует удостовериться, что Вы находитесь в ветке master, и выполнить команду git merge <your-branch-name>. Если все предыдущие пункты были выполнены именно так, как описаны, конфликтов слияния возникнуть не должно

Как мог заметить внимательный читатель, мы поговорили не только о запросах на слияние, но и том, что делать после того, как запрос был удовлетворён (или отклонён). Спасибо за внимание.