Table of Contents
Git checkout switches between branches and undoes changes.
However, failure to deeply understand the command could prevent you from applying it correctly. Worse yet, you may not distinguish the checkout command from other git commands such as clone, restore, remove, reset, and revert.
This tutorial simplifies deploying the checkout command. It explains the challenging parts of git checkout using relatable words and examples. Read on to learn more.
Git checkout command cheat sheet
Git checkout affects files, commits, and branches.
On files, git checkout undoes changes.
git checkout HEAD~N <file>
Alternatively, you can overwrite contents in the working tree to match the specified file in the index.
git checkout -f <pathspec>
-f with the
git checkout -p <pathspec>
shows the diff through an interactive interface.
On commits, the command detaches the HEAD.
git checkout <SHA1>
Lastly, git checkout plays a massive role in branching. You can switch between existing branches,
git checkout <existing branch>
create a branch and move into it,
git checkout -b <new branch>
or navigate to a remote branch.
git checkout <remote branch>
Let us dive into git HEAD and branching.
A simple explanation of git HEAD and branch
You should understand how git stores snapshots of your changes before applying the checkout command.
Initializing a repository creates a
.git subdirectory in the filesystem. In git, a filesystem is a directory whose files and subdirectories you are modifying. A repository, on the other hand, is a collection of commits.
In technical terms, git is a version control system API for tracking objects and a naming system for the objects: refs.
Objects are blobs, trees, and commits. Commits reference trees, which in turn, reference blobs. Blobs contain file contents. Refs can be heads (branches) or tags.
A branch is a named reference to a commit. The last commit, also known as the repository tip or HEAD, gets tracked in the HEAD file. Switching between branches modifies the contents of the HEAD file.
Say the HEAD file's
content is ref: refs/heads/main. That means the tip of the latest commit lies in the main branch.
Assume you then create the
second branch and switch to it. The contents of the HEAD file
then become ref: refs/heads/second.
Where git checkout comes in a typical git workflow
Think of checkout as a compound word of check + out, which means "explore the contents of something."
Say you have committed to multiple branches and want to update the refs. Or you want to retreat your steps to a particular snapshot. Git checkout command comes in to help, depending on the supplied pathspec or option.
For example, during branching, the command automatically updates the HEAD file to notify git you are working on another branch.
Apart from the checkout command, you can use commands such as git rm, git restore, git reset, git revert, and git switch. Here is how to distinguish git checkout from the commands.
How to distinguish the checkout command from other git commands
git rm works on committed changes, deleting files and directories from the file system
git rm <file or directory>
or unstaging them.
git rm --cached <file>
git restore with the
--staged option does a similar job to
git rm with the
git restore --staged <file>
git reset exists in three forms: hard, soft, and mixed.
The hard reset
git reset --hard <HEAD or SHA1>
deletes the specified commits and the affected files from the file system.
The soft reset
git reset --soft <HEAD or SHA1>
does not discard files but uncommits the changes.
git rm with the
--cached option and
git restore with the
--staged option, the mixed reset
git reset HEAD
It would be best to apply
git reset on unpushed repositories and use
git revert <HEAD or SHA1>
on a shared repository with a remote. Instead of discarding commits,
git revert inverses them with a new commit. Unlike the reset or checkout commands,
git revert only operates at the commit level.
Another specific command is
git clone <remote URL>
git clone differs from
git checkout because it fetches remote commits into the local repository, whereas the checkout command switches commit HEAD between local branches.
After checking out a branch, you can introduce more commits and combine them with the main branch by switching into the main branch and using git merge.
git merge <modified branch>
Here, you create a ball of commits and throw it into the main branch with a commit message. Use
git rebase to stack the commits onto the main's changes.
git rebase <modified branch>
Commands such as
git stash and
cherry-pick help maintain a repository.
The key takeaway here is to use git checkout in switching branches and let other commands handle git unstaging. Besides, you can use supportive commands to ease collaboration and repository maintenance.
Enough with comparisons. Let us do some practice with the checkout command.
Lab setup to practice git checkout
I am creating a repository on GitHub called
I then copy its URL and clone it on my terminal.
cd into the cloned repository and create two files, stage, and commit them.
cd git_checkout echo "File 1" > file1.txt git add file1.txt git commit -m "Track file 1" echo "File 2" > file2.txt git add file2.txt git commit -m "Track file 2" git push
We have three commits on the main branch.
Let us do some practice with the setup.
git checkout command examples
Example-1: Git checkout a file to undo commit using HEAD reference
We can undo the last commit by modifying
file2.txt, staging, and committing it, then check it out.
echo "Modify file2.txt" >> file2.txt git add . git commit -m "Change file 2"
undo the last commit,
git checkout HEAD~1 file2.txt
and recheck the status.
The changes returned to the index.
Example-2: Git undo a specific commit using checkout
Let us log history and check out the second commit from the local HEAD.
git log --pretty=oneline git checkout 0cff5e7c8263a11b405ed8d3735d6257fdeeb055
Git tells us we are in a detached HEAD. That means the ref in the
.git/HEAD file does not match a branch, as git expects it to.
Git sees ref: refs/heads/<commit> instead of the expected format ref: refs/heads/<branch>. So, git does not know what to do with changes you do at the misplaced HEAD.
The best time to check out a commit is when restoring commits after a hard reset. Let us return the HEAD to the main branch.
git checkout main
Reset the last commit.
git reset --hard HEAD^
And restore it from the reflog using the checkout command and a new branch.
git reflog git checkout 0cff5e7 git switch -c new_branch
Return to the main branch and rebase the
git checkout main git rebase new_branch
Rechecking the history
git log --pretty=oneline
confirms the restored changes.
Example-3: Checkout and switch to an existing branch
Let us switch to the
new_branch branch, add a commit, and push it with its changes to the remote.
git checkout new_branch echo "File 3" > file3.txt git add file3.txt git commit -m "Add file 3, second branch" git push origin new_branch
You can then create a pull request on GitHub to merge the branches remotely.
Example-4: Checkout and create a new branch
Apart from switching to an existing branch and making changes, you can create a new branch using the checkout command and the
git checkout -b third_branch
Checking the number of branches
confirms we have three branches:
Example-5: Checkout and switch into a remote branch
Let us list all the remote branches using the
git branch -r
And switch to the
origin/new_branch branch by checking it out.
git checkout origin/new_branch
That detaches the HEAD. We can then create a branch from the detached HEAD as we did in example~2 above.
Git checkout is a multi-purpose command. It allows you to undo changes and switch the HEAD between branches. Using it effectively requires understanding the origin of the term HEAD and distinguishing the command from related commands, as explained in this tutorial.