Stream packs to the destination

Streaming the pack through to the target may be preferable to compressing fully in-memory and then splatting it out to the target.  (I was OOM'ing while pushing very large commits with very large blobs.)

This introduces some simple helper functions to wrap zlib to deal with error handling and to expose a more `write(2)` like semantic.