# Inside Git

## **Inside Git: How it Works and the Role of the .git Folder**

The `.git` folder is a **hidden directory** created when you initialize a Git repository using `git init`. It is the **core of Git**, containing all the information Git needs to track and manage a project.The `.git` folder is the **core of your Git repository**, containing **<mark>all the metadata and the complete history of your project</mark>**. It functions as Git's internal database, and without it, your project is just a regular local directory with no version control.

## What does the `.git` folder contain?

The `.git` folder stores:

Without this folder, Git cannot track changes.

* **Commit history** (all previous versions of the project)
    
* **Branches** and pointers (like `main`, `HEAD`)
    
* **Staging area (index)** information
    
* **Configuration settings**
    
* **Tags and references**
    
* **Objects** (snapshots of files)
    
* **Store the entire version history** of the project
    
* **Track file changes** efficiently
    
* **Enable branching and merging**
    
* **Allow reverting to older versions**
    
* **Support collaboration** without losing data
    

In short, it allows Git to function as a **version control system**.

### **Git Objects: Blob, Tree, and Commit**

Git stores data as **objects**. Git's core functionality is built upon three primary object types stored in the internal database: **blobs**, **trees**, and **commits**. These objects, identified by their unique SHA-1 hashes, work together to efficiently track project history and content. 

**Blob (Binary Large Object)**

A blob object stores the raw content of a file. It is a mass of bytes without any associated metadata like the filename, path, or modification time. 

* **Purpose:** To store file data efficiently. If multiple files (even across different commits or branches) have the exact same content, Git stores only one blob object and reuses its reference, which saves storage space.
    
* **Identification:** Each blob is named by the SHA-1 hash of its content, ensuring that the content is immutable and can be reliably retrieved. 
    
* **Tree**
    
    A tree object functions like a directory entry, organizing files and subdirectories. It connects the content (blobs) to the project structure. 
    
    * **Purpose:** To represent the directory hierarchy at a given moment. A single tree object contains a list of entries, each with a file mode, object type , the object's SHA-1 hash, and the filename.
        
    * **Structure:** This hierarchical structure allows Git to track changes within subdirectories by merely updating the parent tree's hash when a file within a subdirectory is modified. 
        
    * ## Commit Object
        
        ### What is a Commit?
        
        A **Commit** records a **snapshot of the project** at a particular time.
        
        ### Key points:
        
        * Points to a **tree object** (project structure)
            
        * Stores **author**, **date**, and **commit message**
            
        * Points to **parent commit(s)**
            
        
        ### Example:
        
        ```plaintext
        Commit A → Commit B → Commit C
        ```
        
        Each commit saves:
        
        * What the project looked like
            
        * What changed
            
        * Who made the change
            
            ### How Git Tracks Changes
            
            Git tracks changes by **saving snapshots of your project**, not by storing differences line-by-line like some older systems.
            
        * **Core Mechanisms**
            
            * **Content Storage (Blobs):** When you add or commit a file, Git doesn't just record a difference (delta) from the previous version immediately; it stores the entire file's content as a "blob" object in its internal database (`.git/objects`). The name of the blob object is the SHA-1 hash of the file's content. This ensures that identical files, even in different directories or at different points in history, are stored only once, saving space.
                
            * **Directory Structure (Trees):** Git stores snapshots of your project's directory structure using "tree" objects. A tree object lists file names, metadata, and references (SHA-1 hashes) to the corresponding blob objects or other sub-tree objects (for subdirectories).
                
            * **Project History (Commits):** A "commit" object ties everything together. It contains metadata such as the author, date, commit message, a reference to the top-level tree object (representing the project's state at that moment), and references to one or more parent commits. This structure forms the complete history of your project. 
                
            
            **The Tracking Workflow**
            
            Git's tracking process involves a three-stage cycle: 
            
            1. **Working Directory:** This is where you make changes to files on your local machine. Git uses file modification times and sizes to quickly check if a file's working copy differs from what is recorded in the index.
                
            2. **Staging Area (Index):** When you run `git add` for a file, Git takes a snapshot of its current working directory content, compresses it into a blob object, and places a reference to this new object in the staging area. The staging area acts as a temporary buffer that builds your proposed *next* commit, allowing you to select exactly which changes you want to save together.
                
            3. **Local Repository:** The `git commit` command takes the snapshot stored in the staging area, creates a permanent commit object, and records it in the local repository. 
                
            
            **Key Concepts**
            
            * **Snapshots, Not Deltas:** Unlike older version control systems (like SVN), Git primarily thinks in terms of full project snapshots for each commit. While it uses compression and delta-encoding (packfiles) under the hood for efficient storage during garbage collection, the underlying model is based on snapshots.
                
            * **Tracked vs. Untracked Files:** A file is "tracked" if it was present in the last snapshot or has been explicitly added to the staging area with `git add`. Files in the working directory that are new and not yet in the index are "untracked". 
                
            
            This architecture makes Git fast and ensures data integrity through the use of SHA-1 hashes, as any change to a file would result in a different hash ID.
