Reading — step 1 of 5
Read
Packfile Header: Reading the Bytes
The previous (conceptual) lesson described what packfiles are. Now let's read one — at least the 12-byte header that announces what's inside.
A .pack file begins with:
+---------+---------+---------+---------+
| 'P' 'A' 'C' 'K' | version (u32 BE)|
+---------+---------+---------+---------+
| object count (u32 BE) |
+---------+---------+---------+---------+
... objects ...
... 20-byte SHA footer ...
That's it. Twelve bytes. Magic + version + count. Everything else is the object stream (and the SHA-1 footer over the entire packfile).
Parsing in any language
use std::io::Read;
let mut buf = [0u8; 12];
file.read_exact(&mut buf)?;
assert_eq!(&buf[0..4], b"PACK");
let version = u32::from_be_bytes(buf[4..8].try_into()?);
let count = u32::from_be_bytes(buf[8..12].try_into()?);
Versions
| Version | Year | What's new |
|---|---|---|
| 1 | 2005 | Original; barely seen in the wild today |
| 2 | 2006 | OFS_DELTA, the dominant format |
| 3 | 2018 | SHA-256 support (experimental) |
If you see version 1, you're reading a museum repo. Treat it as
unsupported. Most production git uses v2 exclusively; v3 is opt-in via
extensions.objectFormat.
Why big-endian?
Network byte order. Packfiles travel over the wire (git fetch / git push),
so they use the same endianness as TCP/IP. Even on little-endian disks,
the bytes match what comes off the network.
Validation matters
A corrupted pack header is the difference between "git fetch failed" and "git fetch silently produced garbage." The combination of:
- Magic bytes
- Version whitelist
- Length precondition (≥12 bytes for the header alone)
- SHA-1 footer over the full file
makes packs robust to truncation, byte-flips, and version skew. The footer is the most important — git always validates it before trusting any object inside the pack.
After the header
Each object in the body starts with a variable-length size + type header, then zlib-compressed (or delta-compressed) data. Parsing the body is substantially more work than the header. That's a great next project — but this lesson stops at byte 12.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…