Hash Algorithm
SHA-1: The Original Hash
Section titled “SHA-1: The Original Hash”Since its creation, Git has used SHA-1 (Secure Hash Algorithm 1) to identify all objects. Every Blob, tree, commit, and tag is named by the 40-character hexadecimal representation of its SHA-1 Hash, producing a address space.
SHA-1 Properties
Section titled “SHA-1 Properties”| Property | Value |
|---|---|
| Output size | 160 bits (20 bytes, 40 hex characters) |
| Collision resistance | (theoretical) — broken in practice |
| Preimage resistance | (unbroken) |
| Speed | Fast (hardware-accelerated on modern CPUs) |
The SHA-1 Collision Problem
Section titled “The SHA-1 Collision Problem”In 2017, researchers at Google and CWI Amsterdam demonstrated the first SHA-1 collision (the “SHAttered” attack). They produced two different PDF files with the same SHA-1 hash, requiring Approximately computations (far below the theoretical ).
Does this affect Git? Directly, not much. The attack required significant computational Resources (6,500 CPU-years) and was specifically crafted for PDF files. However, it proved That SHA-1”s collision resistance is weaker than assumed, and future advances could make attacks Cheaper.
Git’s Defenses Against Collision Attacks
Section titled “Git’s Defenses Against Collision Attacks”Git has several properties that make collision attacks harder than generic SHA-1 collisions:
- Object headers: Git hashes
"<type> <size>\0<content>"Not raw content. An attacker must collide the full header+content. - Detect checks:
git fsckdetects objects whose hash does not match their content. - Collision detection: Git includes collision detection code that detects SHAttered-style attacks.
SHA-256: The Transition
Section titled “SHA-256: The Transition”Git 2.29 (September 2020) added experimental support for SHA-256 as an alternative hash Algorithm.
Enabling SHA-256
Section titled “Enabling SHA-256”## Initialize a new repository with SHA-256$ git init --object-format=sha256
## Configure globally for new repositories$ git config --global init.defaultObjectFormat sha256
# Check the hash algorithm of an existing repository (0=SHA-1, 1=SHA-256)$ git config core.repositoryFormatVersionSHA-256 Properties
Section titled “SHA-256 Properties”| Property | SHA-1 | SHA-256 |
|---|---|---|
| Output size | 160 bits | 256 bits |
| Collision resistance | (broken) | (secure) |
| Preimage resistance | (secure) | (secure) |
| Hash length | 40 hex chars | 64 hex chars |
| Speed | Faster | 20% slower (software) |
Migration Challenges
Section titled “Migration Challenges”Migrating an existing repository from SHA-1 to SHA-256 is not currently supported by Git. This Is because:
- Every object hash changes: All blobs, trees, commits, and tags get new hashes.
- All references break: Branches, tags, remotes. Everything must be updated.
- All packfiles must be regenerated: The entire object store is invalidated.
- Interoperability: SHA-256 repositories cannot interoperate with SHA-1 tools or servers.
The Git community is working on a migration path, but it is not yet production-ready. For new Repositories, enabling SHA-256 from the start is recommended.
Hash Length Abbreviation
Section titled “Hash Length Abbreviation”Git allows abbreviating hashes to the shortest unambiguous prefix:
# Full SHA-1 (40 chars)a3f2b1c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6
# Abbreviated (minimum unambiguous length)a3f2b1c
# Configure minimum abbreviation length$ git config core.abbrev 12 # Require at least 12 charsWith SHA-256, the minimum abbreviation length is longer (more objects can share a prefix before Diverging). Git handles this automatically.
Practical Implications
Section titled “Practical Implications”For New Projects
Section titled “For New Projects”# Start new projects with SHA-256$ git init --object-format=sha256This provides future-proofing at essentially zero cost (the slight speed difference is negligible For most workflows).
For Existing Projects
Section titled “For Existing Projects”No migration path exists yet. Monitor the Git mailing list for updates. In the meantime:
- Run
git fsckperiodically to detect corruption. - Keep your
gc.pruneExpiresettings generous to avoid accidental data loss. - Back up your
.gitdirectory regularly.
For Security-Sensitive Projects
Section titled “For Security-Sensitive Projects”If you are concerned about collision attacks:
- Enable fsck: Run
git fsckin CI to detect corrupted objects. - Sign commits: Use GPG or SSH to sign commits and tags.
- Use SHA-256 for new repositories.
Content-Addressable Storage: Design Rationale
Section titled “Content-Addressable Storage: Design Rationale”Git’s choice of content-addressable storage (CAS) is fundamental to its design. The implications are Far-reaching:
| Property | Benefit |
|---|---|
| Deduplication | Identical files across commits produce one blob object |
| Integrity | Any modification of an object changes its hash, breaking references |
| Distributed consensus | Two developers can independently verify they have the same object |
| Deterministic builds | A commit hash uniquely identifies a project state |
| Garbage collection | Unreachable objects can be safely deleted without affecting reachable objects |
The trade-off is that Git cannot efficiently store files that change slightly and frequently (e.g., Large binary files, databases). This is why Git LFS exists — it stores the large file content Outside the object store and tracks only a pointer.
Common Pitfalls
Section titled “Common Pitfalls”Writing vague answers without specific biological terminology. Use precise terms (e.g., ‘phospholipid bilayer’ not ‘membrane’).
Using anecdotal evidence or small sample sizes as though they constitute robust scientific data.
Failing to link structure to function when describing biological molecules, cells, or organs.
Misinterpreting graphs by confusing the independent and dependent variables or reading scales incorrectly.
Summary
Section titled “Summary”The key principles covered in this topic are linked in the sub-pages above. Focus on understanding the definitions, applying the formulas or frameworks, and evaluating strengths and limitations of each approach.
Worked Examples
Section titled “Worked Examples”Worked examples demonstrating the application of key concepts are covered in the detailed sub-pages linked above.
Intuition
Section titled “Intuition”Hashing is like a fingerprint for data. Just as a fingerprint uniquely identifies a person, a hash uniquely identifies a piece of content. Content-addressable storage is like a library where books are shelved by their ISBN number instead of by title or author - if two books have the same ISBN, they must be the same book. SHA-1 produces a 40-character hex string that acts as this ISBN. The key insight is that hashing provides integrity verification - if even one bit of a file changes, its hash changes completely. This is like a tamper-evident seal on a package - any attempt to open it leaves evidence. Git uses this to ensure that every object in the repository is exactly what it claims to be.
Cross-References
Section titled “Cross-References”- Git Directory Structure - How hashed objects are stored in the .git directory
- Packing and Garbage Collection - How Git manages object lifecycle using hashes