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).
No comments yet. Be the first to start the discussion.