This article is by Quite Useful contributor Ric Roberts.
I’ve been using the version control system, git (along with GitHub) for a couple of months now, for my open source projects: grrid.js and Taskit. At Swirrl, we recently decided to take the plunge to start using git for our main code repository.
With this series of blog posts, I hope to ease the transition from subversion (or sourcesafe, or whatever) to git. In this article, I’ll just cover the basics. More advanced stuff will come later.
Why Switch?
There are several advantages to using git over other version control systems:
- Being a distributed version control system, everyone has their own version of the whole repository. The central repository (at GitHub in my case) is just arbitrary. This means that you can do operations such as tagging, branching and diff without having to be connected to the central server. This article by Eric Sink is a good explanation of how git differs from traditional version control.
- Due to the git:// protocol and the way git stores and tracks the data and changes in repositories, it’s really fast and the repositories don’t take up much room on disk.
- Quick, cheap, easy branching.
- The repository and branches are separate from the filesystem.
-
GitHub. Why go to the trouble of hosting a central repository yourself, when you can do it securely, cheaply and quickly with GitHub? There’s Sourceforge for svn, but for me GitHub does it better. If you can get to grips with GitHub, it opens up a world of possibilities for publishing or consuming open source code.
How Git Works
The whole repository is stored in a hidden folder called .git at the top level of your project structure. The working tree — the actual files in your project — are just the ones you happen to be working with at the time. Git doesn’t track the files themselves, it just tracks their content along with some metadata (read more about this here).
Git stores content in these locations:
- The working tree. This is the file system, where you manually make the changes.
- The staging area, where changes lie until they’re committed.
- The repository itself, where committed changes go (you can have local and remote repositories).
Commits in git are labeled with an SHA-1 hash instead of version numbers. There’s a very small chance of the hashes ever colliding, so they can be assumed to be unique. Git actually generates a 40 character-long hash but normally the first 7 or 8 characters are enough to uniquely identify a commit.
Installing Git
If you’re using Mac OS X like me, the easiest way to install git is to download the installer from the Google Code project. I used version 1.6.2.2. Alternatively, you can compile it from source or use Macports (see this guide).
If you want to share your code with others, you will need a centrally accessible server. GitHub provides this service for free.
Setting Up a Repository
Sign Up for GitHub
Visit GitHub and sign up for an account.
Next, set up an SSH key. This allows the git command to authenticate with GitHub and send your code to their servers.
Next, configure the global parameters on your computer to tell git what your GitHub username and email address are. For example:
git config --global user.name "RicSwirrl"
git config --global user.email my.email@address.com
Getting Code Into GitHub
Make a new repository with the GitHub web interface. Creating a new repository on GitHub gives you a short guide so you don’t need to remember all the steps. The process is outlined here for completeness.
Initialise your local project by changing into its directory and running:
git init
This will create the .git folder. Next, tell git about the GitHub remote (get the full command from the GitHub web interface):
git remote add origin ...
Next, add all the files in the directory to the repository. At this point they’re not being tracked yet.
git add .
This will add all the files in the directory to the staging area. You can then commit these files to your local repository, with a message:
git commit -m "my initial commit"
Now you have a fully fledged repository on your computer. To send it up to GitHub, just run:
git push origin master
Note that by default git will push to the “origin” remote repository in your config, using the current branch. If you want to push to a different remote repository, using a different branch, you can run something like:
git push github mybranch
Note: for this to work you’d have to define github in your config file as another remote repo, and have a ‘mybranch’ branch.
Push is a similar to a subversion commit, in that it allows you to share your changes with your colleagues.
Working With Existing Repositories
What if one of your colleagues has already set up the repository on GitHub? To get started, you just need to clone the remote repository like this (using the clone url displayed on the GitHub page). For example:
git clone git://github.com/Swirrl/grrid.git
I suppose this is equivalent to a subversion checkout. Watch out, though, because checkout means something a bit different in git.
Working With the Repository
Adding Files to the Staging Area
You’re now ready to start making changes to your code. Once you’ve made a few changes, you can see what’s happened by running:
git status
If you’re ready to commit some of these changes to your local repository, you need to run git add on each file you want to commit. This adds these changes to the staging area.
git add <filename_to_add>
What’s the Point of the Staging Area?
The staging area lets you choose which of your changes you want to commit – a bit like checking/unchecking files in the svn commit dialog in TextMate (or your editor of choice). You can change the files in your staging area as many times as you like, before committing.
Committing to the Local Repository
You can run git status again to check what’s going to be committed. When you’re happy, run:
git commit -m "my message"
…and the changes will be committed. If you know you just want to commit all the changes that you’ve made, you can do it all in one go by running this (i.e. skip the staging step):
git commit -a -m "my message"
Pushing Changes to the Remote Repository
At this point, the changes have been committed to your local repository, but the remote GitHub repository remains unchanged. For your colleagues to be able to see your commits you need to push them up to the remote repository with:
git push
Pulling Changes From the Remote Repository
If you want to see what your buddies have been up to, you need to pull their changes from the remote repository.
git pull
This will fetch the remote changes and merge them with your local ones — it’s a bit like the update command in subversion.
Viewing the Log
To see the history of the commits in a repository:
git log
Getting Help
Many git commands can take multiple optional arguments which I haven’t covered here. To get help on the usage of any command you can do:
git help <command>