Last active
October 4, 2019 06:51
-
-
Save isaacs/55ad9e3338912c008804f69dbe855ed1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require('fs') | |
const index = fs.readFileSync('.git/index') | |
const result = {} | |
let p = 0 | |
result.signature = index.slice(p, p + 4).toString('ascii') | |
p += 4 | |
if (result.signature !== 'DIRC') { | |
throw new Error('not a git index file') | |
} | |
result.version = index.readUInt32BE(p) | |
p += 4 | |
if (result.version !== 3 && result.version !== 2) { | |
new Error('unsupported git index version: ' + result.version) | |
} | |
result.entries = new Array(index.readUInt32BE(p)) | |
p += 4 | |
console.error('%j entries', result.entries.length) | |
for (let i = 0; i < result.entries.length && p < index.length; i ++) { | |
const entry = result.entries[i] = { offset: p } | |
entry.entry = i + 1 | |
entry.ctimeSeconds = index.readUInt32BE(p) | |
p += 4 | |
entry.ctimeNanoseconds = index.readUInt32BE(p) | |
p += 4 | |
entry.mtimeSeconds = index.readUInt32BE(p) | |
p += 4 | |
entry.mtimeNanoseconds = index.readUInt32BE(p) | |
p += 4 | |
entry.dev = index.readUInt32BE(p) | |
p += 4 | |
entry.ino = index.readUInt32BE(p) | |
p += 4 | |
entry.mode = index.readUInt32BE(p).toString(8) | |
p += 4 | |
entry.uid = index.readUInt32BE(p) | |
p += 4 | |
entry.gid = index.readUInt32BE(p) | |
p += 4 | |
entry.size = index.readUInt32BE(p) | |
p += 4 | |
entry.sha1 = index.slice(p, p + 20) | |
p += 20 | |
entry.flags = index.readUInt16BE(p) | |
p += 2 | |
entry.assumeValid = entry.flags & 0x8000 | |
entry.extended = entry.flags & 0x4000 | |
entry.stage = [entry.flags & 0x2000, entry.flags & 0x1000] | |
entry.nameLen = entry.flags & 0xFFF | |
entry.length = 62 | |
if (entry.extended && result.version === 3) { | |
entry.extraFlags = index.readUInt16BE(p) | |
p += 2 | |
entry.reserved = entry.extraFlags & 0x8000 | |
entry.skipWorktree = entry.extraFlags & 0x4000 | |
entry.intentToAdd = entry.extraFlags & 0x2000 | |
entry.length += 2 | |
} | |
if (entry.nameLen < 0xFFF) { | |
entry.name = index.slice(p, p + entry.nameLen).toString('utf8') | |
p += entry.nameLen | |
entry.length += entry.nameLen | |
} else { | |
const a = [] | |
do { | |
a.push(index[p++]) | |
} while (index[p] !== 0) | |
entry.nameLen = a.length | |
entry.length += entry.nameLen + 1 | |
entry.name = Buffer.from(a).toString('utf8') | |
} | |
const padLen = (8 - entry.length % 8) || 8 | |
const pad = index.slice(p, p + padLen) | |
p += padLen | |
for (let i = 0; i < padLen; i++) { | |
if (pad[i] !== 0) { | |
throw new Error('non-null chars in pad') | |
} | |
} | |
} | |
console.log(result) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment