git restore & git switch — Modern Commands
2019 se Git badal gaya. Naye commands seekho, purane tutorials ko translate karo.
git checkout was Git's original "do everything" command. Switching branches? git checkout. Restoring files? git checkout. Inspecting old commits? git checkout. One command, three completely different jobs.
This was deeply confusing. git checkout main switches to the main branch, but git checkout -- app.js discards your changes to app.js. Two very different operations, same command name. The -- separator was the only way Git knew which one you meant.
In August 2019, Git 2.23 introduced two new commands to fix this:
- git switch — handles branch operations ONLY. Switch branches, create branches, toggle between branches.
- git restore — handles undo operations ONLY. Discard changes, unstage files, restore from old commits.
The old git checkout still works for backward compatibility, but the new commands are clearer, safer, and what you should learn in 2024+.
# The old way — one command, many meanings
git checkout main # switch to main branch
git checkout -b feature # create and switch to feature
git checkout -- app.js # discard changes to app.js
git checkout v1.0 # detach HEAD at tag v1.0
# Which one does what? Hard to remember!
# The new way — one command, one job
git switch main # switch to main branch
git switch -c feature # create and switch to feature
git restore app.js # discard changes to app.js
git switch --detach v1.0 # detach HEAD at tag v1.0
# Much clearer! switch = branches, restore = undogit restore is the modern undo command. It targets files in your working directory or staging area — never your commit history.
git restore <file> = discard working directory changes (same as old git checkout -- <file>). DANGEROUS — no confirmation!
git restore --staged <file> = unstage a file (same as old git reset HEAD <file>). Safe — changes stay in working dir.
git restore --staged --worktree <file> = unstage AND discard. Nuclear option.
git restore -s <commit> <file> = restore from a specific commit instead of HEAD. Time travel!
git restore -s HEAD~2 <file> = restore file as it was 2 commits ago.
The key insight: restore targets EITHER working directory OR staging area OR both. Use flags to specify which.
# Scenario: modified and staged a file, then edited more
echo "v1" > app.js && git add . && git commit -m "v1"
echo "v2" > app.js && git add app.js # staged
echo "v3" > app.js # modified again
git status -s
# MM app.js (staged v2, working v3, repo v1)
# Unstage only — keep working dir changes
git restore --staged app.js
git status -s
# M app.js (v3 in working dir, repo has v1)
# Discard working dir changes — DANGEROUS!
git restore app.js
# v3 is GONE. File reverts to v1 (from repo)
cat app.js # "v1"
# Restore from specific commit
git restore -s HEAD~2 app.js # as it was 2 commits ago
git restore -s abc1234 app.js # from specific commit hash
# Unstage AND discard (nuclear)
git restore --staged --worktree app.js
git status before running git restore.git switch is the modern branch command. It does ONE thing: move between branches. No more confusion with file operations.
git switch <branch> = switch to existing branch (same as git checkout <branch>).
git switch -c <new-branch> = create and switch to new branch (same as git checkout -b).
git switch - = switch to the PREVIOUS branch you were on. Like cd - but for branches. Super useful!
git switch --detach <commit> = detach HEAD at a specific commit (for inspecting old code).
switch will NOT switch if you have uncommitted changes that conflict with the target branch. This is safer than the old checkout — it refuses to overwrite your uncommitted work.
# Switch to existing branch
git switch main
# Switched to branch 'main'
# Create and switch to new branch
git switch -c feature/login
# Switched to a new branch 'feature/login'
# The magic dash — switch to previous branch
git switch main
git switch - # back to feature/login!
git switch - # back to main!
# Like a toggle between two branches
# Try to switch with conflicting changes
echo "change" > app.js
git switch main
# error: Your local changes to the following files would be overwritten by checkout:
# app.js
# Please commit your changes or stash them before you switch branches.
# Fix: stash, switch, pop
git stash
git switch main
git stash pop
# Inspect old code (detached HEAD)
git switch --detach v1.0.0
# HEAD is now at abc1234
# Read-only mode — don't commit here!git restore and git reset both "undo" things, but at different levels. Understanding this difference is critical.
git restore = undo changes in working dir or staging. Does NOT move commit history.
git reset = move the branch pointer (HEAD) to a different commit. Affects commit history.
git restore --staged <file> = unstage. The file stays modified in working dir.
git reset HEAD <file> = also unstages. Same result, different command.
git reset --hard HEAD~1 = move branch pointer back AND discard all changes. History rewritten.
Simple rule: if you want to undo a change to a file → restore. If you want to undo a commit → reset.
# RESTORE — undo file changes, no history impact
git restore --staged app.js # unstage the file
git restore app.js # discard working dir changes
git restore -s HEAD~1 app.js # restore file from previous commit
# Branch pointer doesn't move. History is safe.
# RESET — move branch pointer, affects history
git reset HEAD~1 # undo last commit (mixed)
git reset --soft HEAD~1 # undo commit, keep staged
git reset --hard HEAD~1 # undo commit, discard ALL
# Branch pointer MOVES BACKWARD. History changes.
# When to use which?
# "I staged the wrong file" → git restore --staged file
# "I want to undo my last commit" → git reset HEAD~1
# "I want to discard my edits" → git restore file
# "I want to go back 3 commits" → git reset HEAD~3
# RESTORE is safer — it can't move the branch pointer
# RESET is more powerful — it can rewrite historyA complete mapping of old commands to their modern equivalents. Print this. Bookmark this. Tattoo this on your keyboard.
Old: git checkout <branch> → New: git switch <branch>
Old: git checkout -b <branch> → New: git switch -c <branch>
Old: git checkout -- <file> → New: git restore <file>
Old: git reset HEAD <file> → New: git restore --staged <file>
Old: git checkout <commit> -- <file> → New: git restore -s <commit> <file>
Old commands still work but are considered "legacy." New commands are what you should use and learn. When reading Stack Overflow or old tutorials, mentally translate checkout to switch or restore.
# ┌─────────────────────────────────┬─────────────────────────────────┐
# │ Old Command (legacy) │ New Command (modern) │
# ├─────────────────────────────────┼─────────────────────────────────┤
# │ git checkout main │ git switch main │
# │ git checkout -b feature │ git switch -c feature │
# │ git checkout -- app.js │ git restore app.js │
# │ git reset HEAD app.js │ git restore --staged app.js │
# │ git checkout HEAD~1 -- app.js │ git restore -s HEAD~1 app.js │
# │ git checkout - │ git switch - │
# └─────────────────────────────────┴─────────────────────────────────┘
# Pro tip: set up aliases if your fingers are trained on old commands
git config --global alias.co switch # checkout → switch
git config --global alias.unstage "restore --staged"
# Now you can type:
git unstage app.js # same as: git restore --staged app.js
git checkout in tutorials, Stack Overflow, or even at work. The old commands still work and may never be removed. But when YOU write commands, use the new ones. They're clearer, safer, and show you're keeping up with modern Git practices.Lo kar liya — Key Points:
- ✅ Git 2.23 (August 2019) split git checkout into two clearer commands: git switch and git restore
- ✅ git switch = branch operations only. git switch -c
creates, git switch - toggles to previous - ✅ git restore = undo operations only. git restore
discards working dir changes (DANGEROUS!) - ✅ git restore --staged
unstages a file without discarding the changes — safer than restore - ✅ git restore -s
restores a file from a specific commit — time travel for individual files - ✅ restore only affects working dir/staging. reset moves the branch pointer and affects commit history
- ✅ Old checkout commands still work but modern switch/restore are clearer, safer, and recommended
Want to track your progress?
Log in to save your place and pick up where you left off.
Progress track karna chahte ho?
Login karo apni progress save karne ke liye aur jahan chhoda tha wahan se shuru karo.
Login