Post

Git branches, where do they lead ?

Abstract

The Branch is a special labeled marker that allows you to switch back or forward to some particular state of your repository. I.e. branch is just a reference that is pointing to some dedicated commit hash. By having such aliases (branches) it is more easy to operate with git tree than keep in mind SHA1 commits number.

There is a misconception that branch is a data structure like a list or hashmap of commits. It is wrong, git uses the DAG commit structure and branches is a mechanism to create named anchors to some particular state (snapshot) in a time. All branches references are stored in .git/refs/heads directory

HEAD is the reference to the actual state. It can have two states: attached (referencing to some branch by its name) or detached (referencing to commit SHA1 number). On filesystem is represented by file .git/HEAD.

Init repo with first commit

Here is an initial state of repository with a single commit only. We can see that branch master is referencing to 0d38698f SHA1 commit and HEAD is attached and referencing to master.

1
2
3
4
$ cat .git/refs/heads/master
0d38698f4b3d301decb1aa390ee47c953e1fbccd
$ cat .git/HEAD
ref: refs/heads/master

Git repository snapshot:

  • 1 commits
  • 1 trees
  • 1 blobs
  • 2 refs: HEAD, refs/heads/master

If git’s concept of Commit, Tree and Blob is new for you, check this Link to a post with overview of these git’s internal objects and structures.

Adding second.txt file with a second commit. By doing this git is just moves master and HEAD references. And now they are pointing to the latest commit. Now master branch is referencing a newly made commit with SHA1 993bb5b5

Git repository snapshot:

  • 6 commits
  • 6 trees
  • 5 blobs
  • 4 refs: HEAD, refs/heads/master, refs/remotes/origin/HEAD, refs/remotes/origin/master

Detached HEAD

Lets checkout 0d38698f commit, by doing, so we are setting HEAD into detached state, now it is not associated with any branch, but referencing to a single commit. From this state, you can create a new branch, do operations with commit or checkout any other branch.

1
2
3
4
5
$ git checkout 0d38698f4b3d301decb1aa390ee47c953e1fbccd
Note: checking out '0d38698f4b3d301decb1aa390ee47c953e1fbccd'
You are in 'detached HEAD' state.
$ cat .git/HEAD
0d38698f4b3d301decb1aa390ee47c953e1fbccd

Git repository snapshot:

  • 2 commits
  • 2 trees
  • 2 blobs
  • 2 refs: HEAD, refs/heads/master

Adding feature branch and one more commit to master

Git repository snapshot:

  • 3 commits
  • 3 trees
  • 3 blobs
  • 3 refs: HEAD, refs/heads/master, refs/heads/feature

Adding remote origin

It is a local repo, now let’s create a repository on GitHub and add it as a remote origin. Now branch remotes/origin/master is referencing to 849d8fba5 commit. It is the latest commit push and available the remote repo. .git/refs/remotes directory represent remote repositories and remote branches.

1
2
3
4
$ git remote add origin git@github.com:tsypuk/gitexplore.git
$ git push -u origin master
$ cat .git/refs/remotes/origin/master
849d8fba50d841590e4f8cbb7fe3bf118b7b1fc9

Git repository snapshot:

  • 3 commits
  • 3 trees
  • 3 blobs
  • 4 refs: HEAD, refs/heads/master, refs/heads/feature, refs/remotes/origin/master

We continue local development by adding more commits, the HEAD is associated with the current master branch, and the master branch is referencing to the latest SHA1 commit. Also, we see that the current changes are not available at the remote repo, the only previous commit was pushed to the remote. The bigger picture of repository state with all Commit, Tree and Blob objects:

Git repository snapshot:

  • 4 commits
  • 4 trees
  • 4 blobs
  • 4 refs: HEAD, refs/heads/master, refs/heads/feature, refs/remotes/origin/master

Summary

Git repo is a DAG structure of Objects, branches (both local and remote) are a sliding labeled references to particular SHA1 commit in the repo. Overview of branching strategies as well as merging, rebasing, etc, I will do in the next articles.

This post is licensed under CC BY 4.0 by the author.