Git Branches

A git branch is just a named text reference to a specific commit. They allow us to work on a feature without any risk to the default (master) branch. They also allow multiple people to work independently on the project by using different branches.

Multiple branches can exist in the same repository. The pointers for all branches live in the .git/refs/heads directory. The current branch tracks new commits and the branch pointer moves automatically after every commit. We move between branches using the git checkout command. Branch names cannot have spaces in them. Trying to do so gives a fatal error.

Lets examine .git/refs/heads. Run the following commands from the root of our project:

cd .git/refs/heads
ls
cat master

The ls shows us one file called master because master is the only branch we have in our project. If we had multiple branches, we would have a file per branch.cat master shows us the sha1 hash of the latest commit made in the master branch.

A brief digression to talk about HEAD. We can have many different branches with many different commits in them but we can have only one working directory. HEAD is the pointer to the currently checked out branch, it can also store a pointer to a specific commit. It is stored in the file .git/HEAD. If we cat that file, we’ll see a reference to the current branch.

Let’s remove our text files and commit the changes. Run the following commands:

rm *.txt
git add .
git commit -m "Third commit"

If we examine our master branch by catting .git/refs/heads/master, we will see that the branch has moved to our new commit. If we examine our staging area using git ls-files -s, we’ll see that the files removed are gone from there also. HEAD has also moved with the master branch because it still points at it.

Checking out a previous commit is done using the git checkout command. We can find the sha1 hash of the commit by running git log. Run

git log # copy the sha1 hash of second commit
git checkout <sha1 hash>
ls
git ls-files -s
cat .git/refs/heads/master
cat .git/HEAD

Using ls to examine our working directory shows that the files we deleted are back and git-ls-files shows that they are also back in the staging area. Examining refs/heads/master shows that our master branch hasn’t moved and catting .git/HEAD shows that the head now points to our second commit. Normally, we won’t check out a specific commit, but a named branch. We will have noticed that we are in detached head state. This simply means that HEAD is not pointing to a branch. Using git log will show only two commits because we are at a point in time before the third commit was made.

To move the HEAD pointer back to the master branch, we simply check it out:

git checkout master

Examining our HEAD will show that it once again points to master.

The most commonly used commands for branch management are:

git branch List all local branches. Currently checked out branch will be marked with *
git branch <name> Create a new branch
git checkout <name> Checkout the specified branch. Use git checkout -b <name> to create and checkout a branch
git branch -d <name> Delete the specified branch
git branch -D <name> Delete the specified branch even if it hasn’t been merged
git branch -m <old> <new> Rename the old branch to the new

When creating a new branch, it will be based on the last commit of the currently checked out branch. When we check out our new branch, all git does under the hood is update .get/HEAD to point to the checked out branch.

 

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.