# Inside Git: How It Works Internally

Git is the backbone of modern software development. If you’ve ever pushed code to GitHub, cloned a repository, or merged branches, you’ve used Git. But have you ever wondered:

> *“What’s really happening inside the* `.git` folder?”  
> *“How does Git remember all my changes?”*

Most tutorials teach **commands** like `git add`, `git commit`, or `git push`. But without understanding **how Git works internally**, you end up memorizing commands like a robot — not actually knowing what’s happening.

In this blog, we’re going to **open the hood of Git**, explore its **internal structure**, and understand concepts like **blobs, trees, and commits** in **simple, human language**. By the end, you’ll have a mental model of Git that makes working with it intuitive.

## What Happens When You Use Git?

Let’s start with a simple mental picture:

Git is like a **smart notebook** that keeps track of every change in your project. Unlike a normal notebook:

* Git doesn’t store every version of your files separately.
    
* It stores **snapshots of content**.
    
* Every snapshot is connected and verifiable.
    

Imagine writing a story. Each paragraph change is saved as a **snapshot**, and Git remembers **who changed what and when**. But instead of writing your name, Git uses **hashes** (unique IDs) to ensure nothing gets lost or tampered with.

## The .git Folder: Git’s Brain

The `.git` folder is like Git’s **brain**. Every repository you initialize (`git init`) contains this hidden folder.

### What’s inside `.git`?

* **objects/** → Where blobs, trees, and commits live
    
* **refs/** → Pointers to branches and tags
    
* **HEAD** → Which commit your working directory is currently on
    
* **index** → The staging area (before committing)
    
* **config** → Repository-specific settings
    

Think of `.git` as a **well-organized filing cabinet**. Everything your repository does adding files, committing changes, switching branches interacts with this folder.

## Git Objects: Blobs, Trees, and Commits

Git stores your project as **objects**. There are three main types:

1. **Blob (Binary Large Object)**
    
    * Stores the **contents of a file**, nothing else.
        
    * Git uses **SHA-1 hashes** as IDs to track content uniquely.
        
    
    Example:
    
    ```plaintext
    File: index.html
    Content: <h1>Hello World</h1>
    Blob ID: 3a4f5d7...
    ```
    
2. **Tree**
    
    * Stores **directory information**, pointing to blobs or other trees.
        
    * Keeps track of **file names and folder structure**.
        
    
    Example:
    
    ```plaintext
    Tree: src/
      index.html -> blob 3a4f5d7...
      style.css -> blob 5b6c7d8...
    ```
    
3. **Commit**
    
    * A **snapshot of the project** at a point in time.
        
    * Points to a tree, has a parent commit, an author, and a message.
        
    
    Example:
    
    ```plaintext
    Commit: 7f8e9d1
    Tree: 2a3b4c5
    Parent: 5d6e7f8
    Author: Chandni Kumari
    Message: Initial commit
    ```
    

### Analogy

* **Blob:** A single file
    
* **Tree:** A folder containing files or other folders
    
* **Commit:** A photo of the entire project at a given moment
    

## How Git Tracks Changes Internally

Let’s see what happens **when you add and commit a file**.

---

1. ### git add
    

`git add` moves your changes to the **staging area** (index). Internally:

1. Git calculates a **hash** of the file content.
    
2. Git creates a **blob object** (if it’s new).
    
3. Git updates the **index** to point to this blob.
    

Example:

```plaintext
git add index.html
```

Internally:

```plaintext
Blob created: 3a4f5d7...
Index updated: index.html -> blob 3a4f5d7...
```

2. ### git commit
    
    `git commit` takes the **staged changes** and creates a **commit object**.
    
    Internally:
    
    1. Git builds a **tree object** from staged files.
        
    2. Git creates a **commit object** pointing to that tree.
        
    3. Git updates **HEAD** to the new commit.
        
    
    Example:
    
    ```plaintext
    git commit -m "Add homepage"
    ```
    
    Internally:
    
    ```plaintext
    Tree created: 2a3b4c5
    Commit created: 7f8e9d1 -> Tree 2a3b4c5
    HEAD updated: points to 7f8e9d1
    ```
    

## How Git Uses Hashes

Git doesn’t trust file names. It trusts **content hashes**.

* Every blob, tree, and commit has a **SHA-1 hash**.
    
* Hash = unique fingerprint of content.
    
* Any change in content → new hash → new object.
    

This is why Git can **track changes perfectly** and **ensure integrity**.

## Visualizing Git Objects and Relationships

```plaintext
Commit 7f8e9d1
  |
  -> Tree 2a3b4c5
       |
       -> Blob 3a4f5d7 (index.html)
       -> Blob 5b6c7d8 (style.css)
```

Explanation:

* Commit points to the tree
    
* Tree points to blobs (files)
    
* Blob stores file content
    

## Internal Flow: git add → git commit

```plaintext
Working Directory
   |
   | git add
   v
Staging Area (Index)
   |
   | git commit
   v
.git/objects (Blobs, Trees, Commits)
```

**Key idea:**

* `git add` = prepare your snapshot
    
* `git commit` = take the snapshot and record it in the `.git` folder
    

## Understanding Git Internals with Commands

* View commit hash:
    

```plaintext
git log --oneline
```

* Check object type:
    

```plaintext
git cat-file -t <hash>
# blob, tree, commit
```

* View content:
    

```plaintext
git cat-file -p <hash>
```

## Mental Model for Git

Think of Git as **a secure digital time machine**:

1. **Blob:** Captures file content
    
2. **Tree:** Captures folder structure
    
3. **Commit:** Captures the project snapshot
    
4. **Hashes:** Ensure nothing is lost or tampered with
    
5. **.git folder:** Stores everything
    

Once you visualize Git like this, commands become **intuitive**, not just memorized.

## The .git Directory Structure

```plaintext
.git/
├── objects/        # blobs, trees, commits
├── refs/           # branches and tags
├── HEAD            # current commit pointer
├── index           # staging area
├── config          # repo settings
└── logs/           # history of HEAD changes
```

## Why Understanding Git Internals Helps

* Debug broken repositories
    
* Resolve merge conflicts intelligently
    
* Understand branch history
    
* Confidently use `rebase` and `cherry-pick`
    
* Impress your teammates with Git mastery 😎
    

---

## 💡 Example Scenario

You add a new file:

```plaintext
echo "Hello Git" > file.txt
git add file.txt
git commit -m "Add greeting file"
```

**Internally:**

1. Blob created for `file.txt`
    
2. Tree updated to include blob
    
3. Commit object created pointing to tree
    
4. HEAD updated
    

Git now has a **safe snapshot** of our work.

## Conclusion

Git is **more than a version control system** . it’s **a smart content tracker**. By understanding:

* `.git` folder
    
* Blobs, Trees, Commits
    
* Internal hash system
    

you move from **memorizing commands** → **truly understanding Git**.
