How git works under the hood


  • The purpose of git is to manage a project or a set of files as they change over time

  • This information is stored in a data structure called a repository

  • A repository contains:

    • A set of commit objects
    • A set references to commit objects, also known as heads
  • The repository is stored in the same folder as the project itself, inside the .git folder

Commit Objects

  • A commit object contains:

    • A set of files, reflecting the state of the project in that point of time
    • Reference to a parent commit objects
    • An SHA1 name that uniquely identifies the commit object. Identical commits will always have the same hash value
  • There is always one commit object without a parent, the first commit of the project

  • You can visualize a repository as a directed acyclic graph of commmit objects

  • Git is all about performing some operation to query or manipulate this graph of commits


  • A head is a reference to a commit object
  • Every head has a name
  • By default every project has the master head
  • A project can have multiple heads, but one head is always the current head, aliased with HEAD


  • “branch” and “head” are often used interchangeably
  • Every branch is represented by one head
  • Sometimes branch is used to refer to the head and all history, while head solely refers to a single commit object

Common branching Use Patterns

  • A common way to develop is to maintain a main branch and create new branches for each new feature to add
  • In this case the master branch is always a releasable candidate

Git fork workflow (Reference)

  • Fork the repository, then clone the fork
$ git clone<fork>.git
  • Add original repository as upstream to be able to fetch latest updates
$ git remote add upstream<org>/<original-repo>.git

Adding a new feature

  1. Create and checkout a feature branch
  2. Make changes to the files
  3. Commit changes to the branch/fork
$ git checkout -b <new branch>
$ git push origin <new branch>

Then create a PR in the original repository.

Cleaning up

  • After the feature was merged, update the fork
$ git pull upstream master
  • Delete the feature branch, as not needed anymore
$ git branch -d <branch name>
  • Update the master branch of the fork
$ git push origin master
  • And also delete the feature branch in the remote repository
$ git push --delete origin <branch name>

Keeping fork in sync

  • Make sure to always have the most recent version in the fork, since forks do not update automatically!
git pull upstream master
git push origin master