# How Git Works: A Deep Dive into the .git Directory

## Introduction: Understanding Git Beyond Commands

Most developers learn Git by memorizing commands like `git add`, `git commit`, and `git push`. However, Git is much more than a command-line tool — it is a powerful content tracking system that stores snapshots of your project efficiently and securely. To truly understand Git, we must explore what happens internally, especially inside the hidden `.git` folder. Instead of memorizing commands, building a mental model of how Git works makes everything clearer and more logical.

---

## How Git Works Internally

![https://media.licdn.com/dms/image/v2/D5612AQGVL-BRQ1YBEw/article-cover_image-shrink_720_1280/article-cover_image-shrink_720_1280/0/1719414907801?e=2147483647&t=QJ2wXmAZXWHkLjiWAWbilI8mdcSiKEgnzAw5Wx_wZTc&v=beta](https://media.licdn.com/dms/image/v2/D5612AQGVL-BRQ1YBEw/article-cover_image-shrink_720_1280/article-cover_image-shrink_720_1280/0/1719414907801?e=2147483647&t=QJ2wXmAZXWHkLjiWAWbilI8mdcSiKEgnzAw5Wx_wZTc&v=beta align="left")

![https://cdn.prod.website-files.com/5ed2ed8ea90a9c03bf1b5a18/613251677413b8c03d79ddac_upS1_fd17QlxeKZ8oc9kmkM6fcHBOqX8_YjfZpjju-zkrZ-loZjsffcDkgFwd-hBgOHTxgellTfX3BCr9KZbi-iY5FHhNydM7qWRhlr1AwtgWZRgvorWMNH7NOg9Ms9EbAjCrCao%3Ds0.png](https://cdn.prod.website-files.com/5ed2ed8ea90a9c03bf1b5a18/613251677413b8c03d79ddac_upS1_fd17QlxeKZ8oc9kmkM6fcHBOqX8_YjfZpjju-zkrZ-loZjsffcDkgFwd-hBgOHTxgellTfX3BCr9KZbi-iY5FHhNydM7qWRhlr1AwtgWZRgvorWMNH7NOg9Ms9EbAjCrCao%3Ds0.png align="left")

![https://miro.medium.com/1%2AdiRLm1S5hkVoh5qeArND0Q.png](https://miro.medium.com/1%2AdiRLm1S5hkVoh5qeArND0Q.png align="left")

4

Git works by storing **snapshots of your project**, not just the differences between files. Every time you commit, Git saves the current state of your project. It does this efficiently by storing only new or changed content while reusing existing data whenever possible. Internally, Git manages three main areas: the working directory (where you edit files), the staging area (where changes are prepared), and the repository (inside the `.git` folder). When you modify a file, it changes in your working directory. When you run `git add`, Git moves that change into the staging area. When you run `git commit`, Git permanently stores a snapshot inside the `.git` folder.

Git also uses a special hashing algorithm called **SHA-1** to generate a unique fingerprint for every piece of data it stores. If even one character changes in a file, the hash changes completely. This ensures data integrity and makes Git extremely reliable.

---

## Understanding the `.git` Folder

![https://humbletoolsmith.com/img/posts/a-look-inside-the-_git-folder/Git%20Folder%20Internals.png](https://humbletoolsmith.com/img/posts/a-look-inside-the-_git-folder/Git%20Folder%20Internals.png align="left")

![https://git-scm.com/book/en/v2/images/data-model-3.png](https://git-scm.com/book/en/v2/images/data-model-3.png align="left")

![https://media.licdn.com/dms/image/v2/D5612AQGq9qEQB2EpOw/article-cover_image-shrink_720_1280/article-cover_image-shrink_720_1280/0/1683085594035?e=2147483647&t=ivAAPzrWdZOGvcxwZwTRAu552dpbE1SpkE85NAi0OXA&v=beta](https://media.licdn.com/dms/image/v2/D5612AQGq9qEQB2EpOw/article-cover_image-shrink_720_1280/article-cover_image-shrink_720_1280/0/1683085594035?e=2147483647&t=ivAAPzrWdZOGvcxwZwTRAu552dpbE1SpkE85NAi0OXA&v=beta align="left")

When you run `git init`, Git creates a hidden folder named `.git`. This folder is the heart of your repository. It contains everything Git needs to track your project history. If you delete the `.git` folder, you lose all version history because that folder stores all commits, branches, and metadata.

Inside the `.git` folder, Git maintains several important components. The `objects` directory stores all Git objects such as file contents and commits. The `refs` directory keeps track of branch references. The `HEAD` file points to the current branch you are working on. The `index` file represents the staging area, and the `config` file stores repository-specific settings. In simple terms, the `.git` folder acts like a private database that manages your project’s entire history.

---

## Git Objects: Blob, Tree, and Commit

![https://miro.medium.com/1%2AOTYINUfVcSmrmd2U6G914Q.png](https://miro.medium.com/1%2AOTYINUfVcSmrmd2U6G914Q.png align="left")

![https://thoughtbot-images.s3.amazonaws.com/upcase/git-course/git-base-object-model.png](https://thoughtbot-images.s3.amazonaws.com/upcase/git-course/git-base-object-model.png align="left")

![https://shafiul.github.io/gitbook/assets/images/figure/objects-example.png](https://shafiul.github.io/gitbook/assets/images/figure/objects-example.png align="left")

Git stores data in the form of objects, and there are three main types: **Blob, Tree, and Commit**. A blob (Binary Large Object) stores the actual content of a file. It does not store the file name — only the content. If you modify a file, Git creates a new blob with a new hash. A tree object represents the directory structure and connects file names to their corresponding blobs. It acts like a folder that organizes files. A commit object links everything together. It stores a reference to a tree, author information, commit message, timestamp, and a reference to the previous commit. This structure creates a chain of commits that forms your project history. The relationship can be understood as: Commit points to Tree, and Tree points to Blobs.

---

## What Happens During `git add` and `git commit`

![https://i.sstatic.net/F2H1Q.png](https://images.openai.com/thumbnails/url/OjM4Nnicu5meUVJSUGylr5-al1xUWVCSmqJbkpRnoJdeXJJYkpmsl5yfq5-Zm5ieWmxfaAuUsXL0S7F0Tw50NguNdDJLy44vLnZJy_HKs9AtjSwPSivNNXbRLXd0tTR38ikKc03ONQxxVCu2NTQAAASgJHw align="left")

![https://miro.medium.com/1%2AdiRLm1S5hkVoh5qeArND0Q.png](https://miro.medium.com/1%2AdiRLm1S5hkVoh5qeArND0Q.png align="left")

![https://i.sstatic.net/YxFVH.png](https://images.openai.com/static-rsc-1/gOflqsX0Txgq3EUDUJ2ut2bzi6_jNWuVb2R5-szh8GI5nBi4t3jkMfOP6W5qKs6xwQOZ8-wOEH2hVeTBP4FmKrmLIKWigvqP_T81Btp91C6mqZNov6Fx55elmOVrb-4mpFHQlnXcbDddgVk15-e5MQ align="left")

When you run `git add`, Git reads the file from your working directory and creates a blob object from its content. It then generates a SHA-1 hash and stores the blob inside the `.git/objects` folder. The staging area (index) is updated to track this prepared snapshot. At this stage, changes are ready but not permanently recorded in history.

When you run `git commit`, Git creates a tree object representing the current directory structure from the staged files. It then creates a commit object that points to this tree and links it to the previous commit. Finally, Git updates the `HEAD` pointer to reference the new commit. This process creates a new snapshot in your project history.

---

## How Git Tracks Changes Using Hashes

Git tracks changes by generating unique hashes based on file content. Each blob, tree, and commit has its own SHA-1 hash. Because the hash is generated from the content itself, any change in content produces a completely different hash. This makes Git a **content-addressable system**. It ensures that data cannot be altered without detection, and it prevents corruption or duplication. Every version of your project is uniquely identified and securely stored.
