Implementing git in rust for fun and education!
If you're looking for a native Rust Git implementation ready for use in anger, you
might consider looking at gitoxide instead!
This is actually my second stab at it, so big blocks will land in place from my first attempt. I'm trying again this year after reading more of "Programming Rust" (Blandy, Orendorff).
open for each read()Storage trait to Queryable<Type + Boxed reader> to "we take a writable object"StorageSet.git/index supportgit log!git log --pretty=oneline >/dev/null vs. git_rs_log >/dev/null against a local checkout of nodejs/node.git_rs_log started out at ~500ms for a complete walk of the repo history. Vanilla git was seeing ~280-300ms.cargo-instruments which worked a treat.git_rs_log, so I added clap.git_rs_log down to 300-320ms for a full walk of node's history. Here's what I did:miniz_oxide backend (the default, written in rust) to native zlib was the biggest boostsort_by_key to sort_unstable_by_key in packfile index reads was a small (5-7ms) win. (Packfile indices have a fanout table, a list of ids in ascending order by id value, and a list of offsets-in-the-packfile whose order corresponds to the ids. In order to use a packfile index to read from a packfile, though, you need to be able to read the offset for your incoming id request and the next id in the packfile in offset order. Hence the sort_by_key call – once we've loaded the ids and offsets, we have to keep a mapping of position of id -> position in packfile.)Id::from_ascii_bytes(&[u8]) for hexadecimal-encoded idsstd::str::from_utf8 which validates that the vector contains valid utf8 before we validate that it only contains hexadecimal chars; now we can do both in one step..git/index. This is the start of the path for writing objects to the Git database.Humanname <email> 10100100100 +7300.git_rs_log
against the Node repository. It turns out someone had committed without an email: Foobar <> 1010020203 -4000.match statements and constants.identity to human_metadata.git log: if we have multiple branches we need to load up
the commit metadata to compare timestamps, as the output order depends on commit timestamp.git log in the node repository.git_rs_log is about 100-200ms slower than git log --pretty=oneline, run against the node repository.src/pack/read.rs file that holds generic read implementations for any BufRead + Seek.Storage trait changed -- instead of returning a boxed read object, it now accepts
a Write destination.Storage is now Queryable (a better name!).Write, we could no longer box Queryables.StorageSet objects had to be rethought as a result -- they could no longer contain Box'd Storage objects.Queryable for the unit type, (), two types (S, T), and arrays of single types Vec<T>.StorageSet may hold a single, top-level Queryable, which might contain nested
heterogenous Queryable definitions.ZlibDecoder will pull more bytes from the underlying stream than it needs, so you can't take
the route of handing it a CrcReader and get good results.Packfile instance created) and outside of the packfile (
implying you have a StorageSet.)Packfile as a non-store object and
iterate over it.Packfile
and an Index (a PackfileStore.)src/stores/mmap_pack into
"sequential packfile reads" and "random access packfile reads (with an index.)"git-rs.eff4c6de1bd15cb0d28581e4da17035dbf9e8596"),
the offsets come from the packfile index.OFS_DELTA ("offset delta") types, the start offset is obtained by reading a [varint][ref_13]
from the packfile and subtracting it from the current start offset.Read state machine.$ claude mcp add git-rs \
-- python -m otcore.mcp_server <graph>