Really Quick Git

An attempt to quickly demonstrate the usefulness of Git for the single-developer environment

What does Git give you as an individual developer?

  • History of changes you made to your files.
    • Allows you to see when particular changes / features were implemented.
    • Also can provide an explanation to why you changed something the way you did.
  • ‘Universal undo’
    • Revert changes to any file you are tracking in Git.
    • Completely external to the particular editor you are using at the time.
    • Useful when a rm goes bad, or when you get crazy with Vim (“:d20j :wq”).
  • Test out new changes / ideas without fear.
    • Branching capabilities in Git make it easy to try out large scale modifications to your code that you can always revert if things don’t work out.
    • Also could be useful if you need to have a number of versions of your code with small tweaks in them.
  • Tagging allows you to know exactly how your code looked at a particular revision
    • Useful for when you need to know if a bug / feature was present in the code at version x

What a central Git repository (like Github) gives you

  • Easily share code in a consistent, familiar manner.
  • Provide a backup of your source code for when your harddrive crashes.
  • A quick place to share code with yourself on multiple computers.
    • Keep working (and maintaining a history of your work) no matter where you are.

Worth it?

I think it can be hard to prove that the added benefit you get from a version control system is worth the effort it takes to use it. Hopefully I can show that even with just a minimal amount of overhead, Git can be an valuable tool.

Assumptions

  • You are on a *nix based machine
  • Git is already installed on your system

Initial Setup

There are a few steps that are good to take care of up front, to avoid frustrations later on. We will just execute these commands without too much explanation as to the details of what they do. Commands are executed in the terminal.

Set your get name and email

git config --global user.name "Jim Somebody"
git config --global user.email "jims@domain.com"

Turn on color for your git output

git config --global color.ui true

Add global gitignore file for temporary files

# create .gitignore in home directory

touch ~/.gitignore

# add some files patterns to ignore

echo "\*.swp" >> ~/.gitignore
echo ".DS_Store" >> ~/.gitignore

# tell git about our global ignore

git config --global core.excludesfile ~/.gitignore

# you can add to this .gitignore file later

# and each git project also can have its own

# specific .gitignore

Ok, that takes care of most of the setup stuff. Lets get to using Git.

How Git works - the basics

Here’s a quick rundown of the basic points on how Git operates.

You Commit Changesets to a Git repository

Git works with groups of changes to your files, which we will call changesets. A changeset can include adding / removing text inside a file and / or adding / removing entire files. A changeset is commited to the git repository to track the changes. The idea here is that each changeset should optimally contain changes for a single logical modification to your code.

So, for example, if you codebase is a command line tool, a possible changeset would be adding the ability to specify an output directory. You would commit all the file modifications to complete this change as a single changeset. Another changeset could be the creation of a new class to represent ‘xyz’. That would go into its own changeset and that changeset would be committed to the repository.

You can work at a lower or higher scope than this, but I belive working with individual logical changes as individual changes allows you to get the most from your repository.

Git has a Staging area to Prepare your Commits

As changesets can and often do include multiple files, you need a way to group your changes before committing. That’s where the staging area comes in. The staging area is a holding place for changes in a changeset that will be committed.

This makes committing a change a 2 step process:

  • First, a change is added to the staging area
  • Then, the set of changes in the staging area (your changeset) is committed.

This makes it easy to have lots of modified files, but pick and choose which changes go into individual commits. Without a staging area, you would have to either only work on a single changeset at a time, or be forced to combine modifications from different logical modifications into one large commit. Both of these options are no good - hence the staging area.

Working with Git

Enough of the theoretical, lets start using it.

Initialize Git Repo

The first step is to create a Git repository. You can do this in a directory that already has files in it that you now want to track, or you can do this in a clean directory as a first step to starting a project.

cd /path/to/directory
git init

You now have a git repository in your current directory capable of tracking changes to all files in this directory and any sub-directory of this directory. It current is not tracking any files.

Preparing for the First Commit: Excluding Files

Usually, you will git init in a directory that already has files in it. Lets assume that is the situation for the rest of this article.

In this situation, it is beneficial to add all current files at once to git, and use this as your first commit.

But before we do that, lets make sure that there aren’t any files we want to not have tracked in git. Usually, files that are automatically generated and temporary files are good candidates for files we don’t want to track.

Lets say that there is a directory called temp that we don’t want to track changes to. To tell git about this directory, we add it to the repositories .gitignore file. So create this file and add temp to ignore:

touch ./.gitignore
echo "temp/\*" >> ./.gitignore

Notice that we actually give a file matching pattern that says “ignore all files and folders inside of temp”. Git automatically ignores empty directories, and so Git will ignore the temp directory as well as we have made it ‘empty’ by ignoring all the files inside it.

First Commit

Ok, now we are ready to commit our current set of files to git.

First, its nice to see the status of git using git status

git status

# output with all files listed in 'untracked files' section

git add

Like I mentioned above, committing in git is really a 2 step process: add and then commit. This allows you to be very particular about which files go into a specific commit.

As this is our first commit, we want to add all the files to our repository. This can be done a number of ways, but I like the following method:

git add .

And that’s it. See what you just did with git status

git status

# output with all files in the 'Changes to be committed' section

git commit

Now we are ready to commit these changes to our repository. Each commit in git is given a “commit message” which describes what these changes are about. You can make these messages as long as you want, but for individual developers, its usually easiest to provide short but meaningful comments on what you changed. You can provide this short style comment using the -m flag when committing.

git commit -m "initial commit"

And that’s it! Your new files have been added to git to track. Check git status and you will see that there are no new changes.

Git Workflow

With just a few commands, you can quickly utilize git to track changes, try out new experimental changes, and figure out why or when things changed.

Adding changesets to git

By far the most common procedure is checking in new commits to git. Here is the general workflow for this process:

git status

# see what changes have been made

git add file1
git add file2

# add particular files that have been modified as part

# of the current change you are working on

git commit -m "added xyz feature for abc reason"

# commit with comment

So just 3 commands: git status, git add, and git commit. If you aren’t sure what you did to a particular modified file use git diff file_name to get a quick diff of the uncommitted changes.

blog comments powered by Disqus