One of the very first commands developers learn when starting out with Git is git checkout. However, git checkout is a notoriously overloaded command. It handles too many responsibilities, making it a common source of confusion and accidental file loss for beginners and experienced developers alike.
To solve this, Git version 2.23 (released in 2019) introduced two dedicated, task-focused alternatives: git switch and git restore.
In this post, we’ll discuss the design problems surrounding git checkout, explain the roles of the newer commands, and show you how to transition to using them today.
1. The Problem: The Overloaded Nature of git checkout
The primary issue with git checkout is that it combines two entirely different operations into a single command: managing branches and restoring files.
Switching Branches:
# Switches your workspace to feature-branch
git checkout feature-branch
Discarding Uncommitted File Changes:
# Wipes local changes to main.js, reverting it to the last commit
git checkout -- main.js
This dual-nature introduces risk. For instance, if you type git checkout feature hoping to revert a local file named feature, but you also happen to have a branch named feature, Git will switch your active branch instead of resetting the file.
2. The Solution: Function-Specific Commands
To resolve the ambiguity, Git split the functionalities into two standalone utilities.
3. Branch Swapping with git switch
git switch focuses exclusively on branch navigation. It does not touch your uncommitted file contents unless requested.
Common Commands:
# Switch to an existing branch
git switch feature-branch
# Create a new branch and switch to it (replaces checkout -b)
git switch -c new-feature-branch
# Switch back to the previous branch (replaces checkout -)
git switch -
4. Reverting File Changes with git restore
git restore is designed to reset files in your working directory or staging area to a previous commit’s state.
Common Commands:
# Discard local unstaged changes to a file (replaces checkout --)
git restore src/main.js
# Unstage a file you added via git add (replaces git reset HEAD)
git restore --staged src/main.js
# Unstage and discard changes to a file at the same time
git restore --source=HEAD --staged --worktree src/main.js
5. Why You Should Make the Move
- Improved Safety: Separating file modification operations from branch pointer movements helps prevent accidental loss of local work.
- Better Developer Ergonomics:
The names
switchandrestoreexplicitly describe what they do. This reduces cognitive overhead and makes training team members on Git easier.
Although Git continues to support git checkout for backwards compatibility, major documentation projects and GUI tools have transitioned to the new syntax.
Conclusion
For a safer and more intuitive Git workflow, phase out git checkout in favor of the specialized alternatives:
- Use
git switchfor branch pointer updates. - Use
git restorefor workspace file reversions.
Adopting these commands makes your interactions with Git much more predictable.
