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>
Replacing the -f
with the -p
option
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
cat .git/HEAD
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
cat .git/HEAD
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 --cached
option.
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.
Like git rm
with the --cached
option and git restore
with the --staged option
, the mixed reset
git reset HEAD
unstages changes.
It would be best to apply git reset
on unpushed repositories and use git revert
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
.
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 git_checkout
.
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.
git log
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"
Check status,
git status
undo the last commit,
git checkout HEAD~1 file2.txt
and recheck the status.
git 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 new_branch
.
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 -b
option.
git checkout -b third_branch
Checking the number of branches
git branch
confirms we have three branches: main
, new_branch
, and third_branch
.
Example-5: Checkout and switch into a remote branch
Let us list all the remote branches using the -r
option.
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.
Conclusion
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.