Wednesday 14th January 2009
One of the most important features of git is the ability to branch. By default, a git repository has just one branch, known as master. You can see this by typing:
This shows all the current branches of a git repository. When we create another branch, git treats it independently of all the other branches. When we commit to one branch, only that branch is updated.
So, for instance, we might have the master branch as the stable version of the program under development. If you want to add a caching feature to your application, you might create a new branch called caching, based on the stable version. This means that you can make changes to the caching branch, potentially breaking the application, but you'll still have the stable branch, master, being unaffected.
This could be handy, say, when somebody finds a bug. If you want to issue a quick fix, you can change back to the master branch, fix the bug, commit the fix, and then go back to the unstable caching branch and carry on hacking.
So, enough chatter - how do we actually create branches? Simple. Just issue the command:
git branch <my-branch>
This will create a new branch called <my-branch>. It will be based on whatever is currently checked out. So, if you're currently working on the master branch, git branch <my-branch> will create a new branch based on the HEAD of master.
If you type git branch, you can see the list of branches in the repository, with the currently checked out branch having an asterix next to it. Despite creating the new branch, you'll still be in the same branch as before. To change to the new branch, use:
git checkout <my-branch>
Now, any changes you commit will be committed to <my-branch>, rather than master (or whatever branch you happened to be in before)
To both create and change to a branch in a single command, use:
git checkout -b <my-branch>
Checking out is not just limited to branches - we can checkout specific commits. For instance, if we have a commit identified by f107dd02d45cbc88a539d52d6829eb7237023441, we can check it out using:
git checkout f107
This assumes that no other commits start with the characters f107 - otherwise, the identifier would be amibigious. The working tree now contains the contents of that commit. Note, however, that since we haven't checked out the HEAD of a branch, we can't do many of our usual operations, such as git add or git commit - doing so wouldn't make any sense since we're not actually on any branch. If we want to create a branch from this point, we can use the same command as before:
git branch <my-branch>
We don't have to checkout a specific commit that we want to branch from - we can just specify the commit when branching, like so:
git branch <my-branch> <commit-to-branch-from>
So, if we want to create a branch called baz from the commit before last, we would use:
git branch baz HEAD^
If we want to rename a branch, we simple use the -m flag:
git branch -m <old-name> <new-name>
We might also decide we no longer need a branch since we've merged its changes into some other branch (more on merging later). In that case, we use the -d flag:
git branch -d <my-branch>
If the changes of <my-branch> have not been fully merged, git will abort the deletion of that branch. If you really want to delete that branch and lose its commits, then use the -D flag:
git branch -D <my-branch>
When identifying commits, if a commit is the HEAD of a branch, you simply need to use the name of the given branch. Say we want to see how the caching branch differs from the master branch - we can use:
git diff master caching