mirror of
https://seed.radicle.dev/rad:z6cFWeWpnZNHh9rUW8phgA3b5yGt.git
synced 2026-10-24 22:00:38 +08:00
radicle-git init
Port over all git relevant parts of the radicle-link repository[0]. The packages that are kept are: * git-ext * git-ref-format * git-trailers * link-git * macros * std-ext * test -- only the portions that test the above The development and testing scripts are also added for local and CI testing. [0]: https://github.com/radicle-dev/radicle-link/ Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
// Copyright © 2021 The Radicle Link Contributors
|
||||
//
|
||||
// This file is part of radicle-link, distributed under the GPLv3 with Radicle
|
||||
// Linking Exception. For full terms see the included LICENSE file.
|
||||
|
||||
//! Everything you never knew you wanted for handling git ref names.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
//! This crate provides a number of types which allow to validate git ref names,
|
||||
//! create new ones which are valid by construction, make assertions about their
|
||||
//! structure, and deconstruct them into their components.
|
||||
//!
|
||||
//! ## Basic Types
|
||||
//!
|
||||
//! The basic types are:
|
||||
//!
|
||||
//! * [`RefStr`]
|
||||
//! * [`RefString`]
|
||||
//!
|
||||
//! They are wrappers around [`str`] and [`String`] respectively, with the
|
||||
//! additional guarantee that they are also valid ref names as per
|
||||
//! [`git-check-ref-format`] (which is also exposed directly as
|
||||
//! [`check_ref_format`]). Both types are referred to as "ref strings".
|
||||
//!
|
||||
//! Note that this implies that ref names must be valid UTF-8, which git itself
|
||||
//! doesn't require.
|
||||
//!
|
||||
//! Ref strings can be iterated over, either yielding `&str` or [`Component`]. A
|
||||
//! [`Component`] is guaranteed to not contain a '/' separator, and can thus
|
||||
//! also be used to conveniently construct known-valid ref strings. The [`lit`]
|
||||
//! module contains a number of types (and `const` values thereof) which can be
|
||||
//! coerced into [`Component`], and thus can be used to construct known-valid
|
||||
//! ref strings.
|
||||
//!
|
||||
//! The [`name`] module also provides a number of constant values of commonly
|
||||
//! used ref strings / components, which are useful for pattern matching.
|
||||
//!
|
||||
//! The `"macro"` feature enables the `refstring!` and `component!` macros,
|
||||
//! which can be convenient to construct compile-time validated [`RefString`]s
|
||||
//! respectively [`Component`]s.
|
||||
//!
|
||||
//! ## Refspec Patterns
|
||||
//!
|
||||
//! The types
|
||||
//!
|
||||
//! * [`refspec::PatternStr`]
|
||||
//! * [`refspec::PatternString`]
|
||||
//!
|
||||
//! guarantee that their values are valid ref strings but additionally _may_
|
||||
//! contain at most one "*" character. It is thus possible to convert a ref
|
||||
//! string to a refspec pattern, but not the other way round. Refspec patterns
|
||||
//! are commonly used for mapping remote to local refs (cf. [`git-fetch`]).
|
||||
//!
|
||||
//! The `"macro"` feature enables the `refspec::pattern!` macro, which
|
||||
//! constructs a compile-time validated [`refspec::PatternString`].
|
||||
//!
|
||||
//! ## Structured Ref Strings
|
||||
//!
|
||||
//! Ref strings may be [`Qualified`], which essentially means that they start
|
||||
//! with "refs/". [`Qualified`] ref string also require at least three
|
||||
//! components (eg. "refs/heads/main"), which makes it easier to deal with
|
||||
//! common naming conventions.
|
||||
//!
|
||||
//! [`Qualified`] refs may be [`Namespaced`], or can be given a namespace
|
||||
//! (namespaces can be nested). [`Namespaced`] refs are also [`Qualified`], and
|
||||
//! can have their namespace(s) stripped.
|
||||
//!
|
||||
//! # On Git Ref Name Conventions
|
||||
//!
|
||||
//! Git references are essentially path names pointing to their traditional
|
||||
//! storage location in a the repository (`$GIT_DIR/refs`). Unlike (UNIX) file
|
||||
//! paths, they are subject to a few restrictions, as described in
|
||||
//! [`git-check-ref-format`].
|
||||
//!
|
||||
//! On top of that, there are a number of conventions around the hierarchical
|
||||
//! naming, _some_ of which are treated specially by tools such as the `git`
|
||||
//! CLI. For example:
|
||||
//!
|
||||
//! * `refs/heads/..` are also called "branches".
|
||||
//!
|
||||
//! Omitting the "refs/heads/" prefix is typically accepted. Such a branch
|
||||
//! name is also referred to as a "shorthand" ref.
|
||||
//!
|
||||
//! * `refs/tags/..` are assumed to contain tags.
|
||||
//!
|
||||
//! `git` treats tags specially, specifically it insists that they be globally
|
||||
//! unique across all copies of the repository.
|
||||
//!
|
||||
//! * `refs/remotes/../..` is where "remote tracking branches" are stored.
|
||||
//!
|
||||
//! In `git`, the first element after "remotes" is considered the name of the
|
||||
//! [remote][git-remote] (as it appears in the config file), while everything
|
||||
//! after that is considered a shorthand branch. Note, however, that the
|
||||
//! remote name may itself contain '/' separators, so it is not generally
|
||||
//! possible to extract the branch name without access to the config.
|
||||
//!
|
||||
//! * `refs/namespaces/..` is hidden unless [`gitnamespaces`] are in effect.
|
||||
//!
|
||||
//! The structure of namespaces is recursive: they contain full refs, which
|
||||
//! can themselves be namespaces (eg.
|
||||
//! `refs/namespaces/a/refs/namespaces/b/refs/heads/branch`). Note that,
|
||||
//! unlike remote names, namespace names can **not** contain forward slashes
|
||||
//! but there is no tooling which would enforce that.
|
||||
//!
|
||||
//! There are also other such ref hierachies `git` knows about, and this crate
|
||||
//! doesn't attempt to cover all of them. More importantly, `git` does not
|
||||
//! impose any restrictions on ref hierarchies: as long as they don't collide
|
||||
//! with convential ones, applications can introduce any hierchies they want.
|
||||
//!
|
||||
//! This restricts the transformations between conventional refs which can be
|
||||
//! made without additional information besides the ref name: for example, it is
|
||||
//! not generally possible to turn a remote tracking branch into a branch (or a
|
||||
//! shorthand) without knowning about all possible remote names.
|
||||
//!
|
||||
//! Therefore, this crate doesn't attempt to interpret all possible semantics
|
||||
//! associated with refs, and instead tries to make it easy for library
|
||||
//! consumers to do so.
|
||||
//!
|
||||
//! [`git-check-ref-format`]: https://git-scm.com/docs/git-check-ref-format
|
||||
//! [`git-fetch`]: https://git-scm.com/docs/git-fetch
|
||||
//! [git-remote]: https://git-scm.com/docs/git-remote
|
||||
//! [`gitnamespaces`]: https://git-scm.com/docs/gitnamespaces
|
||||
#[cfg(feature = "percent-encoding")]
|
||||
pub use git_ref_format_core::PercentEncode;
|
||||
pub use git_ref_format_core::{
|
||||
check_ref_format,
|
||||
lit,
|
||||
name::component,
|
||||
Component,
|
||||
DuplicateGlob,
|
||||
Error,
|
||||
Namespaced,
|
||||
Options,
|
||||
Qualified,
|
||||
RefStr,
|
||||
RefString,
|
||||
};
|
||||
|
||||
pub mod name {
|
||||
pub use git_ref_format_core::name::*;
|
||||
|
||||
#[cfg(any(feature = "macro", feature = "git-ref-format-macro"))]
|
||||
pub use git_ref_format_macro::component;
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "macro", feature = "git-ref-format-macro"))]
|
||||
pub use git_ref_format_macro::refname;
|
||||
|
||||
pub mod refspec {
|
||||
pub use git_ref_format_core::refspec::*;
|
||||
|
||||
#[cfg(any(feature = "macro", feature = "git-ref-format-macro"))]
|
||||
pub use git_ref_format_macro::pattern;
|
||||
}
|
||||
Reference in New Issue
Block a user