Skip to content
ExponaBLOG
GIT & GITHUB FOR PROFESSIONAL DEVELOPERS · DAY 018 / 100

git restore and git switch: patterns, pitfalls and fixes

Clearer commands than checkout.

Expona Admin6 min read

Introduction

If you've been using Git for a while, you've probably reached for git checkout out of habit—it works, and it's everywhere in tutorials. But modern Git offers clearer, more focused commands: git restore and git switch: patterns, pitfalls and fixes address the root problem that checkout tried to solve by doing too much at once. Learning when and how to use these newer commands will make your workflow faster, safer, and easier to explain to teammates.

Why checkout became a problem

git checkout was the Swiss Army knife of Git: switch branches, discard changes, unstage files, restore deleted files. That flexibility meant every developer learned it first, but it also meant the command's intent was ambiguous. Was git checkout file.txt supposed to switch to a branch or restore a file? Context mattered, and context is easy to misread when you're moving fast.

Git 2.23 (August 2019) introduced git restore and git switch to split checkout into two purposeful commands. They're not replacements—git checkout still works—but they're the right tool for the job, and they've become standard in modern workflows.

git restore: Discarding working changes safely

The most common use of git restore is undoing changes to files in your working directory. If you've modified a file and want to throw away those changes, git restore makes that intention explicit.

bash
git restore src/payment.ts

That command resets src/payment.ts to the version in the current HEAD commit. Your changes are gone, but it's clear what happened: you restored a file to its last committed state.

This is safer than git checkout src/payment.ts because the verb "restore" doesn't suggest branch switching. A teammate reading your command knows exactly what you did, no ambiguity.

Restoring multiple files

You can restore several files at once by listing them, or use a pattern:

bash
git restore src/*.ts
git restore .

Restore the entire working directory with git restore ., but use it with care—you'll lose all uncommitted work in one go. It's useful after a messy merge or when you want to start fresh on a branch.

Restoring from a specific commit

By default, git restore pulls from HEAD, but you can restore from any commit or branch:

bash
git restore --source=main src/config.js
git restore --source=abc1234 src/utils.ts

This is powerful when you need a file from an earlier state but don't want to check out the entire branch. In a real scenario, imagine your team broke a feature in main three commits ago, but you need the old version of a config file right now. Rather than switching branches or hunting through history, you pull just that file from the commit that had it working.

git restore --staged: Unstaging changes

The other half of what git checkout did was unstaging files. If you've run git add and then changed your mind, git restore --staged removes the file from the staging area without touching your working changes.

bash
git add src/auth.ts src/database.ts
git restore --staged src/database.ts

Now src/auth.ts is staged and ready to commit, but src/database.ts is back in your working directory as modified but unstaged. The file itself hasn't changed; you've just removed it from the staging area.

Compare this to the old git reset HEAD src/database.ts. Both work, but git restore --staged is more explicit about what you're doing: you're restoring the file to its unstaged state.

Unstaging everything

If you've staged too much and want to start over:

bash
git restore --staged .

All staged changes move back to your working directory, uncommitted. This is equivalent to git reset, but again, the verb is clearer.

git switch: Changing branches with clarity

git switch does one thing: change branches. It's what git checkout branch-name did, but without the baggage of file restoration.

bash
git switch feature/payment-retry

You're now on feature/payment-retry, and it's immediately obvious that you switched branches. There's no way to accidentally restore a file—you can't pass a file path to git switch.

Creating and switching in one step

Like git checkout -b, you can create a new branch and switch to it:

bash
git switch -c feature/refund-flow

This is slightly more readable than git checkout -b because the verb "switch" immediately tells you what's happening. You're creating a branch and switching to it, not checking something out.

Switching based on a remote branch

A handy shortcut: if you try to switch to a branch that doesn't exist locally but matches a remote branch, Git creates a local tracking branch automatically:

bash
git switch feature/rate-limiting

If origin/feature/rate-limiting exists but you don't have it locally, Git sets up a local branch tracking that remote. This saves you from typing git switch -c feature/rate-limiting --track origin/feature/rate-limiting.

Detached HEAD state

Switching to a commit (rather than a branch) puts you in a detached HEAD state:

bash
git switch --detach abc1234

You can now inspect that commit or test it without being on a branch. When you're done, git switch - takes you back to your previous branch. This is useful for quick investigations without cluttering your branch list.

Common mistakes

Confusing restore and switch

A common slip: trying to use git restore to switch branches, or git switch to discard changes. The commands are strict about their purpose, which is actually a safety feature. If you run git restore main, Git won't switch you to main—it'll try to restore a file named "main" from the index.

Forgetting --staged when you mean to unstage

git restore src/file.ts discards changes in your working directory. git restore --staged src/file.ts removes the file from the index. It's easy to forget the flag and lose work. If you're unsure, git status will tell you exactly what you need to do.

Using git restore . without thinking

git restore . nukes all your working changes. It's fast and sometimes necessary, but it's unforgiving. Make sure you've stashed anything important first, or use git diff to review what you're about to lose.

Mixing old and new commands on a team

If your team has folks on older versions of Git (pre-2.23), they won't have git restore and git switch. Document what you're using in your onboarding and contributing guides, or stick with git checkout and git reset if compatibility is critical. Most modern teams have moved on, but it's worth checking.

When checkout is still the right call

You don't have to abandon git checkout entirely. It's still useful in a few scenarios where its dual purpose shines:

  • Quick one-liners: If you're switching branches and restoring a file in one command for some reason, git checkout can do it in ways restore and switch can't.
  • Legacy codebases: Older team projects might have scripts that rely on git checkout.
  • Shell history: If you've been using it for years, the muscle memory is there. Consistency within a team matters more than adopting the newest command.

But for new code, new teams, and new documentation, git restore and git switch are the clearer choice.

Key takeaways

  • git restore <file> discards working changes; git restore --staged <file> unstages without changing the file itself.
  • git switch <branch> changes branches; git switch -c <branch> creates and switches in one step.
  • git checkout still works but conflates branch switching and file restoration, making intent unclear.
  • Use git restore --source=<commit> to pull a file from a specific point in history without switching branches.
  • Use git switch --detach <commit> to inspect a commit without being on a branch.
  • The new commands are strict by design—they prevent accidental branch switches or file overwrites.
  • Review git status and git diff before running git restore . to avoid losing work.
  • Adopt git restore and git switch in documentation, scripts, and team guidelines for consistency and clarity.
ShareXLinkedInReddit

Found this useful? Support the writing.

Buy me a coffee
Written by
Expona Admin
Site administrator

Comments

Loading comments…

Leave a comment

Comments are reviewed before they appear. Be kind and stay on topic.

Related articles