silk.git.refs.

Git object ids, references, and the lists of references that a remote or a local repository has.

When to use#

Use the types here with silk.git.remote, which lists the references of a remote repository like git ls-remote, and silk.git.local, which reads them from a .git directory. Look a name up in a RefList with RefList.find for an exact name such as refs/tags/v1.0.0, or with RefList.resolve for a short name such as main or v1.0.0, as Git does.

Details#

An ObjectId is a SHA-1 (20 bytes) or SHA-256 (32 bytes) object name. A Ref has a full name, the object it points at, the object that an annotated tag peels to, and the target of a symbolic reference such as HEAD. Ref.commit gives the peeled object when there is one, which for a tag is the commit that it tags.

Errors#

  • GitRefError for the failures of the Git modules, such as a malformed advertisement.

  • OutOfMemoryError from functions that copy names.

Examples#

Resolve a short name#

silk
import silk.mem.allocator { Allocator, OutOfMemoryError }
import silk.core.effect { Effect }
import silk.core.option { Option }
import silk.git.refs { ObjectId, Ref, RefList }

effect fn build() -> bool ! OutOfMemoryError ? &mut Allocator {
  let id = match ObjectId.parseHex(b"95d09f2b10159347eece71399a7e2e907ea3df4f") {
    Option<ObjectId>.Some { value } => value
    Option<ObjectId>.None => { return false }
  }
  let mut refs = RefList.make()
  run refs.add(run Ref.make("refs/heads/main", Option<ObjectId>.some(id)))
  return match refs.resolve("main") {
    Option<&Ref>.Some { value } => value.isBranch()
    Option<&Ref>.None => false
  }
}

pub effect fn main() -> i32 ! OutOfMemoryError {
  let mut allocator = Allocator.systemAllocatorProvider()
  if run build() |> Effect.provideMut<Allocator>(&mut allocator) {
    return 0
  }
  return 1
}

Import as RefList with import silk.git.refs { RefList }.

Public declarations: 4.

ObjectId#

silk
pub struct ObjectId

The name of a Git object: a SHA-1 of 20 bytes or a SHA-256 of 32 bytes.

Details#

Make one with ObjectId.parseHex from 40 or 64 hexadecimal digits, or with ObjectId.fromBytes. It is a plain value, so copies are cheap. Two ids are equal when ObjectId.equals says so: the same length and the same bytes.

Implementation Copy for ObjectId#

silk
impl Copy for ObjectId

Implementation ObjectId#

silk
impl ObjectId

Associated function parseHex#

silk
pub fn parseHex(text: &[u8]) -> Option<ObjectId>

Returns the id that text spells in hexadecimal, upper or lower case, or None if text is not 40 or 64 hexadecimal digits.

Associated function fromBytes#

silk
pub fn fromBytes(bytes: &[u8]) -> Option<ObjectId>

Returns the id with the raw bytes bytes, or None if bytes is not 20 or 32 bytes long.

Method bytes#

silk
pub fn bytes(self: &Self) -> &[u8]

Returns the raw bytes of the id: 20 for SHA-1, 32 for SHA-256.

Method isSha256#

silk
pub fn isSha256(self: &Self) -> bool

Returns true for a SHA-256 id, false for a SHA-1 id.

Method isZero#

silk
pub fn isZero(self: &Self) -> bool

Returns true if every byte is zero. Git uses the zero id for a reference that does not exist yet.

Method equals#

silk
pub fn equals(self: &Self, other: &ObjectId) -> bool

Returns true if self and other have the same length and the same bytes.

Method hexLength#

silk
pub fn hexLength(self: &Self) -> usize

Returns the number of hexadecimal digits of the id: 40 for SHA-1, 64 for SHA-256.

Method writeHex#

silk
pub fn writeHex(self: &Self, output: &mut [u8]) -> usize

Writes the id as lower-case hexadecimal digits to the start of output and returns the number of digits written, ObjectId.hexLength. Returns 0 and writes nothing if output is shorter than that.

Method hex#

silk
pub effect fn hex(self: &Self) -> String
    ! OutOfMemoryError
    ? &mut Allocator

Returns the id as lower-case hexadecimal text, such as 95d09f2b10159347eece71399a7e2e907ea3df4f.

Errors#

  • OutOfMemoryError if the Allocator cannot supply the text.

Implementation Debug for ObjectId#

silk
impl Debug for ObjectId

Operation debug#

silk
effect fn debug(self: &Self, formatter: &mut Formatter) -> ()
    ! WriterError
    ? &mut Writer

Writes the id as lower-case hexadecimal digits.

Ref#

silk
pub struct Ref

One Git reference: a name, the object it points at, and, for some, a symbolic target or a peeled object.

Details#

name is the full name, such as HEAD, refs/heads/main, or refs/tags/v1.0.0. id is the object that the reference points at. It is None only for a symbolic reference whose target does not exist yet, such as HEAD in a new repository. peeled is the object that an annotated tag points at, after all tags are followed, when the source reported it. target is the name that a symbolic reference points at, such as refs/heads/main for HEAD.

Field name#

silk
pub name: String

The full name of the reference.

Field id#

silk
pub id: Option<ObjectId>

The object the reference points at, or None for an unborn symbolic reference.

Field peeled#

silk
pub peeled: Option<ObjectId>

The object that an annotated tag peels to, when the source reported it.

Field target#

silk
pub target: Option<String>

The name that a symbolic reference points at, or None for a direct reference.

Implementation Ref#

silk
impl Ref

Associated function make#

silk
pub effect fn make(name: string, id: Option<ObjectId>) -> Ref
    ! OutOfMemoryError
    ? &mut Allocator

Returns a direct reference named name that points at id, with no peeled object and no target.

Errors#

  • OutOfMemoryError if the Allocator cannot supply the copy of name.

Method fullName#

silk
pub fn fullName(self: &Self) -> string

Returns the full name, such as refs/heads/main.

Method isBranch#

silk
pub fn isBranch(self: &Self) -> bool

Returns true for a branch, a name that starts with refs/heads/.

Method isTag#

silk
pub fn isTag(self: &Self) -> bool

Returns true for a tag, a name that starts with refs/tags/.

Method isRemoteBranch#

silk
pub fn isRemoteBranch(self: &Self) -> bool

Returns true for a remote-tracking branch, a name that starts with refs/remotes/.

Method isSymbolic#

silk
pub fn isSymbolic(self: &Self) -> bool

Returns true for a symbolic reference, one with a target.

Method shortName#

silk
pub fn shortName(self: &Self) -> string

Returns the name without the prefix of its kind: main for refs/heads/main, v1.0.0 for refs/tags/v1.0.0, origin/main for refs/remotes/origin/main. Another name under refs/ loses only refs/, and a name outside refs/, such as HEAD, does not change.

Method commit#

silk
pub fn commit(self: &Self) -> Option<ObjectId>

Returns the object that the reference finally names: the peeled object when there is one, which for an annotated tag is the object it tags, usually a commit. Otherwise returns id.

Implementation Debug for Ref#

silk
impl Debug for Ref

Operation debug#

silk
effect fn debug(self: &Self, formatter: &mut Formatter) -> ()
    ! WriterError
    ? &mut Writer

Writes the fields, as Ref { name: "refs/heads/main", id: Some(95d0...) }. It leaves out peeled and target when they are absent.

RefList#

silk
pub struct RefList

The references of one repository, in the order of the source.

Details#

A remote lists its references sorted by name, after HEAD. A local repository is read in the same order. Use RefList.find for an exact name, RefList.resolve for a short name, and RefList.asSlice to walk all of them.

Implementation RefList#

silk
impl RefList

Associated function make#

silk
pub fn make() -> RefList

Returns an empty list. It does not allocate.

Method add#

silk
pub effect fn add(self: &mut Self, entry: Ref) -> ()
    ! OutOfMemoryError
    ? &mut Allocator

Adds entry at the end of the list.

Errors#

  • OutOfMemoryError if the Allocator cannot grow the list. The list does not change.

Method insertSorted#

silk
pub effect fn insertSorted(self: &mut Self, entry: Ref) -> usize
    ! OutOfMemoryError
    ? &mut Allocator

Puts entry at its place in name order and returns its index. A reference with the same name is replaced.

Details#

Names compare by their bytes, as Git sorts them, so HEAD comes before refs/. It finds the place by binary search, so the list must already be in name order, as it is when you only add references with this function. An entry that sorts last is appended without moving others.

Errors#

  • OutOfMemoryError if the Allocator cannot grow the list. The list does not change.

Method length#

silk
pub fn length(self: &Self) -> usize

Returns the number of references.

Method asSlice#

silk
pub fn asSlice(self: &Self) -> &[Ref]

Returns all references, in the order of the source.

Method asMutSlice#

silk
pub fn asMutSlice(self: &mut Self) -> &mut [Ref]

Returns all references so that you can change them, in the order of the source.

Gotchas#

RefList.insertSorted needs the names in order, so change a name only if the order stays.

Method find#

silk
pub fn find<'r>(self: &'r Self, name: string) -> Option<&'r Ref>

Returns the reference whose full name is exactly name, such as refs/heads/main or HEAD, or None if there is none.

Method resolve#

silk
pub fn resolve<'r>(self: &'r Self, name: string) -> Option<&'r Ref>

Returns the reference that the short name name means, in the order that Git uses, or None if there is none.

Details#

It tries, in order: name itself, refs/<name>, refs/tags/<name>, refs/heads/<name>, refs/remotes/<name>, and refs/remotes/<name>/HEAD. So a tag wins over a branch with the same short name, as in git rev-parse.

Method head#

silk
pub fn head<'r>(self: &'r Self) -> Option<&'r Ref>

Returns HEAD, or None if the source did not report it.

Details#

For a remote, HEAD is the default branch: its target is the branch name, such as refs/heads/main, when the server reports it. A detached HEAD has no target.

Implementation Debug for RefList#

silk
impl Debug for RefList

Operation debug#

silk
effect fn debug(self: &Self, formatter: &mut Formatter) -> ()
    ! WriterError
    ? &mut Writer

Writes the references as a list.

GitRefError#

silk
pub union GitRefError

The reason that a Git operation failed.

Malformed#

silk
Malformed

The data at offset is not in the expected format: a broken pkt-line, a line without an object id, or a broken packed-refs or loose reference file.

Field offset#

silk
pub offset: usize

The byte offset in the response or file where the problem is.

ServerError#

silk
ServerError

The server answered with an ERR packet. message is its text.

Field message#

silk
pub message: String

The text that the server sent.

NotGitRepository#

silk
NotGitRepository

The response is not a Git reference advertisement, for example an HTML page from a URL that is not a repository.

Unsupported#

silk
Unsupported

The repository uses a format that is not read: an unknown object format, or the reftable reference store.

SymbolicLoop#

silk
SymbolicLoop

A symbolic reference points at itself through a chain of more than five references.

Implementation Debug for GitRefError#

silk
impl Debug for GitRefError

Operation debug#

silk
effect fn debug(self: &Self, formatter: &mut Formatter) -> ()
    ! WriterError
    ? &mut Writer

Writes the variant and its fields, such as Malformed { offset: 4 }.

Category: Version control.

Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2, x86_64-pc-windows-msvc, wasm64-unknown-unknown.

View the source of this page