- Андрей Куманяев/
- Git: руководства и команды/
- git switch и git restore: современная замена git checkout (Git 2.23+)/
git switch и git restore: современная замена git checkout (Git 2.23+)
Git 2.23, выпущенный в августе 2019 года, представил две новые команды, которые разделили функциональность перегруженной команды git checkout:
git switch— для переключения между ветками и создания новых ветокgit restore— для восстановления файлов и сброса изменений
До этого одна команда git checkout выполняла обе функции, что было запутанным и противоинтуитивным. Если вы работаете с Git 2.23 или новее, рекомендуется использовать git switch и git restore вместо git checkout.
В этой статье мы разберём обе команды подробно, покажем все синтаксические варианты, и поясним когда использовать какую.
git switch: переключение между ветками #
Основное назначение git switch — это переключение между ветками в вашем репозитории.
Переключиться на существующую ветку #
git switch main
git switch develop
git switch feature-auth
Это самый простой случай. Если ветка существует локально, просто передайте её имя. Для более подробного понимания работы с ветками см. /ru/git/pereklyuchitsya-mezhdu-vetkami/.
Полный пример:
$ git branch
* main
feature-login
feature-auth
$ git switch feature-auth
Switched to branch 'feature-auth'
$ git branch
main
* feature-auth
feature-login
Создать новую ветку и переключиться на неё #
# Создать новую ветку и сразу переключиться
git switch -c new-feature
# Или с полным флагом
git switch --create new-feature
# Создать на основе другой ветки
git switch -c new-feature develop
Пример с базовой веткой:
# Вы на main, но хотите создать feature на основе develop
$ git switch -c feature-new-design develop
Switched to a new branch 'feature-new-design' tracking branch 'develop'
# Теперь вы на новой ветке, основанной на develop
$ git log --oneline -n 3
abc1234 Latest commit from develop
def5678 Another commit
ghi9012 Older commit
Отслеживать удалённую ветку (tracking branch) #
Когда вы переключаетесь на удалённую ветку, Git автоматически создаёт локальную ветку которая её отслеживает:
# Переключиться на удалённую ветку origin/feature-x
# Git автоматически создаст локальную feature-x
git switch feature-x
# Или явно указать удалённую ветку
git switch --track origin/feature-payment
# Более короткий вариант
git switch -t origin/feature-payment
Практический пример:
# Вы получили fetch обновлений от всех удалённых веток
$ git fetch
# Видите что появилась новая ветка в origin
$ git branch -r
origin/main
origin/develop
origin/feature-new-payment
# Переключаетесь на неё
$ git switch feature-new-payment
branch 'feature-new-payment' set up to track 'origin/feature-new-payment'
Switched to a new branch 'feature-new-payment'
# Теперь у вас есть локальная ветка которая отслеживает удалённую
Переключиться на предыдущую ветку #
# Вернуться на ветку на которой вы были перед этой
git switch -
Это удобно для быстрого переключения между двумя ветками:
$ git branch
* feature-auth
main
$ git switch -
Switched to branch 'main'
$ git switch -
Switched to branch 'feature-auth'
$ git switch -
Switched to branch 'main'
Обработка необработанных изменений #
Если у вас есть изменения в файлах, которые конфликтуют с целевой веткой, Git не позволит вам переключиться:
$ git status
On branch feature-auth
Changes not staged for commit:
modified: src/auth.js
$ git switch main
error: Your local changes to 'src/auth.js' would be overwritten by checkout.
Please commit your changes or stash them before you switch branches.
У вас есть несколько вариантов:
# Вариант 1: создать коммит ваших изменений
git add .
git commit -m "Work in progress on auth"
git switch main
# Вариант 2: отложить изменения (сохранить в stash)
git stash
git switch main
git stash pop # Вернуть изменения когда нужно
# Вариант 3: откатить изменения (опасно!)
git restore src/auth.js
git switch main
git switch к коммиту (detached HEAD) #
Хотя основное назначение git switch — работа с ветками, её также можно использовать для перехода к конкретному коммиту. Это перейдёт вас в “detached HEAD” состояние:
# Переключиться на конкретный коммит
git switch --detach abc1234
# Более короткий вариант
git switch -d abc1234
# Или переключиться к определённому релизу
git switch --detach v1.2.3
Что такое detached HEAD? #
Обычно вы находитесь “на ветке” (HEAD указывает на имя ветки). В detached HEAD состоянии HEAD указывает прямо на коммит:
# На нормальной ветке
$ git switch main
Switched to branch 'main'
$ git status
On branch main
# В detached HEAD
$ git switch -d abc1234
Switched to a detached HEAD state at abc1234
$ git status
HEAD detached at abc1234
Когда это полезно #
Detached HEAD полезен когда вы хотите:
# Посмотреть как выглядел проект в старом коммите
git switch -d abc1234
# смотрите файлы, запускаете старый код
# потом возвращаетесь
# Если нашли что-то важное, создаёте ветку
git switch -c investigate-old-bug
# Или возвращаетесь на нормальную ветку
git switch main
Полный пример:
$ git log --oneline -n 5
d7f8e9a Current version (HEAD -> main)
c4b3a2d Added feature X
b1c2d3e Refactored database
a1b2c3d Two weeks ago
# Хотим посмотреть как выглядел проект в коммите a1b2c3d
$ git switch -d a1b2c3d
Switched to a detached HEAD state at a1b2c3d
$ git status
HEAD detached at a1b2c3d
# Смотрим, запускаем, тестируем
# Нашли важный файл который был потерян
$ git switch -c recover-old-feature
# Делаем необходимые коммиты
$ git add .
$ git commit -m "Restore important old feature"
# Потом смержим в main
$ git switch main
$ git merge recover-old-feature
# Если ничего не нужно было, просто возвращаемся
$ git switch main
$ git branch -D some-detached-work
git restore: восстановление файлов #
git restore заменяет функциональность git checkout для работы с файлами. Это команда для отката изменений в файлах.
Отменить изменения в файле #
# Отменить все изменения в одном файле
git restore src/auth.js
# Отменить изменения в нескольких файлах
git restore src/auth.js src/user.js
# Отменить все изменения в текущей директории
git restore .
Пример:
$ git status
On branch main
Changes not staged for commit:
modified: src/auth.js
modified: src/user.js
$ git restore src/auth.js
$ git status
On branch main
Changes not staged for commit:
modified: src/user.js
Отменить staged изменения #
Если вы выполнили git add но хотите отменить это:
# Отменить staging для одного файла
git restore --staged src/auth.js
# Или для всех файлов
git restore --staged .
Полный пример:
$ git status
On branch main
Changes to be committed:
modified: src/auth.js
new file: src/validation.js
# Отменяем staging для файла
$ git restore --staged src/auth.js
$ git status
On branch main
Changes to be committed:
new file: src/validation.js
Changes not staged for commit:
modified: src/auth.js
Восстановить файл из конкретного коммита #
# Восстановить версию файла из предыдущего коммита
git restore --source=HEAD~1 -- src/auth.js
# Из конкретного коммита
git restore --source=abc1234 -- src/auth.js
# Из определённой ветки
git restore --source=develop -- config.json
Практический пример:
# Вы случайно удалили важный файл
# Но помните что он был в коммите abc1234
$ git restore --source=abc1234 -- src/deleted-file.js
$ git status
On branch main
Changes to be committed:
new file: src/deleted-file.js
# Файл восстановлен и в staging, готов к коммиту!
Комбинирование флагов #
# Отменить staged И unstaged изменения (вернуть к HEAD)
git restore --staged --worktree -- src/auth.js
# Более короткий вариант
git restore -SW -- src/auth.js
Сравнение с git checkout #
Для пользователей старых версий Git — вот как переходить со старого синтаксиса на новый:
Для веток #
| Старый синтаксис (checkout) | Новый синтаксис (switch) |
|---|---|
git checkout main | git switch main |
git checkout -b new-feature | git switch -c new-feature |
git checkout --track origin/feature | git switch --track origin/feature |
git checkout - | git switch - |
git checkout -b feature develop | git switch -c feature develop |
git checkout --detach abc1234 | git switch --detach abc1234 |
Для файлов #
| Старый синтаксис (checkout) | Новый синтаксис (restore) |
|---|---|
git checkout -- src/file.js | git restore src/file.js |
git checkout abc1234 -- file.js | git restore --source=abc1234 -- file.js |
git checkout HEAD -- . | git restore . |
| нет прямого аналога | git restore --staged file.js |
Когда использовать что: принятие решения #
Используйте git switch когда:
- Нужно переключиться на другую ветку
- Нужно создать новую ветку
- Нужно переключиться на удалённую ветку
- Нужно вернуться на предыдущую ветку (
git switch -)
Используйте git restore когда:
- Нужно отменить изменения в файле(ах)
- Нужно отменить staging
- Нужно восстановить файл из старого коммита
- Нужно вернуть файл в состояние из другой ветки
Используйте git checkout когда:
- Вы на старой версии Git (< 2.23)
- Вам нужна максимальная совместимость со старыми скриптами
FAQ: Частые вопросы про switch и restore #
Q: Работает ли git checkout всё ещё?
A: Да, git checkout всё ещё работает и не планируется удаляться. Но он считается устаревшим (deprecated) и рекомендуется использовать git switch и git restore для новых проектов.
Q: Какая версия Git мне нужна?
A: git switch и git restore появились в Git 2.23 (август 2019). Проверьте вашу версию:
git --version
Если у вас более старая версия, обновите Git или используйте git checkout.
Q: Что будет если я переключусь с незакоммиченными изменениями?
A: Если изменения конфликтуют с целевой веткой, Git выдаст ошибку и не позволит переключиться. Вы должны либо закоммитить, либо отложить изменения (git stash), либо откатить их (git restore).
Q: В чём разница между git restore и git checkout для файлов?
A: В функциональности нет разницы — они делают то же самое. Разница в синтаксисе: git restore понятнее и специализирован именно для файлов, в то время как git checkout смешивает две разные задачи (ветки и файлы).
Q: Может ли git switch переключать теги?
A: Да, вы можете переключиться на тег (он создаст detached HEAD):
git switch --detach v1.2.3
Это переведёт вас к состоянию на момент релиза v1.2.3.
Заключение #
git switch и git restore — это современный, понятный способ работы с ветками и файлами в Git:
git switchдля всей работы с ветками (переключение, создание, отслеживание удалённых)git restoreдля восстановления и отката файлов
Эти команды имеют намного более логичный синтаксис чем старый git checkout и рекомендуются всем, кто использует Git 2.23 или новее.
Для более глубокого понимания работы с ветками см. /ru/git/pereklyuchitsya-mezhdu-vetkami/ и /ru/git/kak-sozdat-vetku-git/. Для отката изменений см. /ru/git/otmenit-izmeneniya-fajl-git/ и /ru/git/git-stash/.