Skip to content

Instantly share code, notes, and snippets.

@isaacs isaacs/read-git-index.js
Last active Oct 4, 2019

Embed
What would you like to do?
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
You can’t perform that action at this time.