http.git

index · http

Overview

Read-only git smart-HTTP frontend (protocol v0, git-upload-pack only).

Serves git clone and git fetch over HTTP on top of the git core reader and git.pack packfile generation. Provides serve which builds a handler function for http.server, plus the underlying protocol pieces (info_refs, upload_pack, pkt-line helpers) for direct use and testing.

Negotiation is deliberately naive: all have lines are ignored and a full pack of everything reachable from the wanted refs is sent once the client says done. Correct for both clone and fetch, just not bandwidth-optimal on incremental fetches. Shallow (--depth) and partial (--filter) requests are rejected with an ERR pkt.

The pack is assembled in memory (see git.pack), so peak memory use is roughly the compressed pack size — fine for small and medium repositories.

Functions

NameSignature
encode_pktencode_pkt(data) -> pkt
decode_pktsdecode_pkts(body) -> pkts, err
info_refsinfo_refs(git_dir) -> body
parse_upload_pack_requestparse_upload_pack_request(body) -> req, err
upload_packupload_pack(git_dir, body) -> response
serveserve(repos) -> handle, err

encode_pkt(data) -> pkt

Encode a pkt-line

decode_pkts(body) -> pkts, err

Decode a pkt-line stream into an array of { kind = "line"|"flush", data } entries

info_refs(git_dir) -> body

Build the info/refs smart advertisement for service=git-upload-pack

parse_upload_pack_request(body) -> req, err

Parse an upload-pack request body (want/have/done pkt-lines)

Returns { wants = {sha, ...}, haves = n, done = bool, side_band = bool, side_band_64k = bool }. Shallow and filter requests yield an error.

upload_pack(git_dir, body) -> response

Answer an upload-pack POST body with an upload-pack response

Stateless-RPC negotiation: rounds without done get a bare NAK (all haves are ignored); once the client sends done, a full pack of everything reachable from the wants follows, side-band framed when the client requested it. Errors become ERR pkts / band-3 messages.

serve(repos) -> handle, err

Build an http.server handler serving the given repositories read-only

repos maps URL prefixes to repository paths, e.g. { ["/lilush"] = "/srv/git/lilush.git" }. Each path must be a git directory (bare repository) or a worktree containing .git. URLs may carry an optional .git suffix (clone http://host/lilush.git works).

The returned function matches the http.server handler contract: handle(method, query, args, headers, body, ctx).