To the Past

Now, let's say you've been working hard on your project and committing things and now you have lots of history. It's all in .git in a format you probably don't understand (I know I don't.).

Suppose you want to go back and look at an old revision. Before you can do this, you need to get the old revision's address.

Each commit (and just about everything git stores permanently) has an address that is determined by its contents and history.

To see a list of the addresses of past commits, use

$ git log

You'll see some lines that say something like "commit 7fe41ca3112b9f1a6cab21deb4649b52fa53c16a", followed by some more understandable information. That long string of letters and numbers is the commit id.

Usually, you can get away with chopping off the end. I'll call that one 7fe41ca for short.

To go back to an old commit, use the checkout command:

$ git checkout 7fe41ca

Now, here's where it gets a little messy.

There's a very real possibility that, when you entered that command, you had made changes that you didn't commit. Git would rather fail to complete your request than allow you to lose data.

If you've run that command, there are several things that might have happened.

If you see something like this

fatal: Entry 'readme.txt' not uptodate. Cannot merge.
That means that Git would have to change readme.txt, and you have made changes to it that are not committed. Git cannot give you the old version without overwriting your changes, so it did nothing instead.

If you see something like this

M       readme.txt
That means that you have changes to readme.txt, but that's OK because Git didn't have to touch readme.txt. The file still has your changes in it.

You will probably see something like this

Note: moving to "7fe41ca3112b9f1a6cab21deb4649b52fa53c16a" which isn't a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
  git checkout -b <new\_branch\_name>
I'll explain branches later. For now, this means that you cannot make commits until you go back to the current revision.

If you're a fan of time travel, you can think of it this way: You've used checkout to go back in time. You are now in the past. If you made a commit, that would mean you've changed the past. It would also mean that the present is different, and you potentially lose your work. Git won't let you do that. At least, not unless you ask it to, but I won't get into that until much later.

You will probably also see this

HEAD is now at 7fe41ca... saved the world from global thermonuclear war
That just means it worked.

Now, let's say you want to go back to the present. Did you write down the address of the most recent commit when you did git log?

No?

Well, no, git log won't tell you what it is now.

It starts at the current revision and works backward, so no, you won't see things that are in the future.

...

...

Anyway, you don't need that. Just checkout "master" to go back to the present:

$ git checkout master

An important difference from last time is that Git will say:

Switched to branch "master"
Again, I'll get into branches later. For now, this just means you can commit again. Also, for now, "master" is the only place where you can commit.

If you prefer to look at your commits in a GUI (I usually do), use gitk:

$ gitk

This will show you not only the commit messages and their id, but a listing of the things that changed in each commit.

Here's a list of other things you can use in checkout:

See "git help rev-parse" for more.

Vincent Povirk