git branches

git checkout

Переключение ветки или восстановление файлов рабочего каталога

Описание

git checkout — многофункциональная команда, которая умеет делать несколько разных вещей: переключать ветки, создавать новые ветки, восстанавливать файлы до состояния из коммита или индекса, а также переходить в режим «detached HEAD». Именно из-за этой многофункциональности в Git 2.23 были добавлены специализированные команды git switch (для веток) и git restore (для файлов).

Команда git checkout по-прежнему полностью поддерживается и широко используется. Вы встретите её во многих руководствах, скриптах и при работе с более старыми версиями Git. Важно понимать обе формы: checkout <ветка> и checkout -- <файл> — они ведут себя принципиально по-разному.

Режим «detached HEAD» возникает при переключении на коммит или тег напрямую (не через ветку). В этом режиме можно изучать состояние репозитория на любой момент истории, но новые коммиты не будут принадлежать ни одной ветке и могут быть потеряны при смене HEAD.

Синтаксис

# Переключение на ветку git checkout <имя-ветки> # Создать ветку и переключиться git checkout -b <новая-ветка> git checkout -b <новая-ветка> <начальная-точка> # Создать с tracking от remote git checkout -b <ветка> --track origin/<ветка> # Переключиться на предыдущую ветку git checkout - # Перейти в detached HEAD git checkout <хеш-коммита> git checkout <тег> # Восстановить файл из коммита/индекса git checkout -- <файл> git checkout <коммит> -- <файл> git checkout HEAD~3 -- src/app.py # Восстановить все файлы (отменить изменения) git checkout -- .

Двойное тире -- разделяет имена веток/коммитов от путей к файлам. Без него Git может запутаться, если имя файла совпадает с именем ветки.

Флаги и опции

Флаг Описание
-b <ветка> Создать новую ветку и переключиться на неё
-B <ветка> Создать ветку принудительно (сбрасывает существующую) и переключиться
-t, --track При создании ветки настроить upstream-отслеживание
--no-track Не устанавливать upstream при создании ветки
-f, --force Принудительное переключение, отбрасывая незафиксированные изменения
-m, --merge Выполнить слияние при переключении с незафиксированными изменениями
--orphan <ветка> Создать ветку без истории (orphan branch)
-p, --patch Интерактивный выбор фрагментов при восстановлении файлов
--detach Явно перейти в detached HEAD, даже если указана ветка
-- Разделитель: всё после него интерпретируется как пути к файлам
-l Создать reflog для новой ветки

Паттерны использования

Создание feature-ветки

# Создать от текущей ветки
git checkout -b feature/payment

# Создать от main
git checkout -b feature/payment main

# Создать от remote-ветки с tracking
git checkout -b feature/payment --track origin/feature/payment

Восстановление файлов

# Отменить изменения в одном файле
git checkout -- src/app.py

# Восстановить всё в рабочем каталоге
git checkout -- .

# Взять файл из конкретного коммита
git checkout abc1234 -- config/settings.py

Изучение истории (detached HEAD)

# Перейти к конкретному коммиту
git checkout abc1234

# Посмотреть состояние 3 коммита назад
git checkout HEAD~3

# Вернуться обратно на ветку
git checkout main

Работа с тегами

# Перейти к версии для изучения
git checkout v1.2.0

# Создать ветку от тега (для hotfix)
git checkout -b hotfix/v1.2.1 v1.2.0

Частичное восстановление (-p)

# Интерактивно выбрать изменения для отмены
git checkout -p -- src/module.py

# Каждый фрагмент предлагается отдельно:
# y — восстановить, n — оставить изменение

Ветка-сирота

# Создать пустую ветку (например, для docs)
git checkout --orphan docs

# Удалить все файлы из индекса
git rm -rf .

# Начать с нуля
echo "# Документация" > README.md
git add README.md
git commit -m "init: docs branch"

Советы и подводные камни

Современная альтернатива: для новых проектов используйте git switch для веток и git restore для файлов. Это разделяет две разные операции и снижает риск случайного восстановления файлов вместо переключения ветки.
Detached HEAD — ловушка для новичков: если вы сделали коммиты в detached HEAD и затем переключились на ветку, эти коммиты стали «потерянными» (не принадлежат ни одной ветке). Чтобы сохранить их, немедленно создайте ветку: git branch имя-ветки <хеш-последнего-коммита>. Найти хеш можно через git reflog.
checkout -- . безвозвратно удаляет изменения: команда git checkout -- . восстанавливает все отслеживаемые файлы до состояния из индекса, безвозвратно уничтожая незафиксированные изменения. Неотслеживаемые (untracked) файлы при этом не трогаются. Перед использованием проверьте git status.