ApiaryActive
Try: pause · settings · learn · wipe
← Community / Reading Room
HG
coding · 5 min read

How Git Works Under the Hood

As developers, we've all been there - working on a project, making progress, and suddenly, disaster strikes. A file gets corrupted, or a team member's changes…

Understanding the Power of Version Control

As developers, we've all been there - working on a project, making progress, and suddenly, disaster strikes. A file gets corrupted, or a team member's changes break the build. The agony of losing hours or even days of work is a familiar one. It's in these moments that we turn to our trusty version control system, Git. But have you ever stopped to think about what's really happening under the hood? How does Git manage to keep track of our changes, and why is it so darn effective?

Git's power lies in its ability to provide a content-addressable filesystem, where files are stored and retrieved based on their content, rather than their name or location. This might seem like a trivial difference, but it's the key to Git's efficiency and flexibility. By storing files as blobs, and organizing them into trees, Git creates a directed acyclic graph (DAG) of commits that allows us to navigate and manage our codebase with ease. In this article, we'll delve into the inner workings of Git, exploring the mechanisms that make it tick, and why it's become an essential tool for developers and conservationists alike.

The Basics of Git

Before we dive into the nitty-gritty, let's cover the basics. Git is a distributed version control system, meaning that it's designed to work with multiple repositories, each with its own copy of the codebase. This allows developers to work on their own branches, without affecting the main codebase, until they're ready to merge their changes.

A Git repository consists of three main components:

  • .git: This is the hidden directory that contains all the metadata and history of the repository.
  • working directory: This is the directory where you actually work on your code.
  • index: This is a staging area that sits between the working directory and the Git repository.

The Content-Addressable Filesystem

At the heart of Git lies the content-addressable filesystem, which allows it to store and retrieve files based on their content, rather than their name or location. This is achieved through the use of blobs, which are essentially immutable binary files that represent the contents of a file.

When you create a new file in Git, it's first stored as a blob in the Git repository. Each blob is assigned a unique object ID, which is a 40-character hash of the blob's contents. This object ID serves as a kind of identifier for the blob, allowing Git to retrieve it later.

Here's an example of how this works:

$ git add file.txt
$ git ls-tree -r HEAD
100644 blob 1234567890abcdef file.txt

In this example, 1234567890abcdef is the object ID of the blob that represents file.txt.

Trees and Directories

Now that we have a way to store individual files as blobs, we need a way to organize them into directories. This is where trees come in. A tree is essentially a nested directory structure, with each node representing a directory or file.

When you commit a change in Git, it creates a new tree that represents the state of the repository at that point in time. This tree includes all the blobs that make up the files in the repository, as well as the relationships between them.

Here's an example of how this works:

$ tree
.
├── file1.txt
└── file2.txt

$ git add file1.txt
$ git add file2.txt
$ git commit -m "Initial commit"

$ git ls-tree -r HEAD
040000 tree 1234567890abcdef
100644 blob 9876543210fedcba file1.txt
100644 blob 5555555555555555 file2.txt

In this example, 1234567890abcdef is the object ID of the tree that represents the repository's directory structure.

Commits and the Directed Acyclic Graph (DAG)

Now that we have a way to store individual files as blobs, and organize them into directories as trees, we need a way to track changes over time. This is where commits come in.

A commit is essentially a snapshot of the repository at a particular point in time, including all the trees and blobs that make up the repository at that point. Each commit is assigned a unique commit ID, which is a 40-character hash of the commit's contents.

When you make a change to the repository, Git creates a new commit that represents the updated state of the repository. This new commit is then added to the DAG of commits, which forms the history of the repository.

Here's an example of how this works:

$ git add file3.txt
$ git commit -m "New file added"

$ git log --oneline
1234567890abcdef (HEAD -> master) New file added
9876543210fedcba (master) Initial commit

In this example, 1234567890abcdef is the commit ID of the new commit that represents the updated repository.

Branches and Merging

One of the most powerful features of Git is the ability to create and manage branches. A branch is essentially a separate line of development that allows you to work on new features or bug fixes without affecting the main codebase.

When you create a new branch in Git, it creates a new copy of the repository's history, with all the commits up to that point. This new branch is then modified independently of the main branch, allowing you to make changes without affecting the main codebase.

Here's an example of how this works:

$ git branch feature/new-feature
$ git checkout feature/new-feature
$ git add file4.txt
$ git commit -m "New file added"

$ git log --oneline
1234567890abcdef (feature/new-feature) New file added
9876543210fedcba (feature/new-feature) Initial commit

In this example, feature/new-feature is a new branch that represents a separate line of development.

Why it Matters

So, why should you care about the inner workings of Git? The answer lies in its flexibility and power. By understanding how Git stores and retrieves files, and how it tracks changes over time, you can use Git to its full potential.

For developers, this means being able to work on complex projects with ease, and collaborate with others in a seamless way. For conservationists, it means being able to track changes in ecosystems over time, and make informed decisions about how to protect and preserve them.

In the words of Linus Torvalds, the creator of Git, "Git is a tool for the people, by the people." By understanding how Git works under the hood, you can become a part of that community, and use this powerful tool to make a real difference in the world.

Conclusion

In this article, we've explored the inner workings of Git, from the content-addressable filesystem to the directed acyclic graph of commits. We've seen how Git stores and retrieves files, and how it tracks changes over time. We've also seen how Git allows us to create and manage branches, and how it enables collaboration and flexibility.

As we continue to push the boundaries of what's possible with Git, it's essential that we understand the mechanisms that make it tick. By doing so, we can harness its power to make a real difference in the world.

Frequently asked
What is How Git Works Under the Hood about?
As developers, we've all been there - working on a project, making progress, and suddenly, disaster strikes. A file gets corrupted, or a team member's changes…
What should you know about the Content-Addressable Filesystem?
At the heart of Git lies the content-addressable filesystem, which allows it to store and retrieve files based on their content, rather than their name or location. This is achieved through the use of blobs , which are essentially immutable binary files that represent the contents of a file.
What should you know about trees and Directories?
Now that we have a way to store individual files as blobs, we need a way to organize them into directories. This is where trees come in. A tree is essentially a nested directory structure, with each node representing a directory or file.
What should you know about commits and the Directed Acyclic Graph (DAG)?
Now that we have a way to store individual files as blobs, and organize them into directories as trees, we need a way to track changes over time. This is where commits come in.
What should you know about branches and Merging?
One of the most powerful features of Git is the ability to create and manage branches. A branch is essentially a separate line of development that allows you to work on new features or bug fixes without affecting the main codebase.
References & sources
  1. Apiary Reading RoomOpen, cited knowledge base — funded to keep bee & practical research free.
From the Apiary Reading Room. Opinion & editorial — not financial advice. We don't overclaim.
More from the Reading Room