What Is Git Checkout? Switch Branches Like a Pro

Summarize this article with:
Every branch switch, every file restoration, every time you jump back to inspect an older commit, there’s one command doing the work. So what is git checkout, and why does it still matter when newer alternatives exist?
Git checkout is one of the most used commands in any developer’s daily workflow. It handles branch switching, file recovery, and navigating commit history. But it also confuses people because it does too many things at once.
This article breaks down how git checkout works, its syntax and flags, the detached HEAD state, how it compares to git switch and git restore, and the common mistakes that trip up both beginners and experienced developers. You’ll also learn how checkout behaves inside popular IDEs and GUI tools.
What is Git Checkout

Git checkout is a command in Git that switches between branches and restores files in the working directory. It tells Git where you want to be.
When you run git checkout, Git moves the HEAD pointer to a different branch or commit. Then it updates every tracked file in your working directory to match that target.
The command has two distinct jobs. It handles branch switching (moving between different lines of development) and file restoration (reverting specific files to a previous state). This dual nature is actually what makes it tricky for a lot of people, and it’s why the Git team eventually split its responsibilities into separate commands.
Git adoption has grown from 87.1% in 2016 to 93.87% in 2025, according to Command Linux data. Stack Overflow’s developer survey confirms that no other tool is as widely used among professional developers.
Inside a typical Git workflow, checkout operates entirely on your local repository. It doesn’t touch the remote. It doesn’t push or pull anything. It just repositions where you’re working locally, which makes it fast and safe for everyday branch management.
Think of it this way. You have a project with multiple branches. Each branch represents a different feature, bug fix, or experiment. Git checkout is how you jump between them. Your mileage may vary on how often you use it, but if you’re writing code professionally, you’re probably running it dozens of times a day.
How Git Checkout Works

The HEAD pointer is the core of how checkout operates. HEAD is just a reference that tracks your current position in the commit history. When you run git checkout main, Git moves HEAD to point at the main branch’s latest commit.
Then Git does something practical. It rewrites the files in your working directory to match the snapshot stored in that commit. Your staging area (the index) also gets updated to reflect the new branch state.
What happens to uncommitted changes during this process? It depends. If your uncommitted work doesn’t conflict with files on the target branch, Git carries those changes over silently. But if there’s a conflict, Git blocks the checkout entirely and tells you to either commit, stash, or discard your changes first.
Hutte research shows that nearly 90% of developers have faced merge conflicts at some point. Knowing how checkout interacts with uncommitted changes prevents a lot of those headaches.
There’s a real difference between checking out a branch and checking out a specific commit. A branch checkout keeps HEAD attached. A direct commit checkout puts you in a detached HEAD state, which is where things get interesting.
Detached HEAD State
Detached HEAD means your HEAD pointer references a specific commit hash rather than a branch name. You’re looking at a snapshot in time, but you’re not “on” any branch.
This happens when you run something like git checkout a1b2c3d or check out a tag directly. Git warns you about it explicitly.
You can still make commits in this state. But those commits won’t belong to any branch. If you switch away without saving them to a new branch, Git’s garbage collector will eventually clean them up (usually after 30 days, according to the Git documentation).
Getting back is straightforward. Run git checkout main (or whatever branch you came from). If you made commits you want to keep, create a branch first with git checkout -b my-new-branch before switching away. Most people land in detached HEAD by accident. It’s not an error, just an unusual state that requires awareness.
Git Checkout vs Git Switch and Git Restore

In August 2019, Git version 2.23 introduced two new commands: git switch and git restore. The goal was to split checkout’s dual personality into focused, single-purpose tools.
| Command | Purpose | Replaces |
|---|---|---|
git switch | Branch switching only | git checkout |
git restore | File restoration only | git checkout -- |
git checkout | Both (still works) | N/A |
So is git checkout deprecated? No. The Git project still supports it fully. The newer commands just offer clearer intent for each task.
The confusion with checkout was real. Running git checkout <branch> switches branches. Running git checkout -- <file> discards local changes to a file. Same command, completely different behavior based on context. Took me a while to stop mixing those up when I was learning Git years ago.
Git switch uses -c instead of -b for creating branches (short for –create), which is more readable. And git switch refuses to put you in a detached HEAD state unless you explicitly pass the --detach flag. That safety net alone prevents accidental detaches.
If you want to learn more about how to switch branches in Git using both approaches, it’s worth understanding the differences in practice. For teams working with Git 2.23 or later, adopting git switch for daily source control management is a good habit.
Common Git Checkout Use Cases

Switching to an existing branch:
The most basic use. Run git checkout feature-login and Git moves your working directory to that branch. Hutte data shows that 85% of collaborative projects use pull or merge requests in their workflow, which means constant branch switching is the norm.
Creating and switching to a new branch:
The -b flag does both in one step: git checkout -b feature-signup. This is probably the second most common usage pattern. If you need a refresher, here’s how to create a new branch in Git.
Restoring a single file from another branch:
You can pull one file from a different branch without switching: git checkout main -- src/config.js. The double dash separates the branch name from the file path. Super useful when you need a specific version of one file but don’t want to leave your current branch.
Checking out a remote branch locally:
When a teammate pushes a branch you don’t have locally, you fetch first, then checkout. Git automatically sets up tracking if the branch name matches a single remote branch. Understanding what git fetch does before this step matters.
Checking out a tagged release:
Running git checkout v2.0.0 lets you inspect the code at that exact release point. Just remember: this puts you in detached HEAD. Create a branch from the tag if you need to make changes.
Git Checkout Syntax and Flags
The base syntax looks like this:
git checkout [options] [branch|commit] [-- files]
That -- separator is more useful than people realize. It tells Git that everything after it is a file path, not a branch name. Without it, Git might confuse a file named “main” with the branch named “main.” I’ve seen this cause real confusion on projects where someone named a file the same as a branch.
| Flag | What It Does | Example |
|---|---|---|
-b | Create and switch to a new branch | git checkout -b feature-x |
-B | Force-create and switch (resets if branch exists) | git checkout -B feature-x |
-f | Force checkout, discards uncommitted changes | git checkout -f main |
--track | Set up remote tracking for the branch | git checkout --track origin/dev |
-- | Disambiguate file paths from branch names | git checkout -- file.txt |
The -f flag is the dangerous one. It throws away local changes without asking. Use it when you genuinely want a clean slate, not as a default habit.
The -B flag (uppercase) is less common but useful in scripting. If the branch already exists, it resets it to the current HEAD position before switching. In continuous integration pipelines, this avoids errors from stale branch references. GitHub’s Octoverse 2025 report shows that developers pushed nearly 1 billion commits in 2025 alone, a 25% year-over-year increase. That volume of activity means automated checkout operations in build pipelines need to be bulletproof.
For a broader look at commonly used Git commands and their flags, it helps to have a reference handy.
How to Checkout a Remote Branch

Checking out a remote branch is one of those things that trips up newer developers. The branch exists on the remote repository, but Git won’t let you work on it directly until you create a local copy.
Step one: fetch. Always run git fetch (or git fetch origin) before attempting to checkout a remote branch. This downloads the latest remote references without merging anything into your local work. About 70% of developers run git fetch daily to keep local repos in sync, according to Hutte research.
Step two: checkout with automatic tracking.
If you run git checkout feature-payments and that branch name matches exactly one remote branch, Git creates a local tracking branch automatically. It sets up the upstream connection so future git pull and git push commands work without extra configuration.
When automatic tracking fails:
If multiple remotes have branches with the same name, Git can’t guess which one you want. Specify it explicitly:
git checkout --track origin/feature-payments
The most common error here is forgetting to fetch first. You’ll see something like error: pathspec 'feature-payments' did not match any file(s) known to git. That just means Git doesn’t know about the remote branch yet. Fetch, then try again.
As of 2025, GitHub hosts over 180 million developers across more than 630 million repositories, according to the Octoverse report. With that many people collaborating across distributed teams, remote branch checkout is one of the most frequent operations in any software development process.
What Happens to Uncommitted Changes During Checkout

This is where a lot of people get burned. You’re working on something, you haven’t committed yet, and you try to switch branches. What happens next depends entirely on whether your uncommitted changes conflict with the target branch.
When Git carries changes silently: If the files you’ve modified don’t differ between your current branch and the target branch, Git just brings your uncommitted work along. No warning, no message. Your changes show up on the new branch as if you’d made them there. This is actually convenient, but it catches people off guard the first time they notice it.
When Git blocks the checkout: If switching would overwrite your local modifications (because the same files differ between branches), Git refuses to proceed. You’ll see an error like error: Your local changes to the following files would be overwritten by checkout.
Hutte research shows 28% of developers have lost work when using git stash incorrectly. That’s not a small number.
You have three options when Git blocks the switch:
- Commit your changes first (the safest approach)
- Run
git stashto temporarily shelve them, switch branches, thengit stash popto restore - Use
git checkout -fto force the switch and discard everything (dangerous, obviously)
The stash command is probably the most practical choice for quick context switches. It saves your uncommitted work to a temporary storage area and gives you a clean working directory. But stash has quirks. If you stash frequently without popping, you end up with a pile of unnamed stashes that become impossible to tell apart.
Spotify’s engineering team, for reference, operates with thousands of microservice repositories. At that scale, developers switch branches constantly, and having a clean codebase before checkout becomes a non-negotiable habit.
Git Checkout in IDEs and GUI Tools
Not everyone lives in the terminal. And honestly? For branch switching, a GUI is often faster than typing commands.
The Stack Overflow Developer Survey shows that Visual Studio Code holds 75.9% usage among developers as of 2025, making it the dominant coding environment by a wide margin. Its built-in Git integration exposes checkout through the branch picker in the bottom-left status bar. Click it, pick a branch, done.
| Tool | How Checkout Works | Best For |
|---|---|---|
| VS Code | Branch picker in status bar, command palette | Everyday branch switching |
| JetBrains IDEs | Branch popup via Git menu or bottom toolbar | Complex projects with multiple remotes |
| GitHub Desktop | Branch dropdown at the top of the window | Beginners, visual learners |
| GitKraken | Double-click any branch in the commit graph | Visualizing branch history |
| Sourcetree | Right-click branch name, select “Checkout” | Atlassian/Bitbucket users |
The underlying command is the same regardless of interface. When you click “Switch Branch” in VS Code, it runs git checkout (or git switch in newer versions) behind the scenes.
JetBrains IDEs like IntelliJ IDEA and PyCharm handle checkout with some extra intelligence. They’ll prompt you to stash or shelve changes before switching, which prevents the “blocked checkout” scenario entirely. IntelliJ IDEA jumped from 71% to 84% usage among Java developers between 2024 and 2025, according to Second Talent’s analysis of Stack Overflow data.
GitHub Desktop is worth mentioning for teams onboarding junior developers. It strips away command-line complexity and makes version control feel approachable. You can learn how to use GitHub through its interface without memorizing a single terminal command.
Hutte data shows that 92% of projects using Git enforce code review before merging changes. Most of those reviews happen inside IDE integrations or platform interfaces, not the raw command line. The code review process usually involves checking out a colleague’s branch to test changes locally, which makes GUI checkout tools part of the daily routine.
Common Mistakes with Git Checkout

Mistakes happen. Even experienced developers mess up checkout operations regularly. Hutte research found that 70% of developers have used a Git command without fully understanding what it does. That number alone explains a lot of the checkout-related headaches.
Accidentally Entering Detached HEAD
This is the classic one. You mean to switch to a branch but accidentally check out a commit hash, a tag, or a remote reference directly.
The fix is simple. Run git checkout -b temp-branch if you’ve made commits you want to keep, or just git checkout main to go back.
About 65% of developers have recovered lost commits using git reflog, according to Hutte. That command is the safety net when detached HEAD goes wrong.
Overwriting Local Changes with Force Checkout
The -f flag doesn’t ask twice. Run git checkout -f main and everything uncommitted in your working directory disappears. No recovery. No undo.
Hutte data indicates that 58% of developers have accidentally deleted a branch or commits at some point. Force operations account for a big chunk of those losses.
The safer alternatives: commit first, or stash. If you need to discard changes intentionally, git clean gives you more control over what gets removed.
Confusing Checkout with Reset or Revert
| Command | What It Does | Danger Level |
|---|---|---|
git checkout | Switches branches or restores files | Low (unless -f flag used) |
git reset | Moves HEAD and optionally changes staging/working directory | Medium to High |
git revert | Creates a new commit that undoes a previous commit | Low (non-destructive) |
People mix these up all the time. Checkout moves you somewhere. Reset rewrites history. Revert creates a counter-commit. Three completely different operations.
The confusion gets worse because git checkout -- file.txt restores a file (destructive to local changes), which feels a lot like what reverting a commit in Git does, but at a completely different scope. Understanding git diff helps here because it lets you preview exactly what will change before you run any of these commands.
Forgetting to Fetch Before Remote Checkout
You try git checkout feature-payments and Git says it doesn’t exist. Panic.
There’s no panic needed. The branch exists on the remote, your local Git just doesn’t know about it yet. Run git fetch origin first, then retry the checkout. This is such a common issue that resolving merge conflicts guides almost always start with “did you fetch first?”
Over 90% of Fortune 100 companies use GitHub for their development needs, according to GitHub’s official data. With teams spread across time zones, remote branches get created constantly. Building the habit of fetching before checkout saves time and confusion, especially when following a structured Git Flow branching model.
Path Ambiguity Between Branch Names and File Names
Imagine you have a branch named config and a file named config in your repository. Running git checkout config becomes ambiguous. Does Git switch to the branch or restore the file?
Git defaults to the branch interpretation. But relying on that default is risky.
The fix: Use the -- separator. git checkout -- config targets the file. git checkout config -- targets the branch. This tiny detail prevents real problems on projects with large file trees and many branches.
FAQ on What Is Git Checkout
What does git checkout do?
Git checkout switches between branches and restores files in your working directory. It moves the HEAD pointer to a different branch or commit, then updates all tracked files to match that target’s snapshot.
Is git checkout the same as git switch?
No. Git switch only handles branch switching, while git checkout also restores files. Git 2.23 introduced git switch and git rebase alternatives to split checkout’s dual responsibilities into focused commands.
Is git checkout deprecated?
Git checkout is not deprecated. It remains fully supported and functional. The Git project simply recommends git switch and git restore as clearer alternatives for their specific tasks.
How do I checkout a remote branch?
Run git fetch origin first, then git checkout branch-name. If the branch name matches one remote branch, Git automatically creates a local tracking copy. You can also use the --track flag explicitly.
What is a detached HEAD in git checkout?
Detached HEAD happens when you checkout a specific commit hash instead of a branch name. HEAD points directly at that commit rather than a branch reference. Any new commits made in this state won’t belong to a branch.
How do I create a new branch with git checkout?
Use git checkout -b branch-name. The -b flag creates the branch and switches to it in one step. This is one of the most common Git operations in any trunk-based development or feature branch workflow.
What happens to uncommitted changes when I run git checkout?
If your changes don’t conflict with the target branch, Git carries them over silently. If they conflict, Git blocks the checkout. Use git stash or commit your work before switching.
What is the difference between git checkout and git reset?
Git checkout moves you to a different branch or commit. Git reset moves the branch pointer itself, optionally changing the staging area and working directory. Reset rewrites history. Checkout just changes your position.
Can I checkout a single file from another branch?
Yes. Run git checkout branch-name -- path/to/file. The double dash separates the branch name from the file path. This pulls that specific file version into your current branch without switching.
How do I undo a git checkout?
If you switched branches, just checkout the previous branch again. If you restored a file and lost local changes, use git log or git reflog to find the previous state and recover it.
Conclusion
Git checkout remains a core part of how developers manage branches, restore files, and move through commit history. Whether you’re working in a terminal, inside VS Code, or through GitHub Desktop, the mechanics behind this command stay the same.
Understanding its behavior around the HEAD pointer, the staging area, and uncommitted changes saves real time. Knowing when to use the -b flag, the –` separator, or when to reach for git remote and fetch before checking out a branch prevents the most common errors.
Git 2.23 gave us git switch and git restore as focused alternatives. But checkout isn’t going anywhere.
Build the habit of committing or stashing before switching. Use git status to check your working directory first. Small habits, fewer surprises.







