DEV Community

Cover image for Inside Git: How It Works and the Role of the .git Folder
Anoop Rajoriya
Anoop Rajoriya

Posted on

Inside Git: How It Works and the Role of the .git Folder

For many developers, Git feels like a magical incantation. We type git add . followed by git commit -m "fixed stuff", push it to a remote server, and hope for the best. When it works, it’s fantastic. When it breaks, it feels like trying to defuse a bomb while blindfolded.

The key to moving from blind memorization to true mastery lies in understanding what happens beneath the surface. Git isn't just a list of commands; it is a beautifully designed system for managing information. By peeling back the layers, we can build a mental model of how Git actually "thinks."

Our journey begins at the hidden heart of your repository: the .git folder.


How Git Works Internally

Before diving into the folder structure, we need to correct a common misconception. Many people believe Git stores data as a diff—a series of changes recording only which lines were added or removed.

Git doesn't do this. Instead, Git thinks in snapshots.

Every time you commit, Git takes a "picture" of what all your files look like at that exact moment and stores a reference to that snapshot. To stay efficient, if a file hasn't changed, Git doesn't store the file again; it simply links back to the previous, identical version it already has.


Understanding the .git Folder

If you open your project folder in a file explorer, you might not see it at first. It’s usually hidden because it is crucial that you do not manually mess with its contents.

The .git Folder is your repository.

Everything outside of this folder is just your "working directory"—the temporary sandbox where you edit your current files. The .git folder is the database where Git stores every version of every file, the entire commit history, and all your branches.

Important Note: If you delete the .git folder, you lose your project's entire history, leaving only the "current" version of the files you see on your screen.

While there are many files inside, these three are the most critical for understanding internals:

  • objects/: The heart of the database. It stores all the content of your files and your history.
  • refs/: This directory stores pointers (references) into the object data, such as branches (heads) and tags.
  • HEAD: A simple text file that tells Git which branch you are currently working on.

The Big Three: Blobs, Trees, and Commits

Git is essentially a key-value data store. You put data in, and Git gives you a unique key to retrieve it later.

The key is a Hash—a 40-character string (SHA-1) generated based on the content. If the content changes even slightly, the hash changes completely. This ensures data integrity: if the hash is the same, you can trust the data is unchanged.

Git stores three main types of objects in the objects/ folder:

1. The Blob (Binary Large Object)

A Blob is the simplest object; it just stores the content of a file. Crucially, a Blob does not know the file's name or where it lives in your project. It only knows the raw data.

Pro-tip: If you have two different files (README.md and intro.txt) that both contain the exact text "Hello World," Git only stores one Blob.

2. The Tree

If Blobs store content, Trees store structure. A Tree object acts like a directory. It contains a list of entries pointing to:

  • Blobs (files) along with their filenames.
  • Other Trees (subdirectories).

3. The Commit

The Commit object is the wrapper that ties everything into a snapshot in time. It contains:

  • A pointer to the top-level Tree (the project root).
  • Metadata: Author, timestamp, and the commit message.
  • A pointer to the Parent Commit (the snapshot that came before it).

How Git Tracks Changes (The 3-Step Flow)

Understanding these objects unlocks the mystery of the "Staging Area." Let’s track what happens when you save a new file to history.

Step 1: The Working Directory

You create style.css. Right now, this file only exists in your working directory. Git’s database doesn't know it exists yet.

Step 2: The Staging Area (git add)

When you run git add style.css, Git:

  1. Compresses the content into a Blob.
  2. Calculates the hash and stores it in .git/objects.
  3. Updates the Index (the staging area), noting that for the next snapshot, style.css should point to that specific Blob hash.

Step 3: The Commit (git commit)

When you run git commit -m "Added Styles", Git freezes the stage:

  1. It creates a Tree object to represent the directory structure.
  2. It creates a Commit object pointing to that Tree and the previous commit.
  3. It moves your current Branch pointer (e.g., main) to this new commit hash.

👉 Follow, Like & Share if this helped you to understand Git internals


Top comments (0)