To this end, storing “safe” versions isn’t much help without the ability to restore them. Our next task is to learn how to view the previous states of a project, revert back to them, and reset uncommitted changes.
If you’ve been following along from the previous module, you already have everything you need. Otherwise, download the zipped Git repository from the above link, uncompress it, and you’re good to go.
Display Commit Checksums
As a quick review, let’s display our repository’s history. Navigate a command prompt (or Git Bash) to themy-git-repo
folder
and run the following.The output for this should look similar to the following, but contain different commit checksums.git
log
--oneline
Git only outputs the first 7 characters of the checksum (remember that you can see the full version with the default formatting of1c310d2
Add navigation links54650a3
Create blue and orange pagesb650e4b
Create index page
git log
).
These first few characters effectively serve as a unique ID for each
commit.View an Old Revision
Using the newgit checkout
command, we can view the contents of
a previous snapshot. Make sure to change 54650a3
in the following
command to the ID of your second commit.This will output a lot of information about agit
checkout
54650a3
detached HEAD
state. You can ignore it for now. All you need to know is that the above
command turns your my-git-repo
directory into an exact replica of
the second snapshot we committed in The
Basics.Open the HTML files in a text editor or web browser to verify that the navigation links we added in the third commit have disappeared. Running
git log
will also tell us that the third commit is no longer part
of the project. After checking out the second commit, our repository history
looks like the following (the red circle represents the current commit).
View an Older Revision
Let’s go even farther back in our history. Be sure to changeb650e4b
to the ID of your first commit.Now, thegit
checkout
b650e4b
blue.html
and orange.html
files are gone,
as is the rest of the git log
history.
git
status
will answer that question for us. It should return the following
message:Compare this with the status output from the previous module:#
Not currently on any branch.
nothing to commit (working directory clean)
All of our actions in The Basics took place on the#
On branch
master
nothing to commit (working directory clean)
master
branch, which is where our second and third commits still
reside. To retrieve our complete history, we just have to check out this
branch. This is a very brief introduction to branches, but it’s all we
need to know to navigate between commits. The next module will discuss branches
in full detail.Return to Current Version
We can use the samegit checkout
command to return to the
master
branch.This makes Git update our working directory to reflect the state of thegit
checkout
master
master
branch’s snapshot. It re-creates the
blue.html
and orange.html
files for us, and the
content of index.html
is updated as well. We’re now back to
the current state of the project, and our history looks like:
Tag a Release
Let’s call this a stable version of the example website. We can make it official by tagging the most recent commit with a version number.Tags are convenient references to official releases and other significant milestones in a software project. It lets developers easily browse and check out important revisions. For example, we can now use thegit
tag
-a
v1.0
-m
"Stable version of the website"
v1.0
tag
to refer to the third commit instead of its random ID. To view a list of
existing tags, execute git tag
without any arguments.In the above snippet, the
-a
flag tells Git to create an
annotated tag, which lets us record our name, the date, and a
descriptive message (specified via the -m
flag). We’ll use
this tag to find the stable version after we try some crazy experiments.Try a Crazy Experiment
We’re now free to add experimental changes to the example site without affecting any committed content. Create a new file calledcrazy.html
and add the following HTML.<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<title>
A Crazy Experiment</title>
<meta
charset=
"utf-8"
/>
</head>
<body>
<h1>
A Crazy Experiment</h1>
<p>
We're trying out a<span
style=
"color: #F0F"
>
crazy</span>
<span
style=
"color: #06C"
>
experiment</span>
!<p><a
href=
"index.html"
>
Return to home page</a></p>
</body>
</html>
Stage and Commit the Snapshot
Stage and commit the new file as usual.It’s a good practice to rungit
add
crazy.html
git
status
git
commit
-m
"Add a crazzzy experiment"
git
log
git status
to see exactly
what you’re committing before running git commit -m
. This
will keep you from unintentionally committing a file that doesn’t belong
in the current snapshot.As expected, the new snapshot shows up in the repository’s history. If your log history takes up more than one screen, you can scroll down by pressing
Space
and return to the command line by pressing the letter
q
.View the Stable Commit
Let’s go back and take a look at our stable revision. Remember that thev1.0
tag now serves as a user-friendly shortcut to the third
commit’s ID.After seeing the stable version of the site, we decide to scrap the crazy experiment. But, before we undo the changes, we need to return to thegit
checkout
v1.0
master
branch. If we didn’t, all of our updates would be on
some non-existent branch. As we’ll discover next module, you should
never make changes directly to a previous revision.At this point, our history should look like the following:git
checkout
master
git
log
--oneline
514fbe7
Add a crazzzy experiment1c310d2
Add navigation links54650a3
Create blue and orange pagesb650e4b
Create index page
Undo Committed Changes
We’re ready to restore our stable tag by removing the most recent commit. Make sure to change514fbe7
to the ID of the crazy
experiment’s commit before running the next command.This will prompt you for a commit message with a default ofgit
revert
514fbe7
Revert
"Add a crazzzy experiment"...
. You can leave the default message and
close the file. After verifying that crazy.html
is gone, take a
look at your history with git log --oneline
.Notice that instead of deleting the “crazzzy experiment” commit, Git figures out how to undo the changes it contains, then tacks on another commit with the resulting content. So, our fifth commit and our third commit represent the exact same snapshot, as shown below. Again, Git is designed to never lose history: the fourth snapshot is still accessible, just in case we want to continue developing it.506bb9b
Revert "Add a crazzzy experiment"514fbe7
Add a crazzzy experiment1c310d2
Add navigation links54650a3
Create blue and orange pagesb650e4b
Create index page

git revert
, remember to specify the commit that you
want to undo—not the stable commit that you want to return to. It helps
to think of this command as saying “undo this commit” rather than
“restore this version.”Start a Smaller Experiment
Let’s try a smaller experiment this time. Createdummy.html
and leave it as a blank file. Then, add a link in the
“Navigation” section of index.html
so that it
resembles the following.In the next section, we’re going to abandon this uncommitted experiment. But since the<h2>
Navigation</h2>
<ul>
<li
style=
"color: #F90"
>
<a
href=
"orange.html"
>
The Orange Page</a>
</li>
<li
style=
"color: #00F"
>
<a
href=
"blue.html"
>
The Blue Page</a>
</li>
<li>
<a
href=
"dummy.html"
>
The Dummy Page</a>
</li>
</ul>
git revert
command requires a commit ID
to undo, we can’t use the method discussed above.Undo Uncommitted Changes
Before we start undoing things, let’s take a look at the status of our repository.We have a tracked file and an untracked file that need to be changed. First, we’ll take care ofgit
status
index.html
:This changes all tracked files to match the most recent commit. Note that thegit
reset
--hard
--hard
flag is what actually updates the file.
Running git reset
without any flags will simply unstage
index.html
, leaving its contents as is. In either case, git
reset
only operates on the working directory and the staging area, so
our git log
history remains unchanged.Next, let’s remove the
dummy.html
file. Of course, we
could manually delete it, but using Git to reset changes eliminates human
errors when working with several files in large teams. Run the following
command.This will remove all untracked files. Withgit
clean
-f
dummy.html
gone, git status
should now tell us that we have a
“clean” working directory, meaning our project matches the most
recent commit.Be careful with
git reset
and
git clean
. Both operate on the working directory, not on the
committed snapshots. Unlike git revert
, they
permanently undo changes, so make sure you really
want to trash what you’re working on before you use them.Conclusion
As noted in the previous module, most Git commands operate on one of the three main components of a Git repository: the working directory, the staged snapshot, or the committed snapshots. Thegit reset
command undoes
changes to the working directory and the staged snapshot, while git
revert
undoes changes contained in committed snapshots. Not
surprisingly, git status
and git log
directly
parallel this behavior.
git
revert
saves the commit in case you want to come back to it later. This
is only one reason for preserving committed snapshots. When we start working
with remote repositories, we’ll see that altering the history by removing
a commit has dramatic consequences for collaborating with other developers.This module also introduces the concept of switching between various commits and branches with
git checkout
. Branches round out our
discussion of the core Git components, and they offer an elegant option for
optimizing your development workflow. In the next module, we’ll cover
the basic Git branch commands.Quick Reference
git checkout <commit-id>
- View a previous commit.
git tag -a <tag-name> -m "<description>"
- Create an annotated tag pointing to the most recent commit.
git revert <commit-id>
- Undo the specified commit by applying a new commit.
git reset --hard
- Reset tracked files to match the most recent commit.
git clean -f
- Remove untracked files.
-
git reset --hard
/git clean -f
- Permanently undo uncommitted changes.
Comments
Post a Comment