Skip to main content

Module driver

Module driver 

Source
Expand description

The client half: pkt-line framing over a blocking stream, and the send_pack driver that runs one whole push.

§The conversation, exactly

S→C   <old-oid> <refname>\0<capabilities>\n     ref advertisement, protocol v0
S→C   <old-oid> <refname>\n                     …one line per ref
S→C   0000
C→S   <old> <new> <refname>\0<capabilities>\n   the command list
C→S   <old> <new> <refname>\n                   …one line per ref being moved
C→S   0000
C→S   <push-option>\n … 0000                    only if `push-options` was negotiated
C→S   PACK…                                     raw, NOT pkt-line framed
S→C   unpack ok\n                               report-status
S→C   ok refs/heads/main\n | ng refs/heads/x <why>\n
S→C   0000

Three details are where implementations go wrong, and each has a test:

  1. The packfile is not framed. It follows the flush-pkt as raw bytes. Framing it is a corrupt push with a checksum error and no clue pointing at the framing layer.
  2. An all-deletes push sends no pack at all. Sending an empty pack is also legal, but sending one for a push that introduces no objects is a lie about what the client did.
  3. With side-band-64k, the report is muxed inside band 1, pkt-lines nested inside pkt-lines, and the remote’s hook output arrives on band 2. Reading the report without demuxing yields a leading \x01 on every line and a parse that fails in a way that looks like a protocol error.

Functions§

encode_command_list
The command list, framed and flush-terminated.
encode_push_options
The push-options section, framed and flush-terminated.
frame_section
Frame lines as text pkt-lines and terminate with a flush-pkt.
read_advertisement
Read git-receive-pack’s ref advertisement from reader.
read_report
Read the report from reader, demultiplexing sidebands when negotiated.
send_pack
Run one complete send-pack over transport, given an advertisement already read from it.