git checkout is one command doing four different jobs, and mixing them up is how people lose an afternoon's work. You will use it to move between branches, create a topic branch, inspect an old commit, and restore one file without touching the rest of your working tree. These examples match Git 2.43.0, the version documented by the installed git-checkout(1) manual.
Allow about 10 minutes if you already have a repository and know which branch or commit you need. You need Git and a local repository. None of these commands needs sudo or any elevated privilege.
Run these commands from the repository containing the work you want to change:
git --version
git status --short --branch
git branch --show-current
The installed version should report git version 2.43.0 on the system used for this guide. The status output shows the current branch and any modified or untracked paths. A clean working tree is the easiest starting point, but local changes are normally kept when you switch branches if they do not conflict with the target branch.
Checkpoint: Identify the branch you are on and decide whether each listed local change must be kept. Do not use -f to make an uncertain situation disappear.
Replace the placeholder with a branch that exists locally:
git checkout <existing-branch>
For example, git checkout main updates the index and working tree and makes main the current branch. Confirm the result with:
git status --short --branch
git branch --show-current
With Git's default guessing behaviour, a name that is absent locally can be taken from a matching remote-tracking branch when exactly one remote is suitable. If several remotes contain the same name, use an explicit remote branch and create the local branch yourself rather than guessing:
git checkout -b <local-branch> --track <remote>/<remote-branch>
For instance, git checkout -b feature/report --track origin/feature/report creates and checks out feature/report, with upstream tracking configured. The --no-guess option disables the implicit remote lookup for a one-off command.
Create a new branch from the current commit, or provide an explicit starting point:
git checkout -b <new-branch> [start-point]
git branch --show-current
git log -1 --oneline
Square brackets here mean that the argument is optional; do not type them. The default starting point is HEAD. A named commit, tag, or existing branch can be used as the starting point, for example:
git checkout -b feature/report origin/main
This changes branch state, but it does not create a commit. Make your edits, review them with git diff, and commit when they are ready. If the branch name already exists and you only want to switch to it, use the form in step 2.
Git refuses a switch when doing so would overwrite local modifications. That refusal protects your work:
error: Your local changes to the following files would be overwritten by checkout
Choose one of these recovery paths. Commit the work if it belongs on the current branch, or save it temporarily with git stash push if you need to change branches before deciding:
git add <file>
git commit -m "WIP: save local changes"
git checkout <target-branch>
# Or, for work that is not ready to commit:
git stash push -u -m "before switching to <target-branch>"
git checkout <target-branch>
git stash list
git stash pop
Resolve any conflicts reported by git stash pop, then inspect the result with git status and git diff. The -u includes untracked files, so use it only when those files belong in the temporary save.
To replace a working-tree file with the version currently in the index, use -- to mark the end of options and paths:
git checkout -- <path/to/file>
This discards unstaged edits to that path. It does not restore edits that are already staged. The operation is destructive for those unstaged bytes, so inspect the diff first:
git diff -- <path/to/file>
git checkout -- <path/to/file>
git diff --exit-code -- <path/to/file>
The final command should produce no output and return success when the file now matches the index. If you need a file from a particular commit, name the tree before the separator:
git checkout <commit-or-branch> -- <path/to/file>
git diff --cached -- <path/to/file>
This updates both the index and working tree from that tree. Use git restore for new scripts where its separate staged and working-tree modes are clearer, but the checkout form remains supported and is useful in older instructions.
Checking out a commit, tag, or other commit name that is not a branch detaches HEAD:
git checkout <commit-or-tag>
git status --short --branch
git log -1 --oneline
This is suitable for reading code or running a discardable experiment. If you create commits while detached, no named branch advances to retain them. Before leaving, either create a branch at the work:
git checkout -b <keep-experiment>
or return to your previous branch and abandon the detached commits deliberately:
git checkout -
The hyphen means the last branch or commit checked out. If you lose track of a detached commit, git reflog -2 HEAD shows recent HEAD positions so you can find its identifier.
If local edits overlap differences between your current branch and the target, git checkout <target-branch> stops to preserve them. The -m option asks Git to attempt a three-way merge:
git checkout -m <target-branch>
git status
git diff
Use this only when you understand the merge. A conflict leaves unmerged paths. Edit each conflicted file, remove the conflict markers, and mark the resolved result:
git add <resolved-file>
git status
Do not use -f as a general fix. Forced checkout can throw away local modifications and untracked files or directories that obstruct the target. If you used it by mistake, stop making further changes and inspect git reflog, your editor backups, and any stash or commit that contains the work. Git cannot guarantee recovery of discarded uncommitted bytes.
git branch --show-current reports the branch you intended, or status clearly shows a deliberate detached HEAD.git status --short shows only changes you recognise.git diff or git diff --cached.