Starting a topic branch
Create a branch from main or a remote branch with 'git checkout -b feat origin/main' and start working on it right away.
Git · Command
git checkout either moves you to another branch or commit, or overwrites chosen files with the version stored in the index or in a given commit. It is the older all-in-one command whose two jobs are now also covered separately by git switch and git restore.
Last updated
Git looks at the arguments to decide which job to do. Given a branch name and no paths, it points HEAD at that branch and updates the index and working tree to match. Uncommitted edits come along unless the switch would overwrite them. Given a commit that is not a branch, HEAD points straight at that commit, which is called a detached HEAD. Given pathspecs, HEAD stays where it is. Git copies those files from the index, or from a tree-ish if you name one. With a tree-ish, the restored files are also staged. If an argument could be either a ref or a file, Git treats it as a ref unless you put -- in front of the paths.
git checkout [-q] [-f] [-m] [[-b|-B|--orphan] <new-branch>] [<start-point>]
git checkout [-q] [-f] [-m] [--detach] <commit>
git checkout <tree-ish> [--] <pathspec>...
git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [--] <pathspec>...
git checkout (-p|--patch) [<tree-ish>] [--] [<pathspec>...]| Name | Type | Description |
|---|---|---|
<branch> | ref | The branch to switch to. If the name is not a local branch but is a valid commit, HEAD becomes detached. @{-N} and - (the previous checkout) are accepted. |
<new-branch> | string | Name of the branch created by -b, -B or --orphan. |
<start-point> | commit | The commit a new branch starts from. Defaults to HEAD. A...B means their merge base. |
<tree-ish> | commit/tree | Where file contents are taken from when paths are given. If omitted, the index is used. |
<pathspec>... | pathspec | Limits the operation to these files or directories. |
-b / -B | flag | Create a branch and switch to it. -B resets the branch if it already exists. |
--detach | flag | Check out a commit with HEAD detached, even when you give a branch name. |
-f / --force | flag | Throw away local changes when switching. When restoring paths, skip unmerged entries instead of failing. |
-m / --merge | flag | Carry conflicting local changes across the switch by stashing and reapplying them. When restoring paths, recreate the conflicted merge result. |
--ours / --theirs | flag | For unmerged paths, take stage #2 (ours) or stage #3 (theirs) from the index. |
-p / --patch | flag | Choose hunks interactively and revert them in the working tree. |
--orphan | flag | Create an unborn branch whose first commit will have no parent. |
#!/usr/bin/env bash
set -e
# Create a feature branch from main and switch to it
git checkout -b feature/login main
# Throw away unstaged edits to one file (restore it from the index)
git checkout -- src/app.js
# Take a file from two commits back on main (it is staged too)
git checkout main~2 -- Makefile
# Look at an old release without moving any branch
git checkout --detach v2.0
# Keep experimental work made there by putting it on a new branch
git checkout -b spike/v2-fix
# Go back to the branch you were on before
git checkout feature/loginThe script runs through the common checkout jobs: creating a branch, restoring files from the index or from a commit, detaching HEAD, saving work made while detached, and switching back with a branch name.
Create a branch from main or a remote branch with 'git checkout -b feat origin/main' and start working on it right away.
Restore a file from the index, or pull the version from an earlier commit after a broken change.
Check out a tag with HEAD detached to reproduce a bug, then make a branch only if you need to keep fixes.
Use --ours or --theirs on conflicted paths to keep one side in full, or -m to bring the conflict markers back.
Normally HEAD points to a branch name. With a detached HEAD it points straight at a commit. This happens when you check out a tag, a commit hash or an expression like master^^, or when you use --detach. New commits made in this state are referenced only by HEAD.
Follow-up: You already switched away and the detached commits seem gone. How do you get them back? Find their IDs with git reflog (or git log -g), then create a branch or tag on them before garbage collection removes them.
Without a tree-ish, the file is copied from the index into the working tree, so only unstaged edits are thrown away. With HEAD (or any commit), the file is replaced with the committed version in both the index and the working tree, which also drops staged changes.
Follow-up: How do you get the same result with the newer commands? 'git restore file.txt' restores from the index, and 'git restore --source=HEAD --staged --worktree file.txt' matches the HEAD form.
Use 'git checkout -m <branch>' to stash the conflicting edits, switch, and reapply them. Use -f to switch and throw the edits away. You can also commit or stash the edits yourself first.
Follow-up: What happens if reapplying with -m causes conflicts? The stash entry is kept. Resolve the conflicts and run git stash drop, or run git reset --hard and apply the changes later with git stash pop.
git switchgit restoregit branchgit refloggit stashgit worktreegit resetgit add