The switch
command indeed does the same thing as checkout
, but only for those usages that switch branches. It cannot restore working tree files — that is done using restore
, the other command split off from checkout
.
The split checkout
commands, in summary:
switch
— Switch to a specified branch
restore
— Restore file(s) from another branch or source
Detailed explanation
As you noted in the 2.23.0 release notes section you quoted, the switch
and restore
commands were introduced to split the checkout
command into two separate pieces:
- "checking out a branch to work on advancing its history"
- "checking out paths out of the index and/or a tree-ish to work on advancing the current history"
In other words, checkout
does two different things, and this release split each of those different things into its own focused command.
This dual purpose of checkout
can be seen in its summary description in the documentation:
git-checkout - Switch branches or restore working tree files
The commit that added the switch
command explains the rationale for the new commands in its commit message:
"git checkout" doing too many things is a source of confusion for many
users (and it even bites old timers sometimes). To remedy that, the
command will be split into two new ones: switch and restore. The good
old "git checkout" command is still here and will be until all (or most
of users) are sick of it.
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
):
THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.
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:
previous command |
new command |
git checkout <branch> |
git switch <branch> |
git checkout |
N/A (use 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> |
N/A (use git switch <start-point> then 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>…] |
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:
- The
-b
/-B
options 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.
- The source tree for restoring is now given by the
-s
(or --source
) option, rather than being an inline argument.
- Switching using
--force
(or -f
) now fails if there are unmerged entries, rather than ignoring them. --force
has also been renamed to --discard-changes
, with --force
being kept as an alias.
git checkout
? I see no deprecation warnings when using it. But withgit switch
andgit restore
, I now see no need forcheckout
. However, if it is not deprecated, the Git team has just made things more confusing, not less. Does anyone know the plans forgit checkout
? If it does still have a use case, can someone add or edit an answer to elaborate its use case. – Glutengit checkout <commit>
. – Ikedacheckout
will stick around just for its "corner case" that is used the minority of the time. This will stretch out the time of confusion. But I guess we'll just have to help each other out through it. :) – Glutengit switch --detach <commit>
– Opticswitch
explains thatgit checkout
isn't going anywhere: "The good old 'git checkout' command is still here and will be until all (or most of users) are sick of it." That also means that there is no need forcheckout
not covered byswitch
andrestore
, beyond ensuring existing user scripts and the like continue to function. – Manumitgit switch
still has a legend git-switch THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE, so I will advice to use it manually but not yet in automated Git Operations – Antswitch branch
behaves EXACTLY equals thancheckout branch
– Mellon