-
Notifications
You must be signed in to change notification settings - Fork 0
Support inserting tree entries that reference arbitrary existing objects #12
Description
Problem
Ledger::create always writes new blobs for field values. There is no way to insert a tree entry whose OID points to an existing git object (commit, tree, or blob) with the correct file mode.
Use case
Forge reviews keep an objects/ subtree that pins target objects for GC:
objects/
├── <commit-oid> # mode 160000 (gitlink)
├── <blob-oid> # mode 100644
└── <tree-oid> # mode 040000
Each entry's OID must point to the actual object, not a new blob containing placeholder content. Currently, callers must work around this with a fixup_pin_entries post-pass that:
- Reads back the commit that
Ledger::createjust wrote. - Rebuilds the
objects/subtree with the correct OIDs and file modes. - Creates a second commit and force-updates the ref.
This doubles the number of commits per creation and is fragile.
Proposed API
A new Mutation variant (or a new field type) that tells the ledger to insert this entry name with this existing OID and file mode:
// Strawman — exact API shape is up to you.
Mutation::Pin("objects/abc123...", oid, FileMode::Commit)The ledger would insert the tree entry directly, the same way treebuilder.insert(name, oid, mode) works, instead of creating a new blob.
Alternatives considered
- Separate subtree + manual commit: what we do today. Works, but the two-commit dance is ugly and makes ref history harder to follow.
- Store OID strings as blob content: keeps one commit but defeats the purpose — GC can still collect the referenced objects because nothing in the tree actually references them.
Generated-by: Claude Code (Claude Opus 4.6)