# Inside Git

## How Git Works Internally

Git stores code snapshots efficiently using content-addressable objects and pointers, making it fast for branching and history tracking. This internals knowledge helps when debugging repo issues in your full-stack projects.

### Core Components

Git operates across three areas: your working directory (modified files), staging area (git add prepares snapshots), and .git folder (permanent repo storage).​  
The .git directory holds compressed objects: blobs (file contents), trees (directory structures), and commits (snapshots with metadata/parent links).

### Object Storage

Every file/content gets a unique SHA-1 hash (e.g., via `git hash-object file.txt`), stored once to deduplicate identical data across versions.​  
Commits link via parent hashes forming chains; branches are just movable labels (refs) pointing to commit hashes.

### Workflow Internals

* `git commit` creates a commit object with tree root, author, message, and parents; updates HEAD (current branch pointer).​
    
* `git checkout branch` rewrites working directory from that branch's tree objects.​
    
* Merges create a new commit with multiple parents; remotes sync via fetch/push of refs and packfiles (compressed bundles).​
    

### Example Peek

Run `git cat-file -p HEAD` to see the latest commit's tree/parent details, or `ls .git/objects` for hashed storage.

## Understanding the .git Folder

The .git folder is Git's brain—it stores all repository data, history, and metadata in a structured way, separate from your working files. Peeking inside reveals how Git manages snapshots efficiently for your coding projects.

### Main Subfolders

* **objects/**: Holds compressed Git objects (blobs for file contents, trees for directories, commits for snapshots)—organized by SHA-1 hash prefixes into 256 subdirs like `ab/`, plus `pack/` for bundled data.
    
* **refs/**: Stores pointers to commits—`heads/` for local branches (e.g., `main`), `tags/` for tags, `remotes/` for fetched remote branches.
    
* **logs/**: Tracks ref history, like branch movements—check `logs/HEAD` for commit timeline.​
    

### Key Files

* **HEAD**: Points to current branch or commit (e.g., `ref: refs/heads/main`).​
    
* **config**: Repo-specific settings like user info, remotes—edited via `git config`.​
    
* **index**: Staging area snapshot—use `git ls-files --stage` to view.​
    
* **hooks/**: Scripts that run on events like pre-commit (customize via `.git/hooks/`).​
    
    ## Git Objects: Blob, Tree, Commit
    
    Git objects are the fundamental building blocks stored in `.git/objects/`, each identified by a unique SHA-1 hash based on their content. They enable efficient, immutable snapshots: blobs for files, trees for directories, commits for history points.
    
    ### Blob Objects
    
    Blobs store raw file contents without filenames, metadata, or history—just the data compressed with zlib.  
    Identical files share the same blob (deduplication); create one via `git hash-object file.txt` and inspect with `git cat-file -p <hash>`.
    
    ### Tree Objects
    
    Trees represent directory snapshots, listing entries with mode (permissions), name, and hash (to blob or subtree).  
    Root tree links to project structure; changes trigger new trees—run `git cat-file -p HEAD^{tree}` to view.
    
    ### Commit Objects
    
    Commits tie everything: point to root tree, parent commit(s), author/committer details, timestamp, and message.  
    They form history chains; `git cat-file -p HEAD` shows structure like `tree <hash>\nparent <hash>\nauthor ...`.
    

## How git tracks changes

Git tracks changes by comparing file snapshots across three stages: working directory, staging area (index), and repository commits—without storing line-by-line diffs. This snapshot-based approach ensures efficiency and integrity using object hashes.

### Three-Stage Model

* **Working Directory**: Your files as-is; Git checks modification time/size first (fast stat checks), then hashes content if needed to detect real changes.
    
* **Staging Area** (`.git/index`): `git add` hashes modified files into blobs and updates index; untracked files stay ignored until added.​
    
* **Repository** (`.git/objects`): `git commit` creates tree/commit objects from index, forming new snapshot—previous commits unchanged.​
    

### Detection Process

Git runs `git status` by:

1. Stat-ing all tracked files vs index (mtime/size)—flags modified/untracked quickly.
    
2. Hashing changed ones vs index blobs for confirmation.
    
3. Comparing index tree vs HEAD commit tree for staged vs committed diffs.
    

No changes? All hashes match prior snapshots. Example: Edit `file.txt`, `git status` shows "modified" after stat mismatch, `git diff` shows content delta.
