Erik's Thoughts and Musings

Apple, DevOps, Technology, and Reviews

Using Git

I have been using Git a lot in the last few weeks, for setting up this blog and for some research at work. Here is a brain dump for mainly my own personal reference.

Initial Setup

One thing you’ll probably want to setup on first run, make sure you fill in your name and email address in the Git configuration so that commit notes are assigned to you. In UI clients, it will probably ask you the first time you launch or try to download a repository. At the Terminal, you will want to do this:

$ git config --global user.name "Erik Martin"
$ git config --global user.email emartin@myemailservice.com

Getting a repository

Downloading an existing repository:

$ git clone http://git.server.com/git/myproduct.git

It will create a local folder named myproduct and start copying the files. This will retrieve the master branch. The above URL will be configured as the origin.

If you want to grab a specific branch called feature_branch and place it in the local product_feature_branch folder, you do the following:

$ git clone http://git.server.com/git/myproduct.git -b feature_branch product_feature_branch

Committing and Pushing

After you clone the tree, you can do commits just like Subversion:

$ git commit -m “This is a commit message” file.cpp

Assuming you are still on the master branch, push back to the origin remote like this:

$ git push origin master

Or push all local branches back to the origin:

$ git push origin --all

Remotes

You can easily setup another “backup” remote to a folder on your same machine by doing something like this in the local repository folder:

$ git remote add backup /Users/emartin/Source/backup/myproduct.git

A push of the master branch to the backup remote would look like this:

$ git push backup master

You can list all of a repository’s remotes by going to a local repository folder and typing:

$ git remote -v
backup /Users/emartin/Source/git/backup/myproduct.git (fetch)
backup /Users/emartin/Source/git/backup/myproduct.git (push)
origin http://git.server.com/git/myproduct.git (fetch)
origin http://git.server.com/git/myproduct.git (push)

New Repository Setup

If you want to create a new repository from an existing set of files, in the top level folder do this:

$ git init
$ git add .
$ git commit -m “Initial checkin” .

Then on the server or a local remote, you setup a bare repository, say in a folder named myproduct.git

$ mkdir myproduct.git
$ cd myproduct.git
$ git init --bare

Server or local remotes should be bare or you will get a warning during your push. See more info below in the research section of what a bare repo is and why a push must be bare.

On your local machine, you setup the remote in the new repository top level folder:

$ git remote add origin http://git.server.com/git/myproduct.git

And then assuming the authentication is correctly setup, push:

$ git push origin master

Branching

If you want to create a new branch and set it to the current branch, you just do the following while in the local sandbox:

$ git branch new_feature_branch
$ git checkout new_feature_branch

Quick way to create and set the branch:

$ git checkout -b new_feature_branch

To switch back to the master branch:

$ git checkout master

Git Rebase

Sometimes it makes sense to take commits from a feature branch and 'rebase' them into another branch, like the main development branch. That makes the log look more linear when looking back in the history. Here is an example of a rebase:

http://git-scm.com/book/en/Git-Branching-Rebasing

Submodules

Submodules are analogous to Subversion externals, a way to "attach" external repositories to another repository. Submodules work differently and are not as easy to use as svn externals. More info below in the research section.

To add a new submodule to an existing git repository:

$ git submodule add http://git.server.com/git/third_pary_library.git third_pary_library

This creates a folder called third_party_library and updates a .gitmodules file. .gitmodules is version controlled in the parent repository.

After adding, you have to commit the submodule:

$ git commit -m “Committing the submodule third_party_library” .

This commit locks the submodule to that revision of third_party_library. So if someone clones your parent repository, they get the committed revision of the submodule.

If a repository has submodules, there are two ways to check out. The legacy way:

$ git clone http://git.server.com/git/myproduct.git
$ cd repository
$ git submodule init
$ git submodule update

And the easy way:

$ git clone --recursive http://git.server.com/git/myproduct.git