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#
GitRefErrorfor the failures of the Git modules, such as a malformed advertisement.OutOfMemoryErrorfrom functions that copy names.
Examples#
Resolve a short name#
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#
pub struct ObjectIdThe 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#
impl Copy for ObjectIdImplementation ObjectId#
impl ObjectIdAssociated function parseHex#
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#
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#
pub fn bytes(self: &Self) -> &[u8]Returns the raw bytes of the id: 20 for SHA-1, 32 for SHA-256.
Method isSha256#
pub fn isSha256(self: &Self) -> boolReturns true for a SHA-256 id, false for a SHA-1 id.
Method isZero#
pub fn isZero(self: &Self) -> boolReturns true if every byte is zero. Git uses the zero id for a reference that does not
exist yet.
Method equals#
pub fn equals(self: &Self, other: &ObjectId) -> boolReturns true if self and other have the same length and the same bytes.
Method hexLength#
pub fn hexLength(self: &Self) -> usizeReturns the number of hexadecimal digits of the id: 40 for SHA-1, 64 for SHA-256.
Method writeHex#
pub fn writeHex(self: &Self, output: &mut [u8]) -> usizeWrites 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#
pub effect fn hex(self: &Self) -> String
! OutOfMemoryError
? &mut AllocatorReturns the id as lower-case hexadecimal text, such as
95d09f2b10159347eece71399a7e2e907ea3df4f.
Errors#
OutOfMemoryErrorif theAllocatorcannot supply the text.
Implementation Debug for ObjectId#
impl Debug for ObjectIdOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> ()
! WriterError
? &mut WriterWrites the id as lower-case hexadecimal digits.
Ref#
pub struct RefOne 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#
pub name: StringThe full name of the reference.
Field id#
pub id: Option<ObjectId>The object the reference points at, or None for an unborn symbolic reference.
Field peeled#
pub peeled: Option<ObjectId>The object that an annotated tag peels to, when the source reported it.
Field target#
pub target: Option<String>The name that a symbolic reference points at, or None for a direct reference.
Implementation Ref#
impl RefAssociated function make#
pub effect fn make(name: string, id: Option<ObjectId>) -> Ref
! OutOfMemoryError
? &mut AllocatorReturns a direct reference named name that points at id, with no peeled object and no
target.
Errors#
OutOfMemoryErrorif theAllocatorcannot supply the copy ofname.
Method fullName#
pub fn fullName(self: &Self) -> stringReturns the full name, such as refs/heads/main.
Method isBranch#
pub fn isBranch(self: &Self) -> boolReturns true for a branch, a name that starts with refs/heads/.
Method isTag#
pub fn isTag(self: &Self) -> boolReturns true for a tag, a name that starts with refs/tags/.
Method isRemoteBranch#
pub fn isRemoteBranch(self: &Self) -> boolReturns true for a remote-tracking branch, a name that starts with refs/remotes/.
Method isSymbolic#
pub fn isSymbolic(self: &Self) -> boolReturns true for a symbolic reference, one with a target.
Method shortName#
pub fn shortName(self: &Self) -> stringReturns 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#
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#
impl Debug for RefOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> ()
! WriterError
? &mut WriterWrites the fields, as Ref { name: "refs/heads/main", id: Some(95d0...) }. It leaves out
peeled and target when they are absent.
RefList#
pub struct RefListThe 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#
impl RefListAssociated function make#
pub fn make() -> RefListReturns an empty list. It does not allocate.
Method add#
pub effect fn add(self: &mut Self, entry: Ref) -> ()
! OutOfMemoryError
? &mut AllocatorAdds entry at the end of the list.
Errors#
OutOfMemoryErrorif theAllocatorcannot grow the list. The list does not change.
Method insertSorted#
pub effect fn insertSorted(self: &mut Self, entry: Ref) -> usize
! OutOfMemoryError
? &mut AllocatorPuts 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#
OutOfMemoryErrorif theAllocatorcannot grow the list. The list does not change.
Method length#
pub fn length(self: &Self) -> usizeReturns the number of references.
Method asSlice#
pub fn asSlice(self: &Self) -> &[Ref]Returns all references, in the order of the source.
Method asMutSlice#
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#
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#
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#
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#
impl Debug for RefListOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> ()
! WriterError
? &mut WriterWrites the references as a list.
GitRefError#
pub union GitRefErrorThe reason that a Git operation failed.
Malformed#
MalformedThe 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#
pub offset: usizeThe byte offset in the response or file where the problem is.
ServerError#
ServerErrorThe server answered with an ERR packet. message is its text.
Field message#
pub message: StringThe text that the server sent.
NotGitRepository#
NotGitRepositoryThe response is not a Git reference advertisement, for example an HTML page from a URL that is not a repository.
Unsupported#
UnsupportedThe repository uses a format that is not read: an unknown object format, or the reftable
reference store.
SymbolicLoop#
SymbolicLoopA symbolic reference points at itself through a chain of more than five references.
Implementation Debug for GitRefError#
impl Debug for GitRefErrorOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> ()
! WriterError
? &mut WriterWrites 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.