Design: Pure Pony Git Implementation #308
SeanTAllen
started this conversation in
Git for Corral
Replies: 1 comment
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Design companion to the motivation document. This is the high-level approach and phased implementation plan. Each phase will get its own detailed plan as we go.
Approach
Replace
GitVCSinternals with a pure Pony git library. TheVCS,RepoOperation,Repo, andTagListReceiverinterfaces stay unchanged. A newPonyGitVCSimplements the same three operations — sync, tag_query, checkout — using pure Pony code instead of shelling out togit.During implementation, a hybrid
GitVCSdelegates replaced operations to pure Pony and unreplaced operations to the existing process-based implementation. Operations are replaced one at a time in order of increasing complexity:Architecture
New code lives under
corral/git/:Vendored courier stack (courier, lori, ssl, logger — 4 packages, ~131 source files) lives alongside the existing source. Exact vendoring location TBD in Phase 1 detailed plan.
The
VCSinterface is the integration boundary.PonyGitVCSimplements it, returningRepoOperationobjects that do pure Pony git work. The_Updateractor, command layer, and all non-git VCS stubs remain unchanged.What we're not building
Digest.sha1()via OpenSSL/LibreSSL EVP. Since ssl is already required for HTTPS, using it for SHA-1 adds no new dependency.Phases
Phase 1: Vendor Courier Stack + Foundations
Vendor courier, lori, ssl, and logger into the corral repo. Update the build system so corral compiles with the vendored packages. Existing tests must continue to pass — this phase adds dependencies but changes no behavior.
Then implement the two foundational components:
Digestclass providingsha1(data): Array[U8] valandsha1_hex(data): String val. Isolates the ssl dependency to one place.Deliverable: Vendored packages building cleanly. Inflate and SHA-1 with comprehensive test suites. No git integration yet.
Risk: Inflate is the highest-risk component in the entire project. Huffman table decoding, LZ77 back-references, fixed vs. dynamic code tables — subtle bugs here produce silent data corruption downstream. This must be thoroughly tested before proceeding.
Phase 2: Git Object Layer
Read local git data:
.git/objects/xx/yyyy...files, verify SHA-1, parsetype size\0contentheader..idxindex files for object lookup..git/packed-refs(text format) and.git/refs/directory tree. Resolve tag names to SHA-1 hashes.Deliverable: A
GitObjectDBthat, given a.gitdirectory path, can resolve any ref to an object and read any object by SHA-1. Testable against real git repositories.Risk: Packfile delta resolution is the second highest-risk component. Delta chains can be deep, and incorrect application produces silent corruption. Need test vectors covering OFS_DELTA, REF_DELTA, and multi-level chains.
Phase 3: Checkout + Hybrid Integration
Two pieces: the tree walker and the first integration point.
git reset --mixed+git checkout-indextwo-step.GitVCSso thattag_query_opreads refs directly via Phase 2's ref reader (instead ofgit show-ref), andcheckout_opuses the tree walker (instead ofgit reset+git checkout-index).sync_opcontinues to use the git CLI.Deliverable:
tag_query_opandcheckout_oprunning pure Pony.sync_opstill shells out to git. Integration tests pass.Phase 4: Smart HTTP Protocol + Full Integration
Git smart HTTP client using vendored courier:
GET /info/refs?service=git-upload-pack, parse capability advertisement and ref list.POST /git-upload-packwith want/have lines. For initial clone: want all refs, have nothing. For fetch: want new refs, report existing refs as haves..git/refs/or.git/packed-refs.Replace
sync_op:PonyGitSyncuses HTTP to clone (create local.git+ fetch all refs + download pack) and fetch (negotiate + download incremental pack + update refs). Remove git CLI dependency.GitVCSbecomesPonyGitVCSwith no process-based operations.Deliverable: Git CLI no longer required. All integration tests pass against real GitHub repos.
Risk: Highest-complexity phase. The smart HTTP protocol has subtle details (sideband multiplexing, capability negotiation, packfile framing). This is also where authentication for private repos becomes necessary.
Phase Summary
Phases are sequential (each depends on the prior). Estimated new code: ~2500-4000 lines across the git packages, plus ~131 files of vendored courier/lori/ssl/logger.
Design Notes
ActionResult.fail: The existingActionResultclass already has afail(errmsg)constructor used for non-process errors (e.g.,GitCheckoutRepouses it when directory creation fails). Pure Pony operations use this same path — no interface changes needed.repo.remoteis a bare path (e.g.,github.com/ponylang/corral.git). The current_cloneprependshttps://— the pure Pony HTTP client must do the same._fetchdoesn't use the remote URL at all (git remembers it), but pure Pony fetch must always receive it fromrepo.remote..gitdirectory creation: Currentlygit clonecreates the.gitstructure. Pure Pony clone (Phase 4) must create.git/,.git/objects/pack/,.git/refs/, etc. explicitly._fetchuses--tagsto fetch all tags. Pure Pony fetch must replicate this — tags are the primary data corral needs for semver resolution.Open Questions
These don't need answers now — each phase's detailed plan will address them:
corral/logger/package. Courier depends on a separateloggerpackage. These will collide. Resolution options: rename the vendored logger, restructure the vendor path, or adapt courier to use corral's logger. Addressed in Phase 1 detailed plan.-pflag or placement within the source tree). Addressed in Phase 1 detailed plan.What Stays Unchanged
VCS/RepoOperation/Repo/TagListReceiver/RepoOperationResultReceiverinterfaces_Updateractor and command dispatch layerRunner/Program/Action/ActionResultinfrastructure (still needed forPostFetchScript)VCSBuilderinterface and other VCS stubs (hg/bzr/svn/none)What Changes Beyond the Git Library
CorralVCSBuilderimplementation: switches from constructingGitVCStoPonyGitVCS(or hybrid during transition). TheVCSBuilderinterface itself doesn't change.corral.jsonpackages list: newcorral/git/sub-packages and vendored packages must be registered.corral/git/tree and vendored packages.All reactions