What's Inside the .git Folder?
Source: Dev.to
Introduction
In this article we’ll open the hood and look at the engine that powers Git – the .git folder.
By the end of the article you’ll understand:
- How Git stores files and tracks history internally.
- How commits are built under the hood.
Before we dive into the hexadecimal rabbit hole, make sure you’re comfortable with:
- Basic Git commands –
git add,git commit,git push. - The command line – navigating with
cd, listing withls, etc. - Curiosity – a willingness to explore abstract concepts.
New to Git?
If you need a refresher on the basics, check out:
- Learn Git Easily: A Beginner’s Guide to Version Control
The .git Folder
If you open any Git repository on your computer and enable “show hidden files”, you’ll see a folder named .git.
- It isn’t just a config folder – it’s a database.
- It is the brain, heart, and soul of your repository.
- Deleting the project files but keeping the
.gitfolder lets you restore everything. - Deleting the
.gitfolder turns the repo into a plain folder of text files, and all history is lost.
Git is essentially a content‑addressable filesystem – a fancy way of saying it’s a key‑value store.
Core Git Objects
| Object | What it stores | How it’s used |
|---|---|---|
| Blob | Raw file content (e.g., main.ts). Git compresses the content and stores it as a blob. | Holds the data but has no filename. |
| Tree | Directory structure. Maps filenames (e.g., main.ts) to blob IDs and can contain other trees (sub‑directories). | Reconstructs the folder hierarchy. |
| Commit | A snapshot of the repository at a point in time. Contains a pointer to a tree, metadata (author, date, message), and a pointer to the parent commit(s). | Ties everything together; forms the history chain. |
In simple terms
- Blob – the file data.
- Tree – the folder organization.
- Commit – the snapshot (who, when, why).
SHA‑1 (and SHA‑256) Hashes
You’ve likely seen long strings like a1b2c3d…. Those are SHA‑1 hashes – 40‑character IDs generated by applying a mathematical formula to the object’s content.
- SHA = Secure Hash Algorithm.
- Newer Git versions also support SHA‑256, but SHA‑1 remains the default because the ecosystem (GitHub, GitLab, tools) still relies on it.
Check the hash algorithm used by a repository
git rev-parse --show-object-format
# Output: sha1 (or sha256)
rev-parse– a plumbing command that resolves and parses Git references.--show-object-format– displays the object hash format used by the repository.
From Your Editor to the Repository
Step 1 – git add .
What happens:
- Git reads the content of each modified file.
- It creates blob objects for the contents and stores them in
.git/objects. - It updates the index (staging area) – a list that says “for the next commit, this filename points to this blob hash”.
Step 2 – git commit -m "Message"
What happens:
- Tree creation – Git walks the index and builds tree objects that represent the current folder structure.
- Commit creation – A commit object is created, pointing to the top‑level tree and to the previous commit (its parent).
- HEAD update – The
HEADpointer (your current branch label) is moved to the new commit ID.
Integrity Magic
- The hash of a file (e.g.,
"Hello World") is always the same. - Changing the content (e.g.,
"Hello Worlds") produces a completely different hash. - Git hashes not only the content, but also the object type and size, guaranteeing uniqueness and integrity.
Because each commit stores the hash of its parent, the entire history forms a cryptographic chain – tampering with any object would break the chain.
The HEAD File
HEAD is a tiny text file that tells Git where you are currently working. Typical content:
ref: refs/heads/main
- This means “we are on the
mainbranch”. - Running
git checkout dark-modesimply updatesHEADtoref: refs/heads/dark-mode.
Inside the .git Directory
| Directory / File | Purpose |
|---|---|
| objects/ | Stores every Git object (blobs, trees, commits, tags) named by their SHA‑1 hash. |
| refs/ | The catalog of bookmarks – branches and tags. |
| refs/heads/ | Files for each branch (e.g., feature-login). Each file contains a 40‑character commit hash. |
| HEAD | Points to the current branch (or directly to a commit in detached HEAD state). |
| index | The binary staging area. Updated by git add; holds timestamps, filenames, and blob hashes ready for the next commit. |
Inspecting an object
Objects are stored as compressed binaries, so open them with git cat-file:
git cat-file -p <object-id>
# -p = pretty‑print (human‑readable)
Example output of a commit object
tree 8d3a1...
parent 1f4e2...
author Satpal Rana 1703865000 +0000
Created the homepage hero section
Summary
- The
.gitfolder is a full‑featured database that holds blobs, trees, commits, and references. - Git’s content‑addressable storage uses SHA‑1 (or optionally SHA‑256) hashes to guarantee integrity.
- Adding files creates blobs and updates the index; committing builds trees and a commit object, then moves HEAD.
- Branches are lightweight pointers to commit hashes, making them fast to create and switch.
Now you have a clear view of what happens under the hood every time you run a Git command. Happy exploring!
Hands‑On Git
Repository configuration
This text file contains configuration specific to this repository, such as:
- The URL of the remote repository (
origin). - Local user overrides.
- Branch‑tracking information.
Create a new repository
git init demo
cd demo
Create a file and commit it
echo "Hello Git" > hello.txt
git add .
git commit -m "First commit"
Explore the objects
# List the objects stored in the repository
ls .git/objects
# Show the contents of a specific object (replace <sha> with an actual SHA‑1)
git cat-file -p <sha>
Observe how Git stores and retrieves data internally.
Conclusion
In this article we explored how Git stores data internally using blobs, trees, commits, and hashes. Understanding this makes Git feel less magical and more predictable.
“Hidden folders sometimes hold the biggest secrets.”
— Anonymous Developer