Skip main navigation

What is a Git Branch?

Branches can be employed to develop different features separately. Just like a tag and the HEAD, Git represents a branch by simply maintaining a reference to a commit. Specifically, it refers to the most recent commit on that branch.
© The University of Manchester

Branches can be employed to develop different features separately. Just like a tag and the HEAD, Git represents a branch by simply maintaining a reference to a commit. Specifically, it refers to the most recent commit on that branch.

Every commit (except the first) has at least one parent commit from which it is derived. As with all other references in Git, the SHA is used by Git to maintain this reference. However, it is important to understand the concept of reachability as we traverse a Git graph.

Since a commit contains a reference to its parents, we can always follow the chain of references back and “reach” all the commits from the very first commit up until the current one.

However, that does not mean that we can necessarily “reach” every commit in the project in this way.

Git Branch Example

As a simple example, imagine if we are currently on the [add-clothes-shop] branch of our project. By following the parent references of each commit in the chain, we can reach all the commits from the very latest commit on the branch to the very first commit of the project.

Git graph showing how each commit references its parent

However, there is no way for us to walk back through the chain and end up at any of the commits made on other branches, these are said to be “unreachable” from the [add-clothes-shop] branch. If we switch to another branch, the commits we see on that branch will be those that are reachable from the checked out branch while commits that are only on other branches become unreachable.

We can actually see how Git represents a branch by looking directly in the Git directory. The “refs” directory holds all the important references that Git needs to build the network. Inside, we can see that there are subdirectories for the remote tracking branches, tags and “heads”. In this case “heads” refers to the “head” or “end” of a branch, it should not be confused with the HEAD which points to whatever commit we are currently working with.

Directories showing the location of the refs and heads directories

Git Branch File

Looking in the heads directory we can see a list of files with filenames which match our branch names. Reading one of the files reveals that the contents consist of only a SHA number. There really is nothing more than that. This is all a Git branch is! The SHA number is, of course, the SHA number of the most recent commit on that branch.

A text editor showing that the branch file contains a SHA number and nothing else

When we list the branches available to us using the

$ git branch

command, Git simply enumerates the branches which it finds in this directory. We can test this by listing our branches, deleting one and noting that it subsequently disappears from the list.

Output of the Git branch command showing three branches listed and the master highlighted

Heads directory showing one of the branch files being deleted

Output of the Git branch command showing three branches listed and the master highlighted

Similarly, in order to build the graph, Git simply follows the path of parent references from each of the commits referenced by the files in the heads directory. Deleting one of the references from this directory effectively removes the branch.

Terminal output of a Git graph showing three branches

Heads directory showing one of the branch files being deleted

Terminal output of a Git graph showing two branches

Although the branch has been removed, we know that all we have actually deleted is a file containing a SHA number. We deleted a reference, but nothing else. All the data and commits which made up the branch still exists as objects in the .git folder, though they are all now unreachable. If we knew the SHA number for any of the commits that were in the “lost” branch, we could access them directly using the checkout command. However, this unusual situation would ensure that we ended up in a detached head state.

What do you think would happen if, instead of deleting a branch file, we renamed it? Try renaming one of the branch files yourself and see if you are correct.

© The University of Manchester
This article is from the free online

Collaborative Coding with Git

Created by
FutureLearn - Learning For Life

Our purpose is to transform access to education.

We offer a diverse selection of courses from leading universities and cultural institutions from around the world. These are delivered one step at a time, and are accessible on mobile, tablet and desktop, so you can fit learning around your life.

We believe learning should be an enjoyable, social experience, so our courses offer the opportunity to discuss what you’re learning with others as you go, helping you make fresh discoveries and form new ideas.
You can unlock new opportunities with unlimited access to hundreds of online short courses for a year by subscribing to our Unlimited package. Build your knowledge with top universities and organisations.

Learn more about how FutureLearn is transforming access to education