Lindenii Project Forge
Warning: Due to various recent migrations, viewing non-HEAD refs may be broken.
/git/refs.ha (raw)
use bytes;
use errors;
use fs;
use io;
use strings;
// Resolve a Git ref to its object ID from its fully qualified ref name.
export fn resolve_ref(r: repo, refname: const str) (oid | error) = {
{
match (fs::open(r.root, refname)) {
case let fh: io::handle =>
defer io::close(fh)!;
let b = io::drain(fh)?;
defer free(b);
let n = if (len(b) > 0 && b[len(b)-1] == '\n') {
yield len(b) - 1z;
} else {
yield len(b);
};
let s = strings::fromutf8(b[..n])?;
return parse_oid(s)?;
case let fe: fs::error =>
if (!(fe is errors::noentry)) {
return fe;
};
};
};
match (fs::open(r.root, "packed-refs")) {
case let fh: io::handle =>
defer io::close(fh)!;
let pr = io::drain(fh)?;
defer free(pr);
let want = strings::toutf8(refname);
let i = 0z;
for (i < len(pr)) {
let e = match (bytes::index(pr[i..], '\n')) {
case let j: size => yield i + j;
case void => yield len(pr);
};
let line = pr[i..e];
if (len(line) >= 1 && (line[0] == '#' || line[0] == '^')) {
void;
} else if (len(line) >= 66z) {
let sp = bytes::index(line, ' ');
if (sp is size) {
let k = (sp: size);
if (k == 64z && k + 1z < len(line)) {
let name_b = line[k + 1z..];
if (bytes::equal(name_b, want)) {
let hexs = strings::fromutf8(line[..k])?;
return parse_oid(hexs)?;
};
};
};
};
i = if (e < len(pr) && pr[e] == '\n') {
yield e + 1z;
} else {
yield e;
};
};
return errors::invalid;
case let fe: fs::error =>
if (fe is errors::noentry) {
return errors::invalid;
};
return fe;
};
};
// Reads and resolves the HEAD ref to its object ID.
export fn head_oid(r: repo) (oid | error) = {
let fh = fs::open(r.root, "HEAD")?;
defer io::close(fh)!;
let b = io::drain(fh)?;
defer free(b);
let n = if (len(b) > 0 && b[len(b)-1] == '\n') {
yield len(b) - 1z;
} else {
yield len(b);
};
let line = b[..n];
const pfx = strings::toutf8("ref: ");
if (len(line) >= len(pfx) && bytes::hasprefix(line, pfx)) {
let rn = strings::fromutf8(line[len(pfx)..])?;
return resolve_ref(r, rn);
};
let s = strings::fromutf8(line)?;
return parse_oid(s)?;
};