Alex headshot

AlBlue’s Blog

Macs, Modularity and More

Git Tip of the Week: Branches

2011, git, gtotw, tip

This week's Git Tip of the Week is about working with branches. You can subscribe to the feed if you want to receive new instalments automatically.

Branches

So far I've only talked about code which is on a single branch, or in Git terms, the master branch. That's fine for getting started, but you will soon find that you want to create branches for parallel development.

First, it's worth briefly mentioning how Git handles branches, because it's a fairly fundamental part of how Git works. Every Git repository is a tree of commits, with the initial commit being the root of the tree. Every subsequent commit has one or more parents; so from any given commit, you can walk up its parent tree(s) to find the initial commit of a repository.

Since each of these commits is represented as a hash, like 9ab532… then any point on the Git repository's tree of commits can be uniquely identified by this number alone.

As a result, every reference mechanism in Git basically boils down to storing this hash value somewhere. For (local) branches, these are stored in the files refs/heads/*; you'll find a master file in there with a 40-character hash as its contents.

Working with branches

To display a list of branches in Git, run git branch. This shows the list of branches that are currently in your repository. The asterisk shows you which branch you're on at any time.

To create a new branch, based off the current branch, you use git branch name. If you want to base it off a different commit, you can use git branch hash name. To switch to a different branch, you use git checkout name. Here's what it looks like when put together:

$ git branch
* master
$ git branch new
$ git branch
* master
  new
$ git checkout new
$ git branch
  master
* new

There's a shorthand for creating a branch and checking it out, which is git checkout -b name [hash]; so in the above case, we could have done git checkout -b new:

$ git branch
* master
# Shorthand for: git checkout -b new master
$ git checkout -b new
$ git branch
  master
* new

You'll find that what's happened is there has been a file created, refs/heads/new, which contains the new pointer to the tree. Since we created one from the other, they've both got the same contents. However, if we were to commit a change to the new branch, then they would be different. The master branch would stay where it was, whilst the new branch would be one commit ahead.

If you were to checkout the master branch instead, and create a commit, then the branches would start to diverge. Alternatively, we might want to bring in that change from new to master, which we'll do with a merge next time.


Come back next week for another instalment in the Git Tip of the Week series.