How Git Uses SHA Hashes for Commit Integrity: Blobs, Trees, and Commits
Explore the internal architecture of Git's content-addressable database. Learn how blobs, trees, and commit hashes build a cryptographically linked DAG.
Git is a content-addressable key-value object store. Every file (blob), directory (tree), and commit is identified by a 40-character hexadecimal hash prefixed with its type and byte length: sha1('type length content'). Because commits cryptographically reference parent hashes, altering past history alters every subsequent commit ID.
Solve this problem now with our free Hash & Checksum Generator
Try it instantly in your browser — zero tracking, 100% client-side privacy.
Specification & Architecture Reference
| Git Object Type | What It Contains | Hash Prefix Header |
|---|---|---|
| Blob | Raw file contents (no metadata, no filename) | "blob <size>\0<data>" |
| Tree | List of filenames, file modes, and child blob/tree hashes | "tree <size>\0<entries>" |
| Commit | Root tree hash, parent commit hash(es), author, and message | "commit <size>\0<meta>" |
| Annotated Tag | Target object hash, tag name, tagger, and message | "tag <size>\0<data>" |
Git as a Content-Addressable Object Store
Developers typically view Git as a version tracking tool, but under the hood, it is a content-addressable key-value database stored in `.git/objects/`.
The key for any object is the hash of its contents.
The Git Object Header Formula Whenever Git stores an object, it prepends a header containing the object type, byte size, and a null byte (`\0`), then computes the hash:
sha1("commit 178 tree 2bb67...
parent 9a431...
author ...")Reproducing a Git Blob Hash Locally You can calculate a file's exact Git blob hash using Node.js or standard CLI utilities:
function gitBlobHash(content) { const header = `blob ${Buffer.byteLength(content)}\0`; return crypto .createHash("sha1") .update(header + content) .digest("hex"); }
console.log(gitBlobHash("hello world\n")); // Outputs: 3b18e512dba79e4c8300dd08aeb37f8e728b8dad ``` Verifying via Git CLI: ```bash $ echo "hello world" | git hash-object --stdin 3b18e512dba79e4c8300dd08aeb37f8e728b8dad ```
Why Git History Cannot Be Silently Tampered With Because a commit object incorporates the SHA hash of its **parent commit**, commits form a **Merkle Directed Acyclic Graph (DAG)**.
Modifying a single character in a file committed five years ago alters that blob's hash, which changes the containing tree hash, which alters that commit hash, cascading changes down every subsequent commit.
Explore and compute cryptographic hashes directly in your browser with Mickytool's **Hash & Checksum Generator**.
Solve this problem now with our free Hash & Checksum Generator
Execute this workflow immediately without saving data on remote servers.
Frequently Asked Questions
Why does git hash-object output a different hash than sha1sum on the file?
Standard sha1sum hashes raw file bytes alone, whereas Git prepends the object header 'blob <byteLength>\0' before hashing.
Is Git moving from SHA-1 to SHA-256?
Yes. Due to theoretical SHA-1 collision vulnerabilities, Git supports an experimental SHA-256 object format initialized via git init --object-format=sha256.