Предыдущая часть:
В предыдущей части мы рассмотрели создание веток из прошлого коммита. Но такие действия нужны редко – только когда мы что-то упустили в прошлом и хотим вернуться назад.
Гораздо чаще ветки создаются не в прошлом, а в текущем состоянии. Процесс ничем не отличается, команды те же самые.
Я нахожусь в ветке main, и создаю от её головы ветку dev:
git branch dev
Если я теперь посмотрю лог, то увижу, что HEAD показывает на две ветки: main, dev.
Всё верно, так как именно в этом месте ветка dev начинается из main.
Куда прогресс пойдёт дальше, зависит от того, какую ветку я выберу. Переключаюсь в ветку dev и опять смотрю лог:
С виду ничего не изменилось (только теперь HEAD показывает на dev, main). Я вижу те же самые коммиты, которые были в main. Это логично, потому что dev выросла из main и значит унаследовала всё, что было до этого.
Но так как я переключился в dev, все новые коммиты будут теперь добавляться в dev.
Зачем это нужно?
Отращивание новых веток в принципе не имеет никакой критической необходимости. Рассматривать их нужно с точки зрения удобства и порядка. В реальной жизни, когда вы сталкиваетесь со сложными процессами, требующими много действий, вы естественным образом упорядочиваете эти процессы и разбиваете их на подпроцессы. Например, при уборке дома вы отдельно подметаете пол, отдельно раскладываете предметы, отдельно моете посуду и т.д.
Каждую активность вы начинаете и заканчиваете, и затем она становится вкладом в общий результат.
Так же и с ветками Git. Когда вам нужно решить какую-то подзадачу, вы выделяете под неё отдельную ветку. В этой ветке вы можете делать коммиты, ошибаться, откатываться назад, в общем вести всю рутинную разработку. Когда же вы закончите, результат можно будет слить с основной веткой. Этот результат будет готовым и чистым, и таким образом главная ветка не будет засоряться неудачными коммитами.
Коллективная работа
Хотя мы здесь пока не рассматриваем аспект коллективной работы, ветки особенно важны для неё. В команде программистов могут быть сеньоры, джуны и т.д., и далеко не каждый из них может засылать обновления в главную ветку. Например, работа джуна сначала должна быть одобрена сеньором.
Поэтому все работают в своих собственных ветках, и только в конце посылают их в общее хранилище. После проверки ответственным лицом эти ветки сливаются с главной.
Слияние веток
Я симулирую работу в ветке dev, добавив файл readme.txt и затем изменив его. Получилось два новых коммита.
На этом работа в ветке закончена, и я солью её в main. Нужно перейти в ветку main:
git switch main
И дать команду
git merge dev
Расшифровывается это так: залить ветку dev в ту ветку, в которой мы сейчас находимся, т.е. в main.
Cмотрим лог:
Все коммиты из dev попали в main, и теперь эти две ветки идентичны. Для этого лога я использовал дополнительную опцию --graph, чтобы Git нарисовал дерево, которое получилось. Но здесь ничего не получилось.
Ожидалось, что дерево будет выглядеть так:
Но поскольку в main за это время не было ни одного нового коммита, Git поступает проще: спрямляет ветку dev так, что она является продолжением main.
Посмотрим вариант, когда работа ведётся одновременно в двух ветках. В ветке main я добавлю новый файл readme2.txt, и сделаю коммит. В ветке dev ещё раз исправлю файл readme.txt, и тоже сделаю коммит.
Теперь я солью ветку dev в main. Посмотрим лог:
Теперь видно, что с момента последнего слияния коммиты появились в обеих ветках, ветки разошлись, а потом сошлись, и точкой схода стал новый коммит 59981b6 в main. Мы его не делали, он создался сам.
Слияние не значит, что ветка dev закончилась. Она по-прежнему отдельная ветка, и в ней могут появляться новые коммиты. Точка слияния это просто место, где изменения из ветки dev перешли в ветку main.
Например, если я ещё раз изменю файл в ветке dev и сделаю коммит и снова солью dev в main, то лог получится такой:
Есть уже две точки слияния, и ветка dev продолжается параллельно с main.
Заключение
В принципе это весь основной функционал, который нужен в Git. Если вы его освоили, то можете смело пользоваться Git для своих проектов. В дальнейшем мы рассмотрим, как решать конфликты веток, как обслуживать ветки и другие расширенные функции.
Читайте дальше: