Something went wrong. Try again.
Something went wrong. Try again.
2.2 kB · 67 lines
TypeScript
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768import { lineToString } from './pkt-line'
export const ZERO_SHA = '0000000000000000000000000000000000000000'
export interface Advertisement { /** Ref name -> object SHA (unpeeled). For annotated tags this is the tag object. */ refs: Map<string, string> /** For annotated tags, the `<tag>^{}` peeled line: ref name -> commit SHA. */ peeled: Map<string, string> capabilities: Set<string>}
/** * Parse a git ref advertisement (protocol v0) from a list of pkt-line * payloads (flush-pkts already stripped by the reader). * * Handles three shapes that occur in practice: * - smart-HTTP prelude: a leading `# service=git-upload-pack` line, which * the ssh transport omits; * - a populated repo: `<sha> <refname>\0<caps>` on the first ref line, * `<sha> <refname>` thereafter, with `<sha> <refname>^{}` peeled lines * for annotated tags; * - an empty repo: a single `<zero-sha> capabilities^{}\0<caps>` line that * carries capabilities but advertises no usable ref. */export function parseAdvertisement(lines: Buffer[]): Advertisement { const refs = new Map<string, string>() const peeled = new Map<string, string>() const capabilities = new Set<string>()
let first = true for (const raw of lines) { const line = lineToString(raw) if (line.startsWith('# service=')) continue
let sha: string let rest: string if (first) { const nul = line.indexOf('\0') const head = nul === -1 ? line : line.slice(0, nul) const caps = nul === -1 ? '' : line.slice(nul + 1) for (const cap of caps.split(' ')) { if (cap) capabilities.add(cap) } first = false const sp = head.indexOf(' ') sha = head.slice(0, sp) rest = head.slice(sp + 1) // Empty-repo sentinel: zero SHA + the literal "capabilities^{}" name. if (sha === ZERO_SHA && rest === 'capabilities^{}') continue } else { const sp = line.indexOf(' ') sha = line.slice(0, sp) rest = line.slice(sp + 1) }
if (rest.endsWith('^{}')) { peeled.set(rest.slice(0, -3), sha) } else { refs.set(rest, sha) } }
return { refs, peeled, capabilities }}