Sunday, May 20, 2012

You Git. No, I'm Not Insulting You!

Coming from having used SVN for many years, I had to do some reading to figure out what this Git this was all about. Yes, there are many other "Git How-To's" out there, but I thought I'd share the notes that I took. Be forewarned, this only covers the basics and doesn't touch upon the important topics of branching and merging.

The Basics

For details on what Git is and all of the nitty gritty details, I would recommend you check out this page, along with the complete git reference. However, the first thing that you will likely need to do is intall it. More complete instructions can be found here, but here are links to the OS X and Windows installers.
After you’ve installed git, you probably want to check to see that your details are correct, so that when you are working with a team that your name and email are correct. To check what your name and email are set to currently, do (most likely these are not set, so they will return nothing):
local$ git config --get user.name
local$ git config --get user.email
If you want/need to make changes, do:
local$ git config --global user.name ‘Your Name’
local$ git config --global user.email you@somedomain.

Create a New Local Git Repository

Let’s say you just want to put the files on your machine in git to do some version control and don’t need/want to use an external server. For that, simply go to the directory that you want to put under version control and do:
local$ mkdir MyFirstGit
local$ cd MyFirstGit
local$ git init
When you take a look at what's in your MyFirstGit directory, you'll see a new .git directory. This is where git stores all of the metadata. (Unlike svn that has a .svn directory in every subdirectory, there is only one .git directory in a git repository). So, fundamentally, git repositories are composed of two things:
  1. The data. I.e. the “working tree” of directories/files.
  2. A .git directory that contains all of the metadata
If you already have files in that directory to be included in the repository, you’ll want to add them
local$ git add .
Assuming you had some files there to begin with, you’ll want to make an initial commit to save your starting point.
local$ git commit -m “Initial import”
Note, if you don’t want to do “git add [filename]” each time you add new files, you can combine the git add and git commit steps by doing (i.e. adding that -a flag):
local$ git commit -am "My message"
Now, in many cases you may want to use a separate git server to keep track of all your projects. Note, since git is a distributed version control system, you technically don't need a git server, you can just push/pull all of the data to/from your collaborators' computer(s) directly. However, it is often easier to have a central place for the repositories so that the URL stays the same. If you want to set up a get repository server, read on.

Create a New Remote Git Repository

To set up a new git repository (i.e. it's a new project your starting and don't already have a git repository on your local machine) on a server you'll want to do the following (note, if you have an existing git repository you want to put on a server, see the next section):
local$ mkdir myProject.git
local$ cd myProject.git
local$ git init --bare
local$ scp -r myProject.git [user]@[remote]:~/path/to/repositories
As you can see, I am assuming that you have a server somewhere with SSH and/or SCP installed. The init --bare tells git to create a "bare" repository that does not contain any of the actual data and only keeps the metadata about the project (for more info on why this is important, take a look at this page).

Clone the Repository

Now that the repository is on the server, you can clone (the equivalent of"checkout" in svn speak) the repository.
local$ git clone ssh://[user]@[remote]/full/path/to/repositories/myProject.git

Create a Remote Git Repository For an Existing Local Repository

If you already have an existing git repository that you have been working with on your computer, you can do something very similar except that instead of creating a new repository, you clone your existing repository (albeit making it a “bare” one)
local$ git clone --bare /path/to/myExistingProject.git myExistingProject.git
local$ scp -r myExistingProject.git [user]@[remote]:~/path/to/repositories

Making Your Repository Point to the Server

Now that you have the bare repository on the server, you’ll want to make your local repository point to the one on the server. Of course you could clone the remote repository as above, or you can simply add a “remote” location to your existing project. If your repository was cloned from somewhere else and already has a default origin, you’ll first want to remove that origin. To check if it is pointing somewhere else do:
local$ git remote -v
If you see an origin entry there, you’ll want to remove it
local$ git remote rm origin
Now you can add your new origin.
local$ git remote add origin ssh://[user]@[remote]/path/to/repositories/myExistingProject.git
Or, include the port if you are not using the default port for SSH (22).
local$ git remote add origin ssh://[user]@[remote]:[port]/path/to/repositories/myExistingProject.git
Of course, you can name this remote location anything you want (or add multiple ones). The “origin” is simply the alias that will be used when you push data (see below).

Commit Changes to the Repository

Having cloned the repository you can now add/remove files and then commit them. Let’s assume that you are in some existing git repository and you create and add a new file:
local$ echo “a” > a.txt
local$ git add a.txt
local$ git commit -m “Added a new file, a.txt”
The files are now committed to the local “cache.” No one else will see these changes since you haven’t told the server that you made the changes. To publish your changes do:
local$ git push origin master
This tells git to push your data to “origin” (the place you cloned the data from) to the branch called “master” (the default branch). For a more detailed explanation on pushing and pulling data from a repository, take a look at this.

Miscellany

If you are using the Eclipse IDE, the EGit plugin will allow you to work with git repositories from within the IDE.

If you don't use Eclipse, but don’t like the command line for git related stuff (and like a nice UI), take a look at Tower. Sorry, that's OS X only...

By the way, since the above remote git repository requires SSH access to the server, every user that wants to work on that project needs to have SSH access to that machine. If you don't want to setup separate (SSH) accounts for every user, you can use a tool called gitosis or gitolite. However, if you have access to a machine to which all users already have SSH accounts, you probably don't need to do this (in case you care, I've never used either of those tools).