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

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.
Git reads the file content
It creates a blob object
It calculates a SHA hash for that content
The blob gets stored inside
.git/objectsThe 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.
It creates tree objects from the staged files
It creates a commit object
The commit points to the root tree
The commit points to the previous commit
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.



