Skip to main content

Command Palette

Search for a command to run...

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

Updated
โ€ข6 min read
Inside Git: How It Works and the Role of the .git Folder
S
Professional coder. Occasional bug creator ๐Ÿ˜Ž

When most developers start using Git they mostly learn commands.
git add, git commit, git push, git pull.

At first Git feels like magic. You type a command and somehow your project history gets saved.

But have you ever wondered what actually happens inside Git when you run those commands?

What is that mysterious .git folder that suddenly appears in your project?

In this article we will open that black box and look inside Git in a very simple and friendly way. Even if you are new to coding you will be able to understand how Git works internally and why it is designed the way it is.


First Things First: What is the .git Folder?

When you run this command inside a project:

git init

Git creates a hidden folder called .git.

This folder is the heart of Git.

Everything Git needs to track your project lives inside this folder. Your commits, your branches, your history and all the internal data structures are stored there.

Your project folder might look like this:

my-project/
 โ”œโ”€โ”€ index.html
 โ”œโ”€โ”€ style.css
 โ”œโ”€โ”€ app.js
 โ””โ”€โ”€ .git/

Your actual project files are outside the .git folder. The .git folder stores metadata about them.

If you delete the .git folder the project files will still exist but Git will completely forget the history of your project.

That means no commits, no branches, no version control. Just normal files.

So the .git folder is basically Git's brain.


A Quick Look Inside the .git Folder

If you open the .git folder you will see something like this:

.git/
 โ”œโ”€โ”€ objects/
 โ”œโ”€โ”€ refs/
 โ”œโ”€โ”€ HEAD
 โ”œโ”€โ”€ config
 โ””โ”€โ”€ index

Let's understand these in simple terms.

objects/
This is where Git stores all the data of your project. Every file, commit and folder structure eventually becomes a Git object and lives here.

refs/
This stores references to commits.

HEAD
HEAD tells Git which branch you are currently on.

config
This stores repository level configuration.

index
This is the staging area. It temporarily stores changes before they become a commit.

If you remember just one thing from this section remember this.

Git does not store files the way normal systems do. Instead it stores objects.


Git's Secret Weapon: Objects

Internally Git works using objects. There are three main ones you should know.

  • Blob

  • Tree

  • Commit

These objects form the entire history of your project.


Blob: The File Content

A blob represents the contents of a file.

Suppose you have a file:

hello.txt

with this content inside that file:

Hello world

Git stores this content as a blob object.

Important detail - The blob stores only the file content not the filename.

That means if two files have the exact same content Git stores them only once.

Pretty efficient right?


Tree: The Folder Structure

A tree object represents a directory.

It connects filenames to blobs and other trees.

Think of it like this:

project/
 โ”œโ”€โ”€ index.html
 โ”œโ”€โ”€ style.css
 โ””โ”€โ”€ src/
     โ””โ”€โ”€ app.js

Git creates a tree for the project folder and another tree for the src folder.

The tree points to blobs and other trees.

So a tree is basically a map of the project structure.


Commit: The Snapshot of Your Project

A commit is what most developers are familiar with.

But internally a commit is just a pointer to a tree plus some metadata.

A commit contains:

  • A reference to the root tree

  • The author

  • The commit message

  • A reference to the previous commit

This creates a chain of commits.

Commit C
   โ†“
Commit B
   โ†“
Commit A

That chain is your project history.


Relationship Between Commits Trees and Blobs

You can imagine the relationship like this:

Commit
  โ†“
Tree (project structure)
  โ†“
Blobs (file contents)

Commit points to a tree.
Tree points to blobs and other trees.

This is how Git reconstructs the entire project for any commit.


What Happens During git add

Now let's see what actually happens when you run:

git add app.js

Internally Git does a few interesting things.

  1. Git reads the file content

  2. It creates a blob object

  3. It calculates a SHA hash for that content

  4. The blob gets stored inside .git/objects

  5. The staging area index gets updated

The important part here is the hash.

Git calculates a unique SHA-1 hash based on the file content.

Example:

3b18e8c1f4d3...

If the file content changes the hash also changes.

So Git can instantly detect whether something has changed.


What Happens During git commit

Now when you run:

git commit -m "add login feature"

Git does the following internally.

  1. It creates tree objects from the staged files

  2. It creates a commit object

  3. The commit points to the root tree

  4. The commit points to the previous commit

  5. The branch reference updates to the new commit

So a commit is basically Git saying:

"Here is a snapshot of the project at this moment."


How Git Tracks Changes

One important thing to understand is this.

Git does not store differences between files.

Instead Git stores snapshots of the project.

But it is smart about it.

If a file has not changed Git simply reuses the previous blob instead of storing it again.

So commits stay lightweight.

This design makes operations like branching and merging very fast.


Why Git Uses Hashes

Every Git object is identified by a cryptographic hash.

Example:

e83c5163316f89bfbde7d9ab23ca2e25604af290

This hash depends entirely on the object's content.

If even one character changes the hash changes completely.

This gives Git a powerful property.

It guarantees data integrity.

If any object gets corrupted Git will know immediately because the hash will not match.

This is one reason why Git is extremely reliable.


Building a Mental Model of Git

Instead of memorizing commands try to imagine Git like this.

Git is basically:

A database of objects stored in the .git folder.

Each commit points to a snapshot of the project.

Files become blobs.
Folders become trees.
Snapshots become commits.

Branches are just pointers to commits.

Once you understand this mental model Git commands start making much more sense.



At first Git looks complicated because we only interact with commands. But internally the design is actually very elegant.

Everything is built around a simple idea.

Store content as objects and connect them using hashes.

The .git folder is where this entire system lives quietly inside your project.

The next time you run git commit remember that Git is not just saving your code. It is creating a structured history of your entire project.

And all of it starts with that small hidden .git folder.