TThe git checkout command is one of the most powerful and commonly
used commands in Git. It allows you to switch branches, move
between commits, and discard unwanted file changes.
Despite being widely used, git checkout is also one of the most
confusing Git commands — especially when users encounter terms like
HEAD, detached HEAD, or accidentally lose changes.
In this guide, you will learn:
- What
git checkoutactually does internally - How to switch branches and commits safely
- How to restore files using
git checkout - What detached HEAD means (and how to avoid data loss)
- When to use
git checkoutvsgit switchvsgit restore
By the end of this tutorial, you’ll know exactly when and how to use git checkout with confidence.
How git checkout works
git checkout moves HEAD to a new target and then updates the
index (staging) and working directory to match that target.
Before:
HEAD -> main -> (latest commit on main)
You run:
git checkout feature-branch
Git does (in order):
1) Move HEAD to the target
2) Update Index (Staging Area) to match the target snapshot
3) Update Working Directory files to match the Index
After:
HEAD -> feature-branch -> (latest commit on feature-branch)
What changes when you switch branches?
Repository History (commits) : does not change
HEAD pointer : changes (main -> feature-branch)
Staging Area (Index) : replaced to match the branch snapshot
Working Directory (files) : updated to match that snapshot
Why files suddenly change after checkout?
Because Git replaces your working folder to match the files from the
selected branch/commit. That’s why you may see many files updated
instantly after switching from main to feature-branch.
Quick Use-Cases
Here are some of the common git checkout use cases:
| Use Case | Command |
|---|---|
| Switch to another branch | git checkout branch-name |
| Create and switch to a new branch | git checkout -b new-branch |
| View project at a specific commit | git checkout commit-hash |
| Discard local changes in a file | git checkout -- file |
| Recover lost commits | git checkout commit-hash |
| Check out a remote branch | git checkout -b local origin/remote |
git checkout Command Syntax
git checkout <branch-name> # Switch to an existing branch
git checkout <commit-hash> # Move HEAD to a specific commit (detached HEAD)
git checkout -- <file> # Restore file to last committed version
git checkout -b <new-branch> # Create and switch to a new branch
Switching Branches Using git checkout
To switch from your current branch to another existing branch:
git checkout feature-branch # Switch from current branch to feature-branch
What happens internally:
HEADmoves to the target branch- Working directory files are updated
- Commit history remains unchanged
Check your current branch:
git branch # Shows all branches (* marks current)
Creating and Switching to a New Branch
One of the most frequent uses of git checkout is creating a new branch
and switching to it immediately.
git checkout -b new-feature # Create new-feature branch and switch to it
This command creates a new branch and switches to it in a single step. It is commonly used when starting new development work or testing changes which is equivalent to:
git branch new-feature
git checkout new-feature
Use this when starting new development or experiments.
Checking Out a Specific Commit
You can use git checkout to view the repository at a specific commit:
git checkout a1b2c3d4
When you do this, Git updates the working directory to match the selected commit. However, you are no longer on a branch.
This results in a detached HEAD state.
What Is Detached HEAD in Git?
A detached HEAD state occurs when HEAD points directly to a commit
instead of a branch.
In this state:
- You are not on any branch
- New commits are not associated with branch history
- Switching branches can make commits unreachable
Git displays a warning when this happens to prevent accidental data loss.
When Detached HEAD Is Useful
- Inspecting older versions of the code
- Debugging regressions
- Testing changes without affecting branches
How to Keep Changes Made in Detached HEAD
If you want to preserve work done in detached HEAD, create a new branch:
git switch -c temp-branch
This safely attaches your work to a branch.
Restoring Files Using git checkout
git checkout can be used to discard local changes and restore files to
their last committed state.
git checkout -- index.html
This restores the file exactly as it exists in the latest commit.
This operation permanently removes uncommitted changes in the file. Use it only when you are sure the changes are no longer needed.
Recovering a Lost Commit Using git checkout and reflog
If a commit is removed due to a hard reset, it can often be recovered
using git reflog.
View recent HEAD movements:
git reflog
Check out the lost commit:
git checkout <commit-hash>
Create a branch to preserve it:
git switch -c recovered-branch
You can then merge or rebase it back into your main branch
Checking Out a Remote Branch
To work on a remote branch, first fetch updates:
git fetch
List all branches:
git branch -a
Create a local branch that tracks the remote branch:
git checkout -b feature-branch origin/feature-branch
Git automatically links the local branch to the remote branch.
git checkout Syntax and Common Usage Patterns
Git introduced git switch and git restore to simplify workflows that
were previously handled by git checkout.
| Command | Purpose |
|---|---|
git checkout |
Multi-purpose command |
git switch |
Switch branches only |
git restore |
Restore files only |
Modern Alternatives
git switch feature-branch
git restore index.html
git checkout is not deprecated, but newer commands reduce ambiguity
and are recommended for new users.
Conclusion
The git checkout command is a powerful and flexible Git tool used to
switch branches, explore commits, and restore files.
While newer commands simplify certain workflows, git checkout remains
an essential part of Git, especially when working with legacy
repositories or troubleshooting issues.
Once you understand how HEAD, branches, and commits interact,
git checkout becomes a safe and reliable command in your Git workflow.


