Продвинутая работа с Git
Last updated
Last updated
Для ознакомления с данной инструкцией нужно понимать, что означают следующие понятия:
репозиторий (локальный и удаленный);
проиндексировать изменения;
коммит, коммитить изменения;
пушить изменения на удаленный репозиторий;
связать удаленный и локальный репозиторий.
Также нужно уметь создать репозиторий на Gitlab, и запушить туда папку с локального репозитория. Если все вышеперечисленное понятно, то можно приступать к чтению далее. Если нет, предлагаем для начала ознакомиться с и попрактиковать эти навыки, потому что если этого не сделать - дальше читать нет смысла.
Далее будет объяснены основные правила работы с Git в контексте командной работы и показано, как решать те или иные задачи с помощью терминала. Все задачи можно решить также и другими способами, например с помощью плагинов для редакторов кода или специальных программ для управления Git. В данной инструкции показана работа именно через терминал. Пользоваться терминалом или другими способами - остается на усмотрение студента. Но попрактиковать работу с терминалом никогда не будет лишним, так как он дает максиамльно широкие возможности управления вашим проектом, а также доступ к абсолютно всем функциям гита, в то время как во вспомогательных программах чаще всего реализованы только часто используемые функции.
В процессе чтения инструкции нужно будет выполнять задачи, данные по ходу инструкции, для закрепления прочитанного.
После прочтения инструкции студент должен уметь:
Склонировать чужой проект, создать новый проект.
Создать локально новую ветку, переключиться на нее, удалить ветку.
Запушить в удаленный репозиторий свою ветку.
Смерджить локальный master
с локальной веткой.
Залить свои изменения в удаленный master
.
Уметь решать все конфликты, возникающие в процессе мерджей.
Система ветвления в Git
Представим себе, что в команде работает несколько разработчиков. У каждого есть свой компьютер, где он работает над проектом. Все разработчики работают над одним и тем же проектом. Сразу возникает вопрос - как по-человечески организовать разработку так, чтобы несколько разработчиков, разрабатывая один и тот же проект, имели возможность синхронизировать свой вклад в проект и иметь на выходе один большой готовый продукт?
Для решения этой задачи Git предлагает подход, который называют ветвлением. Ветка - это версия кода. Некое сохраненное состояние проекта, имеющее свое название.
Условно это можно показать так:
Всегда есть главная ветка, которая обычно называется master
(Branch master
на рисунке). Это, человеческим языком, финальная версия проекта, условно говоря "чистовик", куда разработчики заливают то, что пойдет в готовый продукт и в итоге увидят клиенты.
Во время работы над проектом, разработчик коммитит различные изменения, пишет код и так далее. Когда приходит время заливать изменения на главную ветку, он делает так называемый мердж реквест (или пулл-реквест). Это запрос на слияние 2 веток.
Если мердж реквест одобрен и все ок (об этом пойдет речь далее), разработчик мерджит свою ветку в главную ветку.
Разберемся в некоторых описанных выше понятиях.
Ветка (бранч) - это версия проекта, имеющая название. В одном и том же проекте может быть много веток, и между ними можно переключаться. Когда вы переключаетесь на другую ветку - версия кода динамически меняется на компьютере. Ветки могут быть локальными и удаленными. Так же как репозиторий есть локальный и удаленный, так и ветки в нем могут храниться только локально, только удаленно, и также и локально и удаленно.
Отколоться от ... (название ветки) - означает создать новую ветку на основе ... (название ветки). Например, нам нужно отколоться от ветки master
. Это значит, что мы создаем ветку, например modal
, являющуюся в момент создания копией ветки master
. Когда мы это сделаем, мы сможем менять то, что нужно, в нашей ветке, не затрагивая ее основную версию - мастер. Условно говоря, создать черновик, что-то в нем исправить и только потом заливать изменения в главную ветку, когда они будут вычищены и финализированы. Таким образом можно кодить, добавлять что-то в проект, тестировать, не затрагивая основную работоспособную версию кода, которая крутится в production.
Померджить ветки, смерджить ветки - слияние 2 веток. Обычно это означает - залить свою ветку в главную ветку, например вашу ветку в мастер, тогда это называют - смерджить в мастер. Когда вы мерджите одну ветку в другую (предположим ветку new-branch
в master
), git сравнивает 2 версии кода (2 ветки) - оценивает какие в ветке new-branch
были изменения в коде по сравнению с веткой master
. И именно эти изменения и добавляет в master
. После мерджа - изменения из ветки new-branch
окажутся в ветке master
.
Мердж реквест (пулл реквест) - запрос (просьба) на слияние 2 веток в удаленном репозитории. Это еще не само слияние, а некое информирование о намерениях. После такого запроса, гит оценит, может ли такое слияние быть выполнено, и разрешит или не разрешит мердж. Для того, чтобы сделать такой запрос, нужно это оформить через Gitlab (или Github или другой удаленный репозиторий, в котором хранится проект), с помощью определенных действий и заполнения определенных полей (об этом подробнее будет сказано далее).
Для того, чтобы начать разработку, нужно создать свою ветку, и начать в ней работать. Для этого нужно отколоться от ветки master
или от ветки develop
(если она есть, на каждом проекте могут быть свои правила).
Задача
Возьмите любую домашнюю работу, которая у вас есть на удаленном и локальном репозитории.
Откройте терминал в папке проекта. Можно открывать как git bash (если Windows), локальный терминал компьютера, так и терминал, встроенный в редактор кода. Это не имеет значения.
Чтобы узнать, на какой ветке мы сейчас находимся, вводим команду git status
.
Также во многих редакторах кода и IDE текущая ветка подсвечивается в нижней части интерфейса.
Создание локальной ветки
Для того, чтобы отколоться от ветки master, нужно, находясь в ней, создать новую ветку, и перейти на эту новую ветку.
Это можно сделать двумя способами:
Способ 1. Вначале создать новую ветку, и потом вручную переключиться на нее.
Для создания новой ветки пишем в терминале git branch new-branch
. new-branch
- это имя новой ветки.
Для переключения на новую ветку пишем в терминале git checkout new-branch
.
Способ 2. Создать ветку, и переключиться на нее одной командой.
Пишем в терминале git checkout -b new-branch
. new-branch
- это имя новой ветки, -b
это дефис и буква b.
Если все прошло успешно, появится следующее сообщение:
Задача
Находясь в ветке master, отколоться от нее, создав две новых ветки.
Первая ветка - проделать "Способ 1", указанный выше. Назвать ветку "footerFix". Вторая ветка - проделать "Способ 2", указанный выше. Назвать ветку "headerFix".
Слияние изменений с главной веткой
Задача
Находясь в ветке "footerFix", внесите в файл "index.html" какие-либо изменения. Например, добавьте новый класс или добавьте новый тег.
Проиндексируйте эти изменения, сделайте коммит.
Находясь в ветке "headerFix" внесите в файл "style.css" какие-либо изменения. Например, добавьте новое свойство в какой-либо класс.
Проиндексируйте эти изменения, сделайте коммит.
Для того, чтобы смерджить в master
, или любую другую ветку, нужно понимать такие понятия как target branch
и source branch
.
Target branch - это ветка, КУДА мы будем добавлять наши изменения. После мерджа Target branch
будет содержать новый код.
Source branch - это ветка, ОТКУДА мы будем добавлять наши изменения в Target branch
. После мерджа Source branch
не изменится.
Чтобы мерджить ветки локально (на вашем компьютере), нужно находиться на ветке, которая является Target branch (в нашем случае master
).
Если вы сейчас не в ней, то в терминале необходимо ввести команду git checkout master
.
Далее вводим команду git merge new-branch
(new-branch
- это имя ветки, которую мы хотим смерджит в мастер).
Задача
Смерджить ветку "footerFix" в ветку "master".
Если все прошло хорошо, результат будет выглядеть примерно так:
То есть в ответе не должно фигурировать большими буквами слово КОНФЛИКТ
.
Мердж с удаленной веткой
Чтобы слить свою ветку с удаленной веткой, необходимо выполнить следующие действия:
Для начала нам необходимо запушить свою локальную ветку в удаленный репозиторий. Для этого после индексации и коммита необходимо в терминале выполнить команду git push origin new-branch
. new-branch
- это имя нашей ветки, которая будет создана после этой команды в удаленном репозитории. Оно должно совпадать с названием ветки, на которой мы сейчас находимся.
Создать мердж реквест. После того, как была создана удаленная ветка, нужно сделать мердж реквест. Для этого есть два способа.
Способ 1. После предыдущей команды терминал формирует ссылку. Переходим по ней:
Способ 2.
Находясь на странице своего репозитория на сайте Gitlab, необходимо найти кнопку Create merge request и нажать на нее.
Задача
Создать мердж реквест через Gitlab (или Github) с ветки "footerFix" в "master" как описано в "Способе 1".
Смерджить в мастер.
Первым делом после создания мердж реквеста, прокручиваем вниз и находим все те же Target branch
и Source branch
. Если нужно что-то менять, в зависимости от того, что куда будем мерджить, то меняем сразу, потому если в будущем эти ветки поменять, можно потерять данные.
В самом мердж реквесте видим такую картину:
From new-branch into master - это все те же Source branch
и Target branch
.
Title - это название мердж реквеста.
В разных компаниях принято их называть по-разному. Где-то это - название задачи, как она сформулирована в таск-менеджере. Где-то - просто кратко смысл того, что будет залито.
Например, если вы сделали header для сайта, то тут, например, будет Site header
.
Description - краткое описание мердж реквеста. Например, это может быть:
Added burger menu
Refactoring styles
И так далее.
Assignee - это человек, который будет мерджить ваш реквест. Его задача - просмотреть ваш мердж реквест, убедиться, что вы не сделали ошибок (например не хотите вмерджить в мастер какие-то конфиденциальные данные), оценить качество кода, и подтвердить мердж.
Если такого человека нет (что не есть "best practice"), то мерджить будете сами.
Внизу есть вкладка под названием Changes. Тут отображены изменения, которые будут внесены в Target branch
после мерджа.
Если все ок, нажимаем кнопку Submit merge request
.
После нажатия на кнопку, наш merge request
будет создан.
Находим наш мердж реквест, нажимаем на него и жмем кнопку Merge
.
На скриншоте видно, что выбрана галочка Remove source branch
. Это означает, что после мерджа удаленная ветка source branch
будет удалена из репозитория на gitlab. Локально на компьютере она останется. Это делается, чтобы, так сказать, не мусорить :) Обычно для последующих задач создаются уже новые ветки, и так далее.
Задача
Сделать мердж реквест через Gitlab (или Github) с ветки "headerFix" в "master" как описано в "Способе 2" при создании мердж реквеста. Заполнить поля "Title" и "description" в соответствии со смыслом внесенных изменений.
Сделать так, чтобы после мерджа "Source branch" была удалена.
Смерджить в мастер изменения.
Все, после мерджа, все наши изменения находятся в ветке master.
Как локально получить изменения, внесенные в master другим разработчиком?
Вам нужно всегда держать главную версию (master) в актуальном состоянии, иначе Гит просто не даст вам смерджить свои изменения, если они будут конфликтовать (далее будет рассмотрено что такое конфликты и как их решать) с главной веткой или если у вас давно не обновлялась главная ветка.
Для того, чтобы обновить состояние локальной ветки master
- находясь локально в ветке master
, вводим команду git pull origin master
.
pull
- команда, которая забирает с удаленного репозитория изменения.
origin
- название удаленного репозитория. По умолчанию он всегда называется origin
.
master
- ветка с которой стягиваются изменения.
В разговорной речи это называться спулиться, спулить изменения, сделать пулл.
Задача
Перейти локально в ветку "master".
Стяните все изменения из удаленного "master".
Иногда может появляться вот такая штука. Если это происходит, введите сообщение для объяснения почему вы делаете слияние веток, или просто нажмите Ctrl+X (комбинация может отличаться в зависимости от установленного на вашем компьютере консольного текстого редактора по умолчанию).
По стандартам современной разработки, в локальном master
разработка никогда не ведется. Ваш локальный master
может обновляться только в следующих случаях:
Вы смерджили локально одну из своих веток в локальный мастер, и запушили изменения на удаленный репозиторий.
Вы стянули в локальный мастер изменения с удаленного репозитория. Делать это рекомендуется максимально часто.
Если вы ведете разработку в своей ветке и понимаете, что в ветке master
на удаленном репозитории есть изменения, вам желательно иметь эти изменения в своей ветке, чтобы работать с последней актуальной версией кода. Чтобы это сделать, необходимо:
Перейти со своей локальной ветки на локальный master
.
Спуллить все изменения с удаленного репозитория.
Снова перейти на свою ветку, и вмерджить локальный мастер в вашу рабочую ветку. В данном случае source branch
будет master
, а target branch
- ваша рабочая ветка.
Задача
Перейти локально в ветку "footerFix".
Смерджить изменения из локального "master".
В ветке "footerFix" в файле "index.html" создать несколько новых тегов. Можно просто несколько раз скопировать существующие. Главное - внести изменения.
Замерджить эти изменения в удаленный "master".
В ветке "headerFix" в файле index.html на тех же строках создать другие теги. Можно просто несколько раз скопировать существующие. Главное - внести изменения.
Попытаться замерджить эти изменения в удаленный "master". Скорее всего, у вас не получится это сделать.
Что произошло и как это исправить?
Конфликты
Вы нарвались на так называемые конфликты. Конфликты возникают, когда вы хотите слить две ветки, в которых были внесены изменения в один и тот же кусок кода. То есть изменения в одной из веток могут перетереть изменения в другой ветке. Гит не знает, какая версия для вас будет более актуальной, поэтому он просит ему это указать.
На данный момент конфликт возник на этапе мерджа в удаленный master
. Если это произошло, вот что нужно сделать:
Перейти в локальный master
.
Спулить master
.
Перейти в ту ветку, которую не удалось замерджить (в нашем случае - headerFix
).
Замерджить в эту ветку локальный master
.
Увидеть, что у нас есть конфликты.
Самый лучший и понятный визуальный интерфейс для решения конфликтов предлагает компания JetBrains в своих продуктах.
Откройте свой проект с конфликтами в любом из редакторов кода этой компании - Intellij IDEA, WebStorm, PhpStorm и так далее.
Найдите вкладку VCS.
В ней - выберите Git → Resolve conflicts
.
Если конфликтов в проекте нет, то эта опция будет недоступной.
У вас появится вот такое окно. Тут можно увидеть перечень всех файлов, в которых в проекте возникли конфликты при мердже. Нажимаем двойным кликом по файлу (либо выбрать файл и нажать кнопку Merge...
).
Внимательно посмотрим на интерфейс.
Сейчас тут отображено три версии файла.
Версия слева - это ваша локальная версия, то что писали вы.
Версия справа - версия файла с ветки master, которую мы пытаемся вмерджить
Посередине - итоговый результат. То что будет в вашей ветке после окончания мерджа.
Чтобы принять какое-либо изменение в итоговый результат, нужно нажать на стрелочку рядом с ним.
Чтобы отклонить изменение - нужно нажать на крестик.
Абсолютно все изменения, которые гит отобразил, нужно обработать таким образом - нажать или на крестик или на стрелочку.
При этом есть ряд изменений, которые не приводят к конфликтам. По цвету заливки изменения можно определить, является ли это изменения конфликтующим. Конфликтующие изменения выделены красным цветом. Синие или зеленые - это изменения в строках кода, которые были сделаны только в одной из веток, и которые, соответственно, не приводят к возникновению конфликта. Но такие изменения тоже нужно вручную принимать.
Чтобы разом принять все неконфликтующие изменения в файле, можно нажать на кнопку Apply all non-conflicting changes
с двумя зелеными стрелками в верхней левой части окна.
После этого в файле останутся только конфликтующие изменения, каждое из которых надо будет разрулить вручную, указав какие куски кода мы оставляем, а какие надо удалить.
Внимательно проверяйте, что вы в итоге будете сохранять. Чтобы случайно не перезатереть изменения вашего коллеги.
Если немного натупили где-то, то всегда можно нажать кнопку Abort
и все сделать заново.
Когда вы решили конфликты, будет показана такая плашка:
Нажимаем на синюю ссылку в ней или кнопку Apply
внизу окна.
Если конфликты возникли в нескольких файлах, каждый файл нужно обработать таким образом.
Если все было сделано правильно, вы решили конфликты.
Вот что после этого покажет команда git status
:
Последуем совету. Закоммитьтесь. Обычно в commit message
при этом пишут что-то вроде resolved merge conflicts
.
Теперь это все нужно запушить на удаленную ветку.
Задача
Решить все конфликты.
Запушить изменения в удаленную ветку.
А теперь посмотрим что произошло с мердж реквестом, сделанным ранее, где возникли конфликты. Мы сделали мердж-реквест, потом что-то добавили в эту ветку. Открытый мердж реквест автоматически обновился согласно новой версии кода. На данный момент конфликтов нет.
Все, мы можем его мерджить.
Общие рекомендации по работе с Git
В проекте всегда лучше держать минимум 2 ветки. Первая ветка - develop
, вторая - master
. master
- это ветка, которая используется в production, по-простому чистовик проекта. Там все должно быть в идеальном рабочем состоянии. Лить напрямую в master
- плохой тон. develop
- это ветка, куда разработчики добавляют новый функционал, там он тестируется, фиксятся баги, и потом в определенный момент времени принимается решение о мердже ветки develop
в ветку master
.
Пишите осмысленные commit messages
. Что вы там сделали, в двух словах. Потом по логам проще отслеживать это и вернуться к какому-то коммиту.
Для каждой задачи необходимо создавать новую ветку. Не нужно иметь одну лично свою ветку, и только там кодить. Начали выполнять новую задачу - откололись от develop
, назвали ветку названием задачи, написали код, смерджили с develop
, удалили ветку.
При мердже через Gitlab, если ветка больше не нужна, удаляйте ее, выбирая галочку Remove source branch
. В других удаленных репозиториях для этого есть аналогичный функционал. Чтоб не разводить бардак в проекте в этом плане. Когда у вас накопится в удаленном репозитории больше 30 веток, которые уже не нужны - это сильно затрудняет ориентацию в проекте. Иногда бывает ситуация, когда тебе нужно забрать себе все удаленные ветки, потому что тебе нужно их 3. Если их там будет 150 - это будет ад.
Для работы с Git можно использовать не только терминал. Множество редакторов кода предлагают встроенные плагины и GUI. Это личное дело каждого, пользоваться терминалом, или каким-то плагином для редактора кода. Иногда правда бывает, что плагины подглючивают и могут или неправильно смерджить ветки, или не допушить какие-то файлы. Терминал просто банально надежнее. Но при этом в терминале гораздо легче "накосячить", написав не ту команду.
Держите главную ветку в своем локальном репозитории (master
, develop
) в актуальном состоянии. Есть даже такая шутка - первое что делает в начале рабочего дня программист - git pull
. Лучше в процессе работы над задачей, если вы знаете, что главная ветка обновляется другими людьми, фиксить небольшое количество конфликтов, чем обновлять главную ветку раз в месяц, а потом понять, что у вас 120 конфликтов в 60 файлах. Решать вы будете их долго. Лучше до такого не доводить.
Старайтесь не мерджить свои мердж реквесты самостоятельно. Пусть ваш мердж реквест посмотрит другой человек. Он свежим взглядом может оценить код и увидеть какие-то ошибки и неточности в нем, сказать вам об этом, чтобы вы исправили. На практике очень редко бывает, что мердж реквесты не проверяются другими людьми. Это делается как во избежание различных механических ошибок, которые разработчик мог допустить, так и на случай, если было сделано что-то действительно плохое (например удалена какая-то важная часть функционала проекта).
Убедитесь, что сразу же после создания проекта и подключения его к Git вы добавили все системные файлы в .gitignore
.
Как работать с Git в команде во время степ-проекта
Студент 1 создает репозиторий в Gitlab, пушит туда скелет проекта.
Студент 2 клонирует репозиторий себе локально. Это делается командой git clone https://gitlab.com/IrinaSt/homework-4-form.git
, где ссылка - это ссылка на репозиторий git, взятая отсюда:
Дальше идет работа по принципам, которые были описаны выше. Создаются ветки, мерджатся, решаются конфликты и так далее.
На первое время хорошо иметь для себя шпаргалку с основными командами по работе с git. Например такую как . Лучше всего составить ее для себя самому, и еще раз перечитать, что та или иная команда делает. Со временем это все будет делаться на автомате, и она больше не будет нужна. Но на первых порах - пока не запомнилось все - это очень полезно.