Skip to content

perf: preserve Git object sessions across coherent writes #94

Description

@flyingrobots

Problem

@git-stunts/git-cas@6.5.2 opens typed cat-file and mktree sessions, but GitPersistenceAdapter retires both sessions after every one-shot blob write, retires both after every bounded bulk write, and retires cat-file after every tree write. In a 128-node git-warp retained materialization this converts nominally persistent protocols back into process-per-object behavior.

Measured baseline:

Metric 6.5.2
Total Git child processes 558
cat-file processes 80
mktree processes 82
hash-object processes 140

Audited Git coherence matrix

Raw protocol tests were run against Git 2.50.1 and 2.39.5, in SHA-1 and SHA-256 repositories.

Existing session Subsequent write Safe to preserve? Evidence
cat-file --batch-command loose hash-object -w yes same process reads the new object
cat-file --batch-command checkpointed fast-import pack yes same process refreshes and reads the new packed object
cat-file --batch-command loose mktree output yes same process reads the new tree
mktree --batch -z loose hash-object -w yes pack-primed process validates the new loose object
mktree --batch -z checkpointed pack above fastimport.unpackLimit no pack-primed process rejects the later packed object

This matches upstream Git implementation: cat-file object lookup permits a second read that refreshes packed state, while mktree requests OBJECT_INFO_QUICK.

Proposed single change

Preserve:

  • cat-file across all successful CAS object writes;
  • mktree across one-shot loose blob writes;
  • both sessions across loose tree writes.

Retire only:

  • scoped fast-import after every bounded bulk write, as today;
  • mktree after a bounded bulk write, because the output may be a newly created pack.

Measured candidate

The audited candidate, applied only to an ignored installed package for A/B testing:

Metric 6.5.2 Candidate Delta
Total Git child processes 558 401 -28.1%
cat-file processes 80 4 -95.0%
mktree processes 82 1 -98.8%
Three-run median materialization test time 14.24s 12.72s -10.7%
Three-run median process CPU (user + sys) 15.74s 13.83s -12.1%

Process counts are deterministic; timings are local evidence and must not be represented as a cross-platform guarantee.

Acceptance criteria

  • Unit tests prove the exact retirement matrix using protocol doubles.
  • Real-Git integration proves both safe reuse and the required post-pack mktree retirement.
  • SHA-1 and SHA-256 object identity remains unchanged.
  • Individual blob writes remain one-shot hash-object operations.
  • Scoped fast-import still checkpoints and closes before OIDs escape.
  • Lifecycle, idle retirement, invalidation, and explicit close semantics remain intact.
  • Existing full unit/integration/platform gates pass.
  • A committed witness records process-count and timing scope.

Non-goals

  • No public API change.
  • No persistent fast-import process.
  • No git-warp cache or CAS ownership change.
  • No workspace RootSet coalescing or retention-policy change.
  • No attempt to eliminate the remaining one-shot hash-object, ref, or commit processes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:runtimeRuntime portability or public API behaviorarea:storageStorage, Git objects, manifests, or persistencestatus:in-progressActively being workedtype:bugIncorrect behavior or regressiontype:designDesign doc or proof-plan worktype:goalpostRelease-scale roadmap outcometype:sliceTurn-sized proof work under a goalpost

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions