Git Notes
Deep dive into Git internals including objects (blobs, trees, commits), the SHA-1 hash system, packfiles, refs, and how Git stores data as a content-addressable filesystem.
Understanding Git internals helps you debug issues, recover lost data, and use Git more effectively. At its core, Git is a content-addressable filesystem with a version control system built on top.
Git Object Model
Git stores everything as objects in .git/objects/. There are four types:
How Objects Relate
| commit | a1b2c3d |
| ├── tree | f4e5d6c (root directory) |
| │ ├── blob: 1a2b3c4 | README.md |
| │ ├── blob: 5e6f7g8 | index.js |
| │ └── tree: 9h0i1j2 | src/ |
| │ ├── blob: 3k4l5m6 | src/app.js |
| │ └── blob: 7n8o9p0 | src/utils.js |
| ├── parent | previous-commit-hash |
| ├── author | Jane Doe <jane@example.com> |
| ├── committer | Jane Doe <jane@example.com> |
| └── message | "Add utility functions" |
Exploring Git Objects
View Object Type
git cat-file -t HEADcommit
View Object Content
git cat-file -p HEADtree f4e5d6c7b8a9012345678901234567890abcdef parent a1b2c3d4e5f6789012345678901234567890abcd author Jane Doe <jane@example.com> 1705312200 -0500 committer Jane Doe <jane@example.com> 1705312200 -0500 Add utility functions
View a Tree Object
git cat-file -p f4e5d6c100644 blob 1a2b3c4d5e6f7890123456789012345678901234 README.md 100644 blob 5e6f7g8h9i0j1234567890123456789012345678 index.js 040000 tree 9h0i1j2k3l4m5678901234567890123456789012 src
View a Blob Object
git cat-file -p 1a2b3c4# My Project This is a sample project.
SHA-1 Hashing
Every object is identified by a SHA-1 hash of its content:
# Calculate hash without storing
echo "Hello World" | git hash-object --stdin557db03de997c86a4a028e1ebd3a1ceb225be238
# Store an object in the database
echo "Hello World" | git hash-object -w --stdinThe same content always produces the same hash — this is content-addressable storage.
The .git Directory Structure
ls -la .git/.git/ ├── HEAD # Points to current branch ├── config # Repository configuration ├── description # Used by GitWeb ├── hooks/ # Hook scripts ├── index # Staging area (binary) ├── info/ # Additional info (exclude patterns) ├── objects/ # All objects (blobs, trees, commits, tags) │ ├── 1a/ # First 2 chars of SHA │ │ └── 2b3c4d... # Remaining chars │ ├── info/ │ └── pack/ # Packed objects for efficiency ├── refs/ # Branch and tag pointers │ ├── heads/ # Local branches │ │ └── main # Contains SHA of latest commit │ ├── remotes/ # Remote tracking branches │ │ └── origin/ │ └── tags/ # Tag references └── logs/ # Reflog data
How Commits Chain Together
git cat-file -p HEADtree abc123... parent def456... ← Points to previous commit author ... committer ... Latest commit message
git cat-file -p def456tree ghi789... parent jkl012... ← Points to even earlier commit author ... committer ... Previous commit message
This chain of parent references forms the commit history.
Refs (References)
Refs are human-readable names that point to commit SHAs:
# What does HEAD point to?
cat .git/HEADref: refs/heads/main
# What commit does main point to?
cat .git/refs/heads/maina1b2c3d4e5f6789012345678901234567890abcdef
# Branches are just files containing a commit SHA
ls .git/refs/heads/develop feature-auth main
Packfiles
Git periodically packs loose objects into packfiles for efficiency:
# Trigger packing manually
git gc
# View packed objects
git verify-pack -v .git/objects/pack/pack-*.idx | head -20a1b2c3d4... commit 234 158 12 b2c3d4e5... tree 98 89 170 c3d4e5f6... blob 2048 1024 259 d4e5f6g7... blob 156 128 1283 1 c3d4e5f6... (delta)
Packfiles use delta compression — storing differences between similar objects.
Low-Level (Plumbing) Commands
# Create a blob object
echo "file content" | git hash-object -w --stdin
# Create a tree object
git mktree < tree-entries.txt
# Create a commit object
git commit-tree <tree-sha> -p <parent-sha> -m "message"
# Update a reference
git update-ref refs/heads/main <commit-sha>Building a Commit Manually
# 1. Create a blob
BLOB=$(echo "Hello Git Internals" | git hash-object -w --stdin)
echo "Blob SHA: $BLOB"
# 2. Add blob to a tree
TREE=$(printf "100644 blob $BLOB\thello.txt" | git mktree)
echo "Tree SHA: $TREE"
# 3. Create a commit pointing to the tree
COMMIT=$(git commit-tree $TREE -m "Manual commit")
echo "Commit SHA: $COMMIT"
# 4. Update main to point to new commit
git update-ref refs/heads/main $COMMITThe Index (Staging Area)
The index is a binary file (.git/index) that represents the next commit:
# View index contents
git ls-files --stage100644 1a2b3c4d5e6f7890123456789012345678901234 0 README.md 100644 5e6f7g8h9i0j1234567890123456789012345678 0 index.js 100644 3k4l5m6n7o8p9012345678901234567890123456 0 src/app.js
The number after the SHA (0) is the stage slot — non-zero during merge conflicts.
Interview Questions
- What are the four types of Git objects?
Blob (file content), Tree (directory listing mapping names to blobs/trees), Commit (pointer to tree + parent + metadata), and Tag (named pointer to a commit with annotation).
- How does Git store file content?
Git hashes file content with SHA-1 and stores it as a blob object. The filename is stored separately in a tree object. Identical content produces the same blob regardless of filename.
- What is the difference between plumbing and porcelain commands?
Porcelain commands are user-friendly (commit, push, pull). Plumbing commands are low-level building blocks (hash-object, cat-file, update-ref). Porcelain is built on top of plumbing.
- How are branches implemented internally?
A branch is simply a file in .git/refs/heads/ containing the SHA-1 hash of the latest commit. Creating a branch just creates a 41-byte file.
- What is delta compression in packfiles?
When Git packs objects, it stores similar objects as deltas (differences) rather than full copies. This dramatically reduces storage by referencing a base object and storing only the changes.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Git Internals - Understanding How Git Works Under the Hood.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Git & GitHub topic.
Search Terms
git-github, git & github, git, github, advanced, internals, git internals - understanding how git works under the hood
Related Git & GitHub Topics