UNPKG

git-cat-file

Version:

A pure-JavaScript implementation of `git cat-file -p` for Node.js.

61 lines (48 loc) 1.87 kB
/** * https://github.com/kawanet/git-cat-file * * @see https://github.com/git/git/blob/master/Documentation/technical/pack-format.txt */ import {promises as fs} from "fs" export type PackIndex = {[oid: string]: number} const toHex = (buf: Buffer) => buf.toString("hex").replace(/(\w.)(?=\w)/g, "$1 ") export async function readPackIndex(path: string): Promise<PackIndex> { path = path.replace(/\.pack$/, ".idx") if (!/\.idx$/.test(path)) throw TypeError(`Invalid pack index file: ${path}`) const data = await fs.readFile(path) return parsePackIndex(data) } async function parsePackIndex(data: Buffer): Promise<PackIndex> { // validate header const headByte = data.slice(0, 4) const head = headByte.toString("latin1") if (head !== "\xFFtOc") throw TypeError(`Invalid header: ${toHex(headByte)}`) // validate version number const version = data.readUInt32BE(4) if (version !== 2) throw TypeError(`Invalid version number: ${version}`) let oidIdx = 8 + 4 * 256 // total objects count const total = data.readUInt32BE(oidIdx - 4) // console.warn(`found: ${total} packed objects`); const oidLast = oidIdx + 20 * total let table4Idx = oidLast + 4 * total let table8Idx = table4Idx + 4 * total const packIndex: PackIndex = {} while (oidIdx < oidLast) { const end = oidIdx + 20 const oid = data.slice(oidIdx, end).toString("hex") let pos = data.readUInt32BE(table4Idx) table4Idx += 4 if (pos & 0x80000000) { // console.warn(pos.toString(16)); const high = data.readUInt32BE(table8Idx) table8Idx += 4 const low = data.readUInt32BE(table8Idx) table8Idx += 4 pos = high * 0x100000000 + low } packIndex[oid] = pos oidIdx = end } return packIndex }