Overview

Git is designed fundamentally as a content-addressable file system rather than a traditional high-level SCM. Its core tracking mechanisms rely on flat binary files and a cryptographic object graph stored locally inside the .git/ directory.


1. The Git Index (.git/index) & git ls-files --stage

The index (or staging area) is a flat binary file located at .git/index that acts as a schema-driven bridge between your working directory and your commit history.

When you run git ls-files --stage, Git reads this index file and prints out lines structured like this: 100644 3549b5ee3ba3ff6ca0bd9127a0119980919b9b30 0 content/Project/01 - Docker.md

Anatomy of an Index Entry Line

Field Breakdown

  • File Mode (100644): Combines file type (100 for regular file) and Unix permissions (644). Standard files are 100644 (owner read/write, others read); executable scripts are 100755.
  • Blob SHA-1 Hash (3549b5ee...): The unique cryptographic object ID pointing directly to the compressed contents stored in .git/objects/.
  • Stage Number (0): Indicates the conflict resolution stage. 0 means normal/no conflict; stages 1, 2, and 3 are used during merge conflicts.
  • File Path: The relative path of the file from the root of the repository.

2. The Object Database (.git/objects/)

Every file version, directory structure (tree), and commit snapshot is stored inside .git/objects/ as an immutable object compressed with zlib.

How objects map to the index

The 40-character SHA-1 hash found in git ls-files --stage corresponds directly to its path on your disk:

  • Directory: .git/objects/35/ (first 2 characters of the hash)
  • File: 49b5ee3ba3ff6ca0bd9127a0119980919b9b30 (remaining 38 characters)

You cannot read these directly with a text editor because they are binary zlib objects, but you can inspect text files using plumbing commands like git cat-file -p <hash>.


File or DB

Physically, it is just a single file on your hard drive, but conceptually and structurally, it functions as a **flat-file database**.

The distinction lies between the container and the organization:

  • The File: .git/index is simply the path and container where the data lives on your disk.
  • The Database: Inside that file, Git doesn’t just dump raw text. It uses a strict, custom-built binary database format (starting with the magic signature DIRC—Directory Cache).

It contains a structured schema with a 12-byte header, followed by a sorted list of fixed-length entries containing timestamps, file sizes, device IDs, file modes (100644), SHA-1 object hashes, and file paths, all wrapped up with a checksum at the very end.

Because it requires a specific parser to read and write structured records rather than acting like a normal configuration text file, Git’s documentation and developers often refer to it as an “internal database” or “index,” even though it lives as a single binary file.

Official Reference

Decoding Git File Modes (100644 vs 100755)

When you run git ls-files --stage, each line starts with a 6-digit file mode: 100644 3549b5ee... 0 content/Project/01 - Docker.md

Anatomy of 100644

  • 100 (File Type): Identifies the object as a regular file (not a symbolic link or folder).
  • 644 (Unix Permissions / chmod): Dictates file access using three digits representing Owner | Group | Others.

How chmod Math Works

Each permission level is a sum of values: Read (4) + Write (2) + Execute (1).

  • 6 (rw-): Read (4) + Write (2) = Can modify, but cannot run/execute.
    • Standard for ordinary files like markdown notes, text files, and source code
  • 7 (rwx): Read (4) + Write (2) + Execute (1) = Can modify and run/execute.
    • Standard for executable scripts or binaries that you need to run, like .sh files
ModeBreakdownMeaningTypical Use Case
100644rw-r--r--Owner can read/write; others can only read.Regular documents, markdown, source code files.
100755rwxr-xr-xOwner can read/write/execute; others can read/execute.Executable scripts (.sh), binaries.

3. Remote Synchronization & Local Tracking

Local vs Remote Scope

  • All metadata, indexes, and object files exist entirely locally on your machine inside .git/.
  • When you run git push, your local commit objects and blob references are uploaded to a remote server (like GitHub or Bitbucket), mirroring your local state onto a shared server.
  • Note on GitHub: GitHub is proprietary software (closed-source), but its backend acts as a translator, running server-side equivalents of Git commands to unpack your pushed objects and render them into the web UI.

4. Global Git Configuration (~/.gitconfig)

Global Settings

User identity and system-wide default settings are stored outside project directories in your user profile (e.g., ~/.gitconfig). You can view or modify them via:

git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

5. Branch Tracking & “Ahead/Behind” Math

Calculating Commit Deltas

Git figures out if you are “1 commit ahead” by comparing object pointers:

  1. It looks up your local branch tip pointer inside .git/refs/heads/.
  2. It checks the remote tracking branch pointer inside .git/refs/remotes/origin/.
  3. By traversing the parent hashes inside the commit objects, it finds the common ancestor and counts the directional divergence.

6. How HEAD Points to a Branch (and Detached HEAD States)

How HEAD Works

Inside .git/HEAD, Git keeps a text pointer.

  • Normal state: It contains a symbolic reference like ref: refs/heads/main. This means HEAD points to a branch file, which holds the actual commit hash.
  • Detached HEAD state: It points directly to a raw commit SHA instead of a branch. This happens when you check out a specific commit hash or remote tracking branch directly.

How to Fix a Detached HEAD

If you are in a detached state and want to save your work:

git switch -c new-branch-name

Reference

https://youtu.be/8dhZ9BXQgc4 Official - Git Internals