Part 8: Git Internals

Level: ๐Ÿ”ต Expert Goal: Understand what Git actually is under the hood โ€” .git, objects, and recovery.


8.1 The .git Directory Structure

The hidden .git/ folder is the entire engine of your repository. Your working files are just the view; .git holds the real data.

your-repo/
โ””โ”€โ”€ .git/
    โ”œโ”€โ”€ HEAD              # which branch am I on?
    โ”œโ”€โ”€ config            # repo-specific settings
    โ”œโ”€โ”€ description       # used by GitWeb
    โ”œโ”€โ”€ index             # the STAGING AREA (a binary index of staged files)
    โ”œโ”€โ”€ refs/
    โ”‚   โ”œโ”€โ”€ heads/        # local branches (pointer files)
    โ”‚   โ””โ”€โ”€ tags/         # tags
    โ”œโ”€โ”€ objects/          # ALL content, stored as immutable objects
    โ”‚   โ”œโ”€โ”€ blobs/
    โ”‚   โ”œโ”€โ”€ trees/
    โ”‚   โ”œโ”€โ”€ commits/
    โ”‚   โ””โ”€โ”€ packs/        # compressed object bundles
    โ””โ”€โ”€ hooks/            # lifecycle scripts (pre-commit, post-merge, ...)

๐Ÿ’ก Pro Tip: You will rarely touch .git directly, but knowing its structure demystifies Git completely.


8.2 The Object Model

Git stores everything as content-addressed objects in objects/. There are four types:

1. Blob ๐Ÿ“„ โ€” file content

  • Stores the content of a file (not the filename!).
  • Identified by its SHA-1 hash.

2. Tree ๐ŸŒณ โ€” directory listing

  • Maps filenames โ†’ blobs (and sub-trees).
  • Represents a folder snapshot.

3. Commit ๐Ÿงพ โ€” project snapshot

  • Points to: a tree (root of the snapshot), parent commit(s), author, committer, and a message.

4. Tag ๐Ÿท๏ธ โ€” named commit

  • A human-friendly name for a specific commit (e.g., v2.0.0).
graph TD
    C["Commit (message, author, parent)"] --> T["Tree (root)"]
    T --> T2["Tree (src/)"]
    T --> B1["Blob: README.md"]
    T2 --> B2["Blob: app.js"]
    T2 --> B3["Blob: style.css"]

How hashing works (the magic)

content  +  type  +  size  โ†’  SHA-1 hash  โ†’  used as the object name
  • Identical content anywhere โ†’ same hash (content addressing).
  • Any change โ†’ different hash โ†’ different object. Immutable history. ๐Ÿ”’

Explore it yourself

git cat-file -t <hash>      # what type of object is this?
git cat-file -p <hash>      # pretty-print its content
git ls-tree HEAD            # see the tree at HEAD

8.3 Branches are just pointers

A branch is simply a file in refs/heads/ containing a commit hash.

cat .git/refs/heads/main
# e.g. a1b2c3d4e5f67890abcdef... (a commit SHA)

git rev-parse main          # the same SHA via a command
graph LR
    M["main โ†’ c3"] --> C1["c1"]
    C1 --> C2["c2"]
    C2 --> C3["c3"]
    F["feature โ†’ c4"] --> C3

Both main and feature point into the same commit chain. Creating a branch = writing a small pointer file.


๐ŸŸข Beginner Example โ€” Viewing Logs

You do not need deep internals to see the structure โ€” git log already shows it beautifully.

git log --oneline                # compact history
git log --oneline --graph        # visual branch structure
git log --stat                   # files changed per commit
git log -p                       # full diffs per commit
git log --all --oneline --graph  # every branch, including remote refs

Output:

* 9z8y7x6 (HEAD -> main) feat: add video player
* 5a4b3c2 fix: typo in settings page
* 1a2b3c4 (origin/main) init: project scaffold

๐Ÿ’ก Pro Tip: To see every commit including "lost" ones: git log --all --oneline --graph. If a commit is not in --all, it is a candidate for recovery (see the expert example below).


๐Ÿ”ต Expert Example โ€” git fsck and Recovering Lost Commits

Scenario: A developer accidentally ran git reset --hard and lost a day of work that was never pushed.

Step 1: Find the "lost" commit

Git's objects are still in .git/objects/ โ€” nothing is deleted immediately. Use fsck (filesystem check):

git fsck --lost-found

Output:

dangling commit 3f2ab4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1
dangling blob 99aa88bb77cc66dd55ee44ff33aa22bb11cc00dd

A dangling commit = a commit no branch points to (our lost work!).

Step 2: Inspect it

git show 3f2ab4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1

Review the message, files, and diff to confirm this is the work you lost.

Step 3: Recover it

Create a branch at the lost commit โ€” instant resurrection:

git branch recover-my-work 3f2ab4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1

Or jump straight there:

git switch -c recover-my-work 3f2ab4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1

Step 4: Merge it back / re-commit

git switch main
git merge recover-my-work     # bring the work home
git branch -d recover-my-work # clean up after a successful merge

โš ๏ธ Warning: Recovery is not guaranteed forever โ€” git gc (garbage collection) permanently deletes unreferenced objects. Recover quickly, and push important work early.

Bonus: reference logs (reflog) โ€” your safety net

Git logs every movement of HEAD and branches:

git reflog

Output:

9z8y7x6 HEAD@{0}: commit: feat: add video player
5a4b3c2 HEAD@{1}: commit: fix: typo
1a2b3c4 HEAD@{2}: reset: moving to HEAD~1    <-- the "oops" moment

Undo that accidental reset:

git reset --hard 1a2b3c4   # reflog told you the exact SHA to go back to

๐Ÿ’ก Pro Tip: The reflog is local only and expires (~90 days). It is the fastest recovery tool for "I moved my branch backward" mistakes.


โš ๏ธ Common Mistakes

  • โŒ Manually editing .git โ€” corrupting objects breaks the repo.
  • โŒ Assuming deleted = gone forever โ€” Git often can recover, but only if you act before git gc.
  • โŒ Forgetting that blobs store content, not names โ€” renaming a file changes a tree, not a blob.
  • โŒ Touching objects with hashes by hand โ€” use git cat-file, git show, and git fsck.

โœ… Key Takeaways

  • .git contains HEAD, the index (staging area), refs, objects, and hooks.
  • Git stores blobs (content), trees (folders), commits (snapshots), and tags.
  • Branches are just pointer files to commits.
  • git fsck and git reflog are your recovery tools for lost commits.

๐Ÿ† Course Complete!

You have reached the end of Git & GitHub Mastery. You went from "what is version control?" to recovering lost commits from Git's raw object database. ๐ŸŽ‰

  • ๐Ÿ“‹ Keep the Cheat Sheet handy for daily use.
  • ๐Ÿ”„ Review the full Command Sequence whenever you start a new project.
  • ๐Ÿš€ Start back at the README and re-practice any part that felt rushed.

Practice is the key. Happy committing!