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
5 min read
Inside Git: How It Works and the Role of the .git Folder

For the first year of my coding life (okay, maybe two), my relationship with Git was basically superstition.

I had memorized a sacred chant. Every time I finished some code, I would open the terminal and robotically type:

git add .
git commit -m "please work"
git push origin main

If it worked, great. If I got an error... panic mode activated. I’d start Googling weird commands, copy-pasting solutions I didn't understand, and basically praying that I didn't delete the entire codebase.

Today, we are going to break open that black box. No more magic. We are going to dive into that mysterious hidden folder that sits in your project root - the .git folder and understand how Git actually works.

Grab a chai, because we are going deep.

The Golden Rule of Git: Your entire project history, every version of every file, every branch, every commit tag—it all lives inside this .git folder. Delete this folder, and your project is no longer a git repository.

The .git folder structure

Let’s peek inside a typical .git folder:

.git/
|-- HEAD         (Points to current branch)
|-- config       (Your local settings)
|-- index        (The STAGING AREA - very important!)
|-- objects/     (THE DATABASE - Where the real magic is)
|-- refs/        (Pointers to branches and tags)

Let’s decode this:

  1. objects/ – The Actual Database

    This is where Git stores:

    • Your files

    • Your folders

    • Your commits

Everything is stored as objects.

No objects = no Git.

  1. refs/ – Bookmarks

    This folder stores pointers like:

    • main

    • feature/login

    • HEAD

  1. HEAD – Where You Are Right Now

    HEAD is Git saying:

    “Tu abhi yahan khada hai”

    Usually it points to: refs/heads/main

  2. index – The Staging Area

    This is very important.

    The index is: “What will go into the next commit”

    Not committed.
    Not working directory.
    In between.

    It is like: “Shaadi pakki hai, date fix nahi hui” 😄

The Building Blocks: Git Objects

Git has only 3 real object types.

Blob – File Content:

A blob is just the raw contents of a file. If you have two files named readme.md and intro.txt, and they both contain the exact text "Hello World", Git will only store one blob. Why store the same data twice?

A blob stores:

  • File content only

  • No filename

  • No path

Same content = same blob
Different content = different blob

Even if the filename changes, blob doesn’t care.

Tree – Folder Structure

If blobs are the files, Trees are the directories (folders).

A Tree object is a list that maps filenames to blobs (or to other sub-trees). It gives structure to the piles of data. A simple Tree object might look something like this internally:

100644 blob a906cb2a4a906cb2a4a906cb2a4  index.html

100644 blob 8f08d23b8f08d23b8f08d23b8f0  styles.css

040000 tree 9c17e34d9c17e34d9c17e34d9c1  images/

A tree stores:

  • Filenames

  • Folder structure

  • References to blobs and other trees

Commit – Snapshot with Metadata

A commit is a snapshot of our project at a specific point in time. It usually contains just four things:

  1. A pointer to the main Tree (the root folder of your project at that moment).

  2. A pointer to the Parent Commit (the commit that came immediately before this one).

  3. Author/Committer information (who did it and when).

  4. The commit message ("Fixed the nav bar for the 10th time").

Relationship Between Them

Commit
  |
  v
 Tree
 ├── Blob (file1)
 ├── Blob (file2)
 └── Tree (subfolder)
       └── Blob (file3)

The Mental Model So Far

Let's visualize how these three connect.

How Git Tracks Changes `git add and git commit`

Git does NOT track changes line-by-line.

Git tracks: Snapshots of the entire project

But smartly, if a file didn’t change:

  • Git reuses the same blob

  • No duplication

Let’s understand this with examples:

Scenario: You create a new file named meme.txt containing the text "Much wow".

At this point, Git knows nothing about this file. It's "untracked".

Step 1: git add meme.txt

When you hit enter, Git does two things under the hood:

  1. It takes the content ("Much wow"), calculates its hash, and creates a Blob object in the .git/objects folder.

  2. It updates the Index (staging area). It adds a line to the index saying, "Hey, the file meme.txt currently matches that new blob hash."

Step 2: git commit -m "Added a solid meme"

When you run commit:

  1. Git looks at the Index (the waiting room). It sees exactly what the project should look like right now.

  2. It creates Tree objects that represent that structure.

  3. It creates a Commit object. This commit points to the newly created main Tree. It also points to the previous commit (its parent) so you have a history chain.

  4. Finally, Git updates your current branch name (like main or master) to point to this new commit hash.

So next time you type git commit, take a second to analyze how files are being created/updated inside that hidden .git folder.

Hashes: Git’s Superpower

Everything in Git is identified by a SHA-1 hash (40 characters).

Example:

e83c5163316f89bfbde7d9ab23ca2e25604af290

This hash depends on:

  • Content

  • Metadata

Change even one character, hash changes.

Benefits:

  • Data integrity

  • No corruption

  • No duplicates

  • History cannot be silently changed

Indian logic:

“Ek bhi paisa idhar-udhar hua, pakda jaayega” 😄

If this blog made Git feel less scary and more logical, mission accomplished.

Now go open .git/ once.
Fear will be replaced by respect. 💪😄