Confused by git checkout

That confusion is acknowledged by Git 2.23.
Git 2.23 (Q3 2019) will replace git checkout with two new commands:

  • git switch
  • git restore (illustrated here)

See commit 97ed685, commit d16dc42, commit bcba406 (20 Jun 2019), commit 4e43b7f, commit 1235875, commit 80f537f, commit fc991b4, commit 75f4c7c, commit 4df3ec6, commit 2f0896e, commit a5e5f39, commit 3a733ce, commit e3ddd3b, commit 183fb44, commit 4058199, commit a6cfb9b, commit be8ed50, commit c9c935f, commit 46e91b6 (25 Apr 2019), and commit 328c6cb (29 Mar 2019) by Nguyễn Thái Ngọc Duy (pclouds).
(Merged by Junio C Hamano — gitster — in commit f496b06, 09 Jul 2019)

checkout: split part of it to new command ‘switch

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.


switch: reject if some operation is in progress

Unless you know what you’re doing, switching to another branch to do something then switching back could be confusing. Worse, you may even forget that you’re in the middle of something.
By the time you realize, you may have done a ton of work and it gets harder to go back.

A new option --ignore-in-progress was considered but dropped because it was not exactly clear what should happen.
Sometimes you can switch away and get back safely and resume the operation. Sometimes not.
And the git-checkout behavior is automatically clear merge/revert/cherry-pick,
which makes it a bit even more confusing.
See this discussion.

We may revisit and add this option in the future.
But for now play it safe and not allow it (you can’t even skip this check with --force).
The user is suggested to cancel the operation by themselves (and hopefully they do consider the consequences, not blindly type the command), or to create a separate worktree instead of switching.

The third option is the good old “git checkout“, but it’s not mentioned.

See git switch man page


Switch to a specified branch.
The working tree and the index are updated to match the branch.
All new commits will be added to the tip of this branch.

Optionally a new branch could be created with either -c, -C, automatically from a remote branch of same name (see --guess), or detach the working tree from any branch with --detach, along with switching.

Switching branches does not require a clean index and working tree (i.e. no differences compared to HEAD).
The operation is aborted however if the operation leads to loss of local changes, unless told otherwise with --discard-changes or --merge.


The following command switches to the “main” branch:

$ git switch main

After working in the wrong branch, switching to the correct branch would be done using:

$ git switch mytopic

However, your “wrong” branch and correct “mytopic” branch may differ in files that you have modified locally, in which case the above switch would fail like this:

$ git switch mytopic
error: You have local changes to 'frotz'; not switching branches.

You can give the -m flag to the command, which would try a three-way

$ git switch -m mytopic
Auto-merging frotz

After this three-way merge, the local modifications are not registered in your index file, so git diff would show you what changes you made since the tip of the new branch.

To switch back to the previous branch before we switched to mytopic (i.e. “main” branch):

$ git switch -

You can grow a new branch from any commit.
For example, switch to “HEAD~3” and create branch “fixup“:

$ git switch -c fixup HEAD~3
Switched to a new branch 'fixup'

If you want to start a new branch from a remote branch of the same

$ git switch new-topic
Branch 'new-topic' set up to track remote branch 'new-topic' from 'origin'
Switched to a new branch 'new-topic'

To check out commit HEAD~3 for temporary inspection or experiment
without creating a new branch:

$ git switch --detach HEAD~3
HEAD is now at 9fc9555312 Merge branch 'cc/shared-index-permbits'

If it turns out whatever you have done is worth keeping, you can
always create a new name for it (without switching away):

$ git switch -c good-surprises

Note the error messages that “git switch” mentions its option to create a new branch, “-b/-B” options were shown, where “-c/-C” options should be, which has been corrected with Git 2.27 (Q2 2020).

See commit 7c16ef7 (30 Apr 2020) by Denton Liu (Denton-L).
(Merged by Junio C Hamano — gitster — in commit f4675f3, 08 May 2020)

switch: fix errors and comments related to -c and -C

Reported-by: Robert Simpson
Signed-off-by: Denton Liu
Reviewed-by: Taylor Blau

In d787d311db (“checkout: split part of it to new command ‘switch'”, 2019-03-29, Git v2.23.0-rc0 — merge listed in batch #4), the git switch command was created by extracting the common functionality of cmd_checkout() in checkout_main().

However, in b7b5fce270 (“switch: better names for -b and -B“, 2019-03-29, Git v2.23.0-rc0 — merge listed in batch #4), the branch creation and force creation options for ‘switch‘ were changed to -c and -C, respectively.

As a result of this, error messages and comments that previously referred to -b and -B became invalid for git switch.

For error messages that refer to -b and -B, use a format string instead so that -c and -C can be printed when git switch is invoked.

Leave a Comment