Параллельные линии работы: новая функция не мешает рабочей версии
Вы делаете на сайте новый раздел «Проекты» — работы на три дня. На второй день просят срочно исправить телефон в контактах. Без веток придётся либо выкладывать недоделанный раздел вместе с исправлением, либо прятать его вручную.
С ветками раздел «Проекты» живёт в своей ветке. Вы переключаетесь на основную ветку main, где раздела ещё нет, исправляете телефон, фиксируете и возвращаетесь к разделу. Две работы не мешают друг другу, а когда раздел готов, ветки сливаются (модуль 06).
Ветка в Git — это не копия файлов, а файл в .git/refs/heads/ с хешем одного коммита. Поэтому ветки создаются мгновенно и почти ничего не занимают.
$ cat .git/refs/heads/main
a3f9c21e8b4d0f6a91c2e7d35b80f14c6a92d7e3
Когда вы делаете коммит, текущая ветка сдвигается на новый коммит. HEAD — указатель на текущую ветку: он отвечает, какая ветка сдвинется при следующем коммите.
main
│
e15d2f0 ◀── 7b04e8d ◀── a3f9c21
│
projects HEAD ─▶ projects
Только что созданная ветка projects указывает на тот же коммит, что и main. После коммита в projects она уйдёт вперёд, а main останется на месте:
main
│
e15d2f0 ◀── 7b04e8d ◀── a3f9c21 ◀── 5d8e0f3
│
projects HEAD ─▶ projects
$ git branch projects # создать ветку, остаться на текущей
$ git switch projects # переключиться
Switched to branch 'projects'
$ git switch -c contacts # создать и сразу переключиться
Switched to a new branch 'contacts'
$ git switch - # вернуться на предыдущую ветку
Switched to branch 'projects'
Новая ветка создаётся от текущего коммита. Создать от другой точки — указать её вторым аргументом: git switch -c hotfix main.
switch встречаются git checkout projects и git checkout -b contacts. Они работают и сейчас, но switch делает только одно — переключает ветки, и в нём труднее ошибиться.При переключении Git меняет файлы в рабочем каталоге: на ветке main файла projects.html нет, на ветке projects — есть. Это нормально: файл хранится в коммитах своей ветки.
$ git branch
contacts
main
* projects # звёздочка — текущая ветка
$ git branch -v # с последним коммитом каждой
contacts a3f9c21 Добавить форму обратной связи
main a3f9c21 Добавить форму обратной связи
* projects 5d8e0f3 Добавить раздел с проектами
$ git branch -m contacts feature/contacts # переименовать
$ git branch -d feature/contacts # удалить
Deleted branch feature/contacts (was a3f9c21).
-d удалит ветку, только если её коммиты уже влиты в текущую. Иначе Git откажется и предупредит, что работа будет потеряна. Удаление с потерей — -D; используйте его, только когда уверены.
Несохранённые изменения не принадлежат ни одной ветке — они лежат в рабочем каталоге. При переключении Git переносит их с собой, если это безопасно. Если на другой ветке тот же файл отличается, Git откажется переключаться:
$ git switch main
error: Your local changes to the following files would be overwritten by checkout:
index.html
Please commit your changes or stash them before you switch branches.
Aborting
git stash — если работа не закончена (модуль 08).git restore — если изменения не нужны.git status. Чистый рабочий каталог («nothing to commit, working tree clean») — переключение безопасно.Если переключиться не на ветку, а на конкретный коммит, HEAD указывает прямо на коммит. Это состояние называется detached HEAD — отсоединённый HEAD:
$ git switch --detach e15d2f0
HEAD is now at e15d2f0 Первая версия главной страницы
$ git status
HEAD detached at e15d2f0
nothing to commit, working tree clean
Смотреть и запускать старую версию так можно. Коммитить — рискованно: новые коммиты не принадлежат ни одной ветке, и после переключения их трудно найти.
# просто посмотреть — вернуться на ветку
$ git switch main
# успели закоммитить и хотите сохранить — создать ветку здесь
$ git switch -c experiment
По имени ветки должно быть понятно, что в ней делается. Распространённое соглашение — тип и короткое описание латиницей через дефис:
| Ветка | Для чего |
|---|---|
main | Рабочая версия, всегда в исправном состоянии |
feature/projects-page | Новая функция |
fix/contact-phone | Исправление ошибки |
docs/readme | Документация |
feature/42-search | С номером задачи из трекера |
- и /.git switch -c имя — создать ветку и перейти на неёgit status: несохранённые изменения мешают или переезжают с вами