git switch и git checkout: В чем разница
git switch
и git checkout
используются для изменения веток, но у них есть различия в синтаксисе и поведении. Разберёмся в чём разница между ними.Одна из важнейших особенностей Git — возможность создавать различные ветки и работать в них. Ветки — это как параллельные временные линии проекта, в которых можно работать над различными функциями или экспериментами, не затрагивая стабильный код. Мы перемещаемся между ветками с помощью git switch
или git checkout
.
Для тех, кому лень читать
git checkout
— это старая команда, используемая для создания и переключения веток, а также для восстановления изменений с определённого коммита. Она также позволяет копировать файлы из любой ветки или коммита прямо в рабочее дерево, не переключая ветки. git checkout
делает больше, чем просто переключение веток, и это начало вызывать путаницу.
Поэтому с Git 2.23 разработчики представили две новые команды git: git switch
и git restore
. Идея заключается в том, чтобы git switch
использовали для переключения веток, а git restore
— для отмены изменений после коммита. git checkout
остаётся для расширенных опций работы с деревьями.
Подробное объяснение
Как указано в примечании к релизу 2.23.0, команды switch
и restore
были введены, чтобы разделить команду checkout
на две отдельные части:
проверка ветви для работы над продвижением её истории
проверка путей из индекса и/или дерева для работы над продвижением текущей истории
Другими словами, checkout
делает две разные вещи, и в этом релизе каждая из них выделена в отдельную команду.
Двойное назначение checkout
можно увидеть в его описании в документации:
git-checkout
— Переключение ветвей или восстановление файлов рабочего дерева
Коммит, добавивший команду switch
, объясняет обоснование новых команд в сообщении коммита:
Команда 'git checkout', выполняющая слишком много действий, приводит в замешательство многих пользователей (а иногда даже кусает старожилов). Чтобы исправить это, команда будет разделена на две новые:
switch
иrestore
. Старая добрая командаgit checkout
по-прежнему здесь и будет существовать до тех пор, пока она не надоест всем (или большинству пользователей).
Очевидно, что новые команды были введены для того, чтобы уменьшить путаницу: вместо одной многоцелевой команды можно использовать две специализированные.
Сравнение команд
Я не нашёл полного сравнения команд. Судя по документации, это должно быть достаточно полное сравнение:
Предыдущая команда | Новая команда |
---|---|
git checkout <branch> | git switch <branch> |
git checkout | Отсутствует (используйте git status ) |
git checkout -b <new_branch> [<start_point>] | git switch -c <new-branch> [<start-point>] |
git checkout -B <new_branch> [<start_point>] | git switch -C <new-branch> [<start-point>] |
git checkout --orphan <new_branch> | git switch --orphan <new-branch> |
git checkout --orphan <new_branch> <start_point> | Отсутствует (используйте git switch <start-point> затем git switch --orphan <new-branch> ) |
git checkout [--detach] <commit> | git switch --detach <commit> |
git checkout --detach [<branch>] | git switch --detach [<branch>] |
git checkout [--] <pathspec>… | git restore [--] <pathspec>… |
git checkout --pathspec-from-file=<file> | git restore --pathspec-from-file=<file> |
git checkout <tree-ish> [--] <pathspec>… | git restore -s <tree> [--] <pathspec>… |
git checkout <tree-ish> --pathspec-from-file=<file> | git restore -s <tree> --pathspec-from-file=<file> |
git checkout -p [<tree-ish>] [--] [<pathspec>…] | git restore -p [-s <tree>] [--] [<pathspec>…] |
Как показывает это сравнение, некоторые предыдущие варианты использования можно преобразовать в новые команды, просто заменив старое имя команды (checkout
) на новое (switch
, restore
), в то время как другие требуют дополнительной настройки. Заметные изменения включают:
- Опции
-b
/-B
для создания новой ветки перед переключением переименованы в-c
/-C
. Они также имеют длинные варианты опций (--create
/--force-create
), в отличие от прежних. --detach
(или-d
) теперь всегда требуется при переключении на отсоединённую голову, в то время как раньше она была необязательной для коммитов и обязательной для веток.- Исходное дерево для восстановления теперь задаётся опцией
-s
(или--source
), а не является инлайн аргументом. - Переключение с использованием
--force
(или-f
) теперь завершается неудачей, если есть не слитые записи, а не игнорирует их.--force
также был переименован в--discard-changes
, при этом--force
был сохранён в качестве псевдонима.