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
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.