Git In Two Minutes (updated after 8 years)

Hacker News - Sat Aug 6 18:03

Inspired by “Git in 5 Minutes”, I decided to take things a step further, and create guide for git that takes even less time to get through. Of course, this is very minimalistic git! But it’s enough be useful for beginning solo developers, and provides a start from which you can grow. As far as I know, this post is the absolute record for minimalistic git guides on the web!  

In two minutes, there isn’t time to worry about a remote server, so this manner of using git is only appropriate for a solo developer who has a regular backup strategy in place for their hard drive. With 2-minute git, plus a backup strategy, you can confidently commit files and know that you can see changes or restore an earlier version if you need to.

Why does this even matter? Well, one of the most annoying and time-consuming experiences a developer can have is to realize that something that used to work no longer does. In such situations, simply being able to see changes and go back to an earlier version can be a huge help. Also, being able to go back gives you freedom to experiment with a new approach — there’s no problem experimenting because you can always go back.

When you have a chance, you should definitely learn about such features as staging and branching, and pushing and pulling to/from remote repositories. But what you’ll learn here will still be useful!

Note: When a filename is mentioned below, you can just as easily use a file path.

Getting set up to use git

We’re assuming you’re working in a directory. The first thing you should do is:

  git init

which initializes the directory for git use.

Telling git about your files

Now you have to tell git which files it should care about. If you have N files, you can do 

  git add <file1>  <file2> … <fileN>

to add them. Or if you want to add every file in the directory, you can do

  git add .
 

Committing changes

Next, we need to commit changes. Any time you want to commit changes to one or more files, do

  git commit <file1> <file2> … <fileN> -m "This is your commit message"

Or, to commit all files that have changed since the last commit:

  git commit -a -m "This is your commit message for all changed files"

Be sure to make your commit message contain enough of a description that you can figure out what version you want to go back to.

Viewing history

Now we need a way to see old versions are available. To see your commit messages along with each version’s “hash” (a number that refers to the version), you can use the following command to show them in a one-version-per-line output. 

  git log --pretty=oneline

That will give you output that looks like the following, showing each commit’s hash together with its commit message

  dbe28a0a1eba45d823d309cc3659069fc16297e3 4th version I wanted to commit
  13bbf385e6d1f94c7f11a4cdfa2a7688dfdd84f8 3rd
  a1696f671fb90dc8ea34645a6f851d0ab0152fc2 2nd version
  179e59467039c7a7b81f676297415c8e018542a0 first version

Note, you can also use

  git log

for a much more verbose output, with multiple lines per version, and you can use

  git log --pretty=oneline -- <filename>

 to view only the changes for a particular file. (Note the space after the second pair of dashes!)

Restoring an old version

To restore a file to an earlier version, you need to identify the version you want to restore. To restore the most recently committed version, just do:

  git checkout HEAD -- <filename>

To get back an earlier version, just use the first few characters of the hash (enough to uniquely distinguish it):

  git checkout <hash> -- <filename>

For example,

  git checkout 179e59467039 -- myfile

will revert my file to the contents of the file called myfile that are associated with the 179e59467039c7a7b81f676297415c8e018542a0 hash (in this case, the first committed version of the file).

Seeing changes

You usually won’t want to retrieve an old version of a file without first examining the changes it contains! To see a list of the changes between the current file and the most recently committed one, you use the fact that HEAD represents the most recent commit:

  git diff HEAD -- <filename>

Alternatively, see a list of differences between the current version of a file and a historical one, you refer to the historical version’s hash:

  git diff <hash> -- <filename>

You can also compare two historical versions:

  git diff <hash1>  <hash2> -- <filename>

Finally, to see a list of the changes you’ve made since your last commit across all files, simply do:

  git diff 

Note: all the diff variants shown above put the results into a pager. You can page through using the space bar, and quit with q. If you don’t want to use the pager, add -P, like:

  git -P diff HEAD -- <filename>

Undoing a bad commit

More often than I care to admit, I've committed a change and then found that there was an error in either the commit message or in the code itself. I don't see any need to keep that error for posterity. So here's how to undo it:

  git reset HEAD^ 

One more thing – optional – may add another minute

While you can get a lot of benefit using just the features above, here's one more thing you'll find to be useful. If you don't want to bother with it now, don't – try it another time.

Sometimes, you're not sure what files have changed. To find out, you can do:

  git status 

That'll generate a list of files and their statuses. For example, a file that hasn't been "git add"-ed will be listed as untracked; if it's a file you care about, you should add it.

The reason I consider this command "optional" in a two-minute guide is that it can be a little unwieldy. It can list a lot of files you don't care about. For instance, if you're programming in Python, it'll show the compiled .pyc files that Python generates. And you'll probably want to do something about that.

To fix it, you need to create a file called .gitignore in your project directory. For instance, if you're working on a project in Python 2.x, you'll probably want it to contain (at least):

  .pyc

Notice that .gitignore understands the * wildcard. And if you want to hide an entire directory, you append the folder name with a slash. For instance you're working in Python 3.x, the compiled files go in a directory called __pycache__, so you'll want the following in your .gitignore:

  __pycache__/ 

And that’s it! Just keep this guide handy.

That’s all you need to know to get started with git, as long as you have a regular backup strategy for your hard drive. If you don’t want to memorize anything, just keep this guide bookmarked and you’ll be able to commit, compare versions, and get back old versions without any trouble!

Remember, this guide is literally as minimalistic as you can possibly get in order to do something useful with git. For powerful features like branching, staging, and sharing with others via a remote server, be sure to move on to Git In Five Minutes and even (?!) longer git guides when you have a chance!

[Update Aug 6, 2022: added the entry for undoing a commit.

Update Jan 2, 2017: added the use of HEAD in restoring file versions.

Update September 7, 2015: added two more ways of seeing changes.

Update September 20, 2015: for some reason the optional section on git status and .gitignore disappeared at some point. So I put it back! Also rewrote the diff section to put the HEAD version first.]