# How Git Works Internally: A Conceptual Guide for Beginners

When I first started using Git, I only knew two commands.  
`git add` and `git commit`.

I typed them again and again without thinking.  
Honestly, I was scared to ask what happens inside Git.

One day, my code broke and I didn’t know why.  
Someone said, “Check how Git tracks changes.”

I felt lost.  
What does Git track?  
Where does it save my files?

I opened my project folder and saw a hidden folder called `.git`.  
I had seen it many times before but never touched it.

That day, I clicked it.

I did not understand everything at first.  
But slowly, things started to make sense.

In this blog, I will share how I understood Git internally.  
Not like a teacher.  
Like a student who was confused and learned step by step.

---

## WHAT IS GIT INTERNALLY?

Git is like a smart notebook for your code.

It does not save files like a normal folder.  
It saves **snapshots** of your work.

Every time you commit, Git takes a photo of your project.  
Not just one file.  
The full structure.

Git stores everything inside one place.  
That place is the **.git folder**.

If you understand this folder, Git becomes less scary.

---

## WHAT IS THE .git FOLDER?

The `.git` folder is the heart of Git.

When you run `git init`, this folder is created.  
Without it, Git cannot work.

Inside `.git`, Git stores:

* Your commits
    
* Your file history
    
* Your branches
    
* Everything needed to track changes
    

You should not edit files inside `.git`.  
But understanding it helps a lot.

Think of `.git` as Git’s brain.

---

## WHY MOST BEGINNERS GET CONFUSED

I made these mistakes too.

1. We think Git saves files like Google Drive
    
2. We think `git add` sends code to GitHub
    
3. We think commit means “upload”
    
4. We memorize commands without understanding meaning
    

Because of this, Git feels magical and confusing.

But Git is actually very logical.

---

## GIT OBJECTS (Blob, Tree, Commit) – IN SIMPLE WORDS

Git stores data as **objects**.

Do not worry about the name.  
Think of them like boxes.

### Blob

A blob stores **file content**.  
Only content, not file name.

If two files have same content, Git stores only one blob.

### Tree

A tree stores **folder structure**.  
It connects file names to blobs.

Like:

* This file name → this content
    

### Commit

A commit stores:

* One tree (project state)
    
* Message
    
* Time
    
* Parent commit
    

A commit is like a full snapshot of your project.

---

## SIMPLE REAL-LIFE ANALOGY

Imagine a school bag.

* Books are **blobs** (content)
    
* Bag arrangement is **tree** (structure)
    
* Daily photo of bag is **commit**
    

Git does not track changes line by line.  
It tracks **snapshots**.

This idea changed everything for me.

---

## Git Objects Explained with Real Examples

Git stores data as **objects** inside the `.git` folder.  
Each object is saved using a **hash**.

Let us see this step by step with a small example.

---

### Step 1: Create a File

```plaintext
echo "Hello Git" > file.txt
```

At this point:

* File exists in working directory
    
* Git is NOT tracking it yet
    

---

### Step 2: Add File to Git

```plaintext
git add file.txt
```

Now Git creates a **blob object**.

You can see it using:

```plaintext
git hash-object file.txt
```

Output will look like this:

```plaintext
557db03de997c86a4a028e1ebd3a1ceb225be238
```

This hash represents the **content** of the file.

This is a **Blob**

* Stores only file content
    
* No file name
    
* No folder info
    

---

### Step 3: Check Git Objects Folder

```plaintext
ls .git/objects
```

You will see folders like:

```plaintext
55
info
pack
```

Inside `55`:

```plaintext
ls .git/objects/55
```

```plaintext
7db03de997c86a4a028e1ebd3a1ceb225be238
```

Git splits the hash:

* First 2 characters → folder
    
* Remaining → file
    

---

### Step 4: Commit the File

```plaintext
git commit -m "Add file.txt"
```

Now Git creates:

* A **tree object**
    
* A **commit object**
    

---

### Step 5: View Tree Object

```plaintext
git cat-file -p HEAD^{tree}
```

Output example:

```plaintext
100644 blob 557db03de997c86a4a028e1ebd3a1ceb225be238    file.txt
```

This is a **Tree**

* Connects file name → blob
    
* Represents folder structure
    

---

### Step 6: View Commit Object

```plaintext
git cat-file -p HEAD
```

Output example:

```plaintext
tree a3f5c6d9e8b1c2f4d5e6a7b8c9d0e1f2a3b4c5d6
author Your Name <you@email.com>
committer Your Name <you@email.com>

Add file.txt
```

This is a **Commit**

* Points to a tree
    
* Has message, author, time
    
* Links to previous commit
    

---

## Simple Object Relationship (Mental Model)

```plaintext
Commit
  ↓
Tree
  ↓
Blob (file content)
```

Git does NOT store files directly.  
It stores **objects that point to each other**.

---

## Why This Matters for Beginners

* Git tracks **snapshots**, not just changes
    
* Same file content = same blob
    
* Commits are cheap and fast
    
* History is safe because of hashes
    

Once this clicks, Git commands feel logical.
