# Ветка (branch) _Ветки и слияния · GitLab Knowledge Base_ **TL;DR:** Ветка в Git - это файл в `.git/refs/heads/`, в котором лежит SHA одного коммита. Создание, переключение и удаление веток тривиальны, потому что данных в ветке - 41 байт. Ветка в Git - самая дешёвая операция. В централизованных VCS вроде SVN ветка означает копирование всего проекта; в Git - это создание файла с одной строкой. ## Что такое ветка физически ```bash cat .git/refs/heads/main # a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0 ``` Один SHA коммита. Всё. От этого коммита через `parent`-цепочку достаётся вся история, доступная из этой ветки. Создать ветку = создать файл с SHA текущего коммита. Передвинуть ветку = переписать этот файл. Удалить ветку = удалить файл. Поэтому branch/checkout/delete работают мгновенно даже на репозитории с миллионом коммитов. ## Базовые операции ```bash git branch # список локальных веток git branch -a # + удалённые git branch -v # + последний коммит каждой ветки git branch feature # создать ветку feature от HEAD git branch feature main # создать feature от main git switch feature # переключиться (новая команда) git checkout feature # переключиться (старая, всё ещё работает) git switch -c feature # создать и переключиться git branch -d feature # удалить (только если смержена) git branch -D feature # удалить принудительно git branch -m old new # переименовать ``` Со времён Git 2.23 (2019) есть две специализированные команды вместо перегруженного `checkout`: `git switch` для веток и `git restore` для файлов. Если только начинаешь - используй их, проще и безопаснее. ## HEAD и активная ветка Когда переключаешься на ветку - Git переписывает файл `.git/HEAD`: ``` ref: refs/heads/feature ``` Теперь все коммиты будут двигать ветку `feature`. HEAD - это «указатель на указатель». Если в HEAD оказался прямой SHA (без `ref:`), это *detached HEAD*. Происходит при `git checkout ` или `git checkout `. Коммиты в этом состоянии «висят в воздухе» - никакая ветка их не держит. Чтобы не потерять - `git switch -c rescue` создаст ветку из текущего HEAD. ## Tracking ветки Локальная ветка может «отслеживать» удалённую: ```bash git branch -u origin/main main # привязать main к origin/main git push -u origin feature # запушить и привязать ``` После этого `git status` будет показывать ahead/behind, `git pull` и `git push` без аргументов будут знать, куда идти. ## Подводные камни - `git branch feature main` создаст ветку **только** от текущего состояния main. Если main потом обновится - feature не догонит автоматически, придётся `merge` или `rebase`. - Удалять ветку, на которой ты сейчас стоишь, нельзя. Переключись куда-то ещё (`git switch main`) и тогда удаляй. - `git branch -D feature` молча удаляет ветку даже если у неё есть несмерженные коммиты. Если по ошибке - `git reflog` поможет восстановить (sha видно), но имя ветки придётся пересоздать. ## Команды ```bash git switch -c feature ``` Создать и переключиться на новую ветку ```bash git branch -d feature ``` Удалить ветку (только если смержена) ```bash git branch -vv ``` Список веток с last-commit и tracking-инфой ```bash git push -u origin feature ``` Запушить ветку и привязать к удалённой ## См. также - [git merge](/courses/git/kb/merge.md) - [Commit](/courses/git/kb/commit.md) - [git push](/courses/git/kb/push.md)