Git 2.23 introduces a new command git switch. After reading the documentation, it seems pretty much the same as git checkout <branchname>. What is the difference or use case?
Two new commands "git switch" and "git restore" are introduced to split "checking out a branch to work on advancing its history" and "checking out paths out of the index and/or a tree-ish to work on advancing the current history" out of the single "git checkout" command.
The
switchcommand indeed does the same thing ascheckout, but only for those usages that switch branches. It cannot restore working tree files — that is done usingrestore, the other command split off fromcheckout.The split
checkoutcommands, in summary:switch— Switch to a specified branchrestore— Restore file(s) from another branch or sourceDetailed explanation
As you noted in the 2.23.0 release notes section you quoted, the
switchandrestorecommands were introduced to split thecheckoutcommand into two separate pieces:In other words,
checkoutdoes two different things, and this release split each of those different things into its own focused command.This dual purpose of
checkoutcan be seen in its summary description in the documentation:The commit that added the
switchcommand explains the rationale for the new commands in its commit message:From this, it's clear that the new commands were introduced to reduce confusion by having two focused commands, rather than one multi-purpose command.
Note that (as of March 2024) the new commands are still listed as experimental (
switch,restore):Command comparison
I have not found a full comparison of the commands anywhere. From reading through the documentation, I think this should be a fairly complete comparison:
git checkout <branch>git switch <branch>git checkoutgit 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>thengit 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>…]As shown by this comparison, some prior usages can be converted to the new commands by simply replacing the old command name (
checkout) with the new one (switch,restore), whereas others require additional adjustment. Notable changes include:-b/-Boptions for creating a new branch before switching are renamed to-c/-C. They also have long option variants (--create/--force-create), unlike before.--detach(or-d) is now always required when switching to a detached head, where it was previously optional for commits but required for branches.-s(or--source) option, rather than being an inline argument.--force(or-f) now fails if there are unmerged entries, rather than ignoring them.--forcehas also been renamed to--discard-changes, with--forcebeing kept as an alias.