gabriel / muse public
feat push main #7 / 100

feat(push): implement two-phase chunked push protocol

Separates large pushes into two phases to avoid the server's per-request object limit (MAX_OBJECTS_PER_PUSH = 1 000):

Phase 1 — object pre-upload POST {url}/push/objects (N calls, ≤ 900 objects) Objects are content-addressed (SHA-256) so each chunk is idempotent — the server skips blobs it already holds. No branch refs are touched.

Phase 2 — commit push POST {url}/push (single call) Carries commits + snapshots with an empty objects list. Because blobs were pre-uploaded, this request is small regardless of history size. Branch refs are updated atomically here.

For small pushes (≤ 900 objects) the two phases collapse into the existing single POST /push call — no behaviour change.

Client-side additions: - ObjectsChunkResponse TypedDict in pack.py (stored / skipped counts) - CHUNK_OBJECTS = 900 constant in transport.py - push_objects() added to MuseTransport Protocol, HttpTransport, and LocalFileTransport with full docstrings and security notes - _parse_objects_response() parser mirrors existing _parse_push_result() - _push_chunked() orchestrator in push.py: chunks objects, prints per-chunk progress, then calls push_pack with a slim (no-objects) bundle

Test: updated test_push_already_up_to_date to mock fetch_remote_info correctly (returns RemoteInfo with same HEAD as local → triggers up-to-date fast-path rather than proceeding to JSON serialisation of MagicMock).

G Gabriel Cardona <gabriel@tellurstori.com> · 14h ago Mar 23, 2026 · 7af7a886 · parent 049f451c
4
files changed
415
files in snapshot
Files Changed 415 in snapshot
~4

0 comments

No comments yet. Be the first to start the discussion.