git checkout vs git switch
For more than a decade, git checkout was the command for everything related to branches and files. It did too much, which confused beginners and even experienced users. In Git 2.23 (2019), the maintainers split it into two clearer commands: git switch (change branches) and git restore (restore files). Both spellings still work, but modern tutorials prefer the split commands.
What git checkout could do
Use case | Old syntax (still works) |
|---|---|
Switch branches | git checkout main |
Create + switch | git checkout -b feature |
Detach HEAD at a commit | git checkout 1f9ab2c |
Restore one file from HEAD | git checkout -- file.js |
Restore a file from another commit | git checkout main -- file.js |
Throw away all unstaged changes | git checkout -- . |
Notice that the same command does branch operations AND file operations. That overlap is why beginners were terrified — git checkout file.js looks like switching to a branch named file.js, but actually destroys local changes.
The 2019 split
Use case | Modern syntax | Old syntax |
|---|---|---|
Switch branches | git switch main | git checkout main |
Create + switch | git switch -c feature | git checkout -b feature |
Detach HEAD at a commit | git switch --detach 1f9ab2c | git checkout 1f9ab2c |
Restore one file from HEAD | git restore file.js | git checkout -- file.js |
Restore from another commit | git restore --source=main file.js | git checkout main -- file.js |
Unstage a file | git restore --staged file.js | git reset HEAD file.js |
Side-by-side examples
Switching branches
# Old way git checkout feature-x # New way git switch feature-x
Creating and switching
# Old way git checkout -b new-feature # New way git switch -c new-feature
Restoring a file
# Old way (the scary form — easy to misuse) git checkout -- src/app.js # New way git restore src/app.js
Detached HEAD
# Old way git checkout 1f9ab2c # New way git switch --detach 1f9ab2c
Why the change?
Clarity.
git switchclearly changes the branch;git restoreclearly touches files.Safety.
git checkout -- .would silently obliterate unstaged work.git restore .does the same but is clearly only about files.Discoverability. A new user reading docs sees two clearly-named commands instead of one swiss army knife.
Future-proofing. As Git adds new behaviour, the split commands grow independently without piling more meanings onto
checkout.
When you might still use git checkout
Reading old tutorials and StackOverflow answers — they will use
checkout. Translate mentally.Working on a really old Git (pre-2.23) where
switch/restoredo not exist yet.Aliases or scripts you have already written.
Some advanced cases — like
git checkout -pfor interactive partial restore — still work the same way through either spelling.
The dangerous overlap
Look at this old form and feel the trap:
A scary command
git checkout . # Discards ALL uncommitted changes in the current directory. # Recovery is hard. There is no confirmation prompt.
Compare to:
git restore . # Does the same thing, but the verb 'restore' tells you you're touching files. # (Still destructive — but no ambiguity about what's happening.)
Do I need to relearn anything?
No. Both commands work indefinitely — Git does not deprecate old syntax lightly. If git checkout is in your muscle memory, you can keep using it for branches. But when teaching someone new, point them at git switch and git restore — it is the cleaner mental model.
git config --global alias.sw switch and git config --global alias.r restore. After a week your fingers will prefer the new shapes.