Ветка — ярлык
Ветки в Git пугают больше, чем заслуживают. Секрет простой: ветка — это ярлык, который указывает на коммит. Не копия проекта, не отдельная папка, а всего лишь имя, приклеенное к одному снимку.
Когда вы делаете коммит, ярлык текущей ветки переезжает на новый коммит. Поэтому ветка кажется «линией коммитов»: это путь, который прошёл её ярлык.
На схеме у проекта две ветки. main — основная, её ярлык стоит на C. feature создана от коммита B, и в ней сделаны коммиты X и Y. Ветки разошлись: у каждой свои новые коммиты, а общее прошлое — A и B.
Отметка HEAD говорит, в какой ветке вы сейчас. Новый коммит всегда встаёт после HEAD и двигает ярлык именно этой ветки. Отсюда главная ошибка новичка: сделать коммит «не в той ветке» — просто потому, что забыли, где находитесь. Лечится она привычкой смотреть git status: первая строка называет текущую ветку.
Основную ветку исторически называли master, сейчас чаще main. Разницы для Git нет — это просто имя, принятое в проекте.
Команды веток
Команд для веток немного.
git branch # список веток, текущая отмечена звёздочкой
git switch -c fix/discount # создать ветку и сразу перейти в неё
git switch main # перейти в существующую ветку
git branch -d fix/discount # удалить ветку, уже влитую в текущую
git switch -c создаёт ветку от того места, где вы сейчас. Поэтому перед созданием новой ветки обычно переходят в main и получают свежие изменения — иначе новая задача начнётся со старого состояния или, хуже, с середины другой задачи.
При переходе между ветками Git меняет файлы в рабочей папке: они становятся такими, какими были в коммите, на который указывает ветка. Файлы появляются, исчезают и меняются — это нормально, ничего не теряется, всё лежит в коммитах.
Удаление ветки с -d безопасно: Git откажется удалять ветку, коммиты которой нигде больше не сохранены. Ключ -D удаляет без вопросов — им пользуются, только когда точно знают, что работа в ветке не нужна.
В старых инструкциях вместо git switch встречается git checkout с именем ветки, а вместо switch -c — checkout -b. Это те же действия прежними командами.
Зачем ветки
Зачем вообще ветки, если можно коммитить прямо в main?
- main остаётся рабочей. Незаконченная задача живёт в своей ветке и не мешает тем, кто собирает и выкладывает проект из main;
- задачи не мешают друг другу. Вы начали большую переделку, а тут срочная ошибка. Переходите в main, заводите ветку под исправление, делаете, возвращаетесь к переделке — ничего не перемешалось;
- эксперимент ничего не стоит. Попробовали идею в ветке — не получилось — удалили ветку. main даже не узнала;
- готовое проверяют отдельно. Ветку можно показать коллеге целиком: вот все изменения по задаче. Об этом — урок про пулл-реквесты.
Когда задача готова, ветку сливают в main — изменения из неё становятся частью основной истории. Как это происходит и что делать, если изменения столкнулись, — в следующем уроке.
Имя и срок жизни
Две привычки делают ветки удобными, а не мучительными.
Понятное имя. Имя ветки должно говорить, что в ней. Частые схемы:
feature/contact-form # новая возможность
fix/discount-rounding # исправление ошибки
docs/payment-section # документация
MAG-214-discount # номер задачи и суть
Косая черта в имени — просто часть имени, её используют для группировки. Имена пишут латиницей, без пробелов, через дефис: так их проще набирать и они одинаково работают везде. «test», «new», «fix2» и «vasya» ничего не говорят — через неделю никто не вспомнит, что в них.
Короткая жизнь. Ветка, которая живёт два дня, сливается легко. Ветка, которая живёт два месяца, расходится с main так сильно, что слияние превращается в отдельную задачу: пока вы работали, main ушла вперёд на десятки коммитов, и ваши изменения сталкиваются с чужими.
Если ветке всё же приходится жить долго, её регулярно обновляют свежими изменениями из main — тогда расхождение копится маленькими порциями. Как именно — в уроках про слияние и удалённый репозиторий.
И последнее: влитые ветки удаляют. Список из сорока старых веток мешает найти нужную, а коммиты из влитой ветки никуда не денутся — они уже в main.