radicle/git/raw: Capture all `git2` re-exports

A refactoring internal to the `radicle` crate, with the goal of
making dependency on `git2` clearer and more controlled.
`radicle::git::raw` is changed from a complete re-export of `git2`
to a module that selectively re-exports (many) members of `git2`.
required to build the workspace (potentially breaking dependents
outside the workspace, but given just how many types are
re-exported, this seems unlikely).

In the future, no more `use git2::…` statements should be added
outside of `crates/radicle/src/git/raw.rs`. This is in an effort to
decrease dependence on `git2` in the future.
This commit is contained in:
Lorenz Leutgeb 2025-10-04 11:59:26 +02:00
parent 633059040c
commit 880634acd4
No known key found for this signature in database
23 changed files with 285 additions and 215 deletions

View File

@ -126,7 +126,7 @@ pub enum ApplyError {
#[error("document does not contain any changes to current identity")] #[error("document does not contain any changes to current identity")]
DocUnchanged, DocUnchanged,
#[error("git: {0}")] #[error("git: {0}")]
Git(#[from] git2::Error), Git(#[from] crate::git::raw::Error),
#[error("git: {0}")] #[error("git: {0}")]
GitExt(#[from] git_ext::Error), GitExt(#[from] git_ext::Error),
#[error("identity document error: {0}")] #[error("identity document error: {0}")]

View File

@ -21,7 +21,7 @@ pub enum OpEncodingError {
#[error("encoding failed: {0}")] #[error("encoding failed: {0}")]
Encoding(#[from] serde_json::Error), Encoding(#[from] serde_json::Error),
#[error("git: {0}")] #[error("git: {0}")]
Git(#[from] git2::Error), Git(#[from] git::raw::Error),
} }
#[derive(Error, Debug)] #[derive(Error, Debug)]

View File

@ -8,6 +8,7 @@ use std::marker::PhantomData;
use serde::Deserialize; use serde::Deserialize;
use crate::git;
use crate::git::Oid; use crate::git::Oid;
use super::{ObjectId, Op, TypeName}; use super::{ObjectId, Op, TypeName};
@ -92,7 +93,7 @@ impl HasRoot for CobRange {
/// ///
/// To construct a `Stream`, use [`Stream::new`]. /// To construct a `Stream`, use [`Stream::new`].
pub struct Stream<'a, A> { pub struct Stream<'a, A> {
repo: &'a git2::Repository, repo: &'a git::raw::Repository,
range: CobRange, range: CobRange,
typename: TypeName, typename: TypeName,
marker: PhantomData<A>, marker: PhantomData<A>,
@ -101,7 +102,7 @@ pub struct Stream<'a, A> {
impl<'a, A> Stream<'a, A> { impl<'a, A> Stream<'a, A> {
/// Construct a new stream providing the underlying `repo`, a [`CobRange`], /// Construct a new stream providing the underlying `repo`, a [`CobRange`],
/// and the [`TypeName`] of the COB that is being streamed. /// and the [`TypeName`] of the COB that is being streamed.
pub fn new(repo: &'a git2::Repository, range: CobRange, typename: TypeName) -> Self { pub fn new(repo: &'a git::raw::Repository, range: CobRange, typename: TypeName) -> Self {
Self { Self {
repo, repo,
range, range,
@ -185,7 +186,7 @@ mod tests {
"xyz.radicle.test".parse::<TypeName>().unwrap() "xyz.radicle.test".parse::<TypeName>().unwrap()
} }
fn gen_ops(repo: &git2::Repository, signer: &MockSigner) -> Vec<cob::Entry> { fn gen_ops(repo: &git::raw::Repository, signer: &MockSigner) -> Vec<cob::Entry> {
// Number of ops // Number of ops
let n = gen::<u8>(1).clamp(1, 10); let n = gen::<u8>(1).clamp(1, 10);
let mut entries = Vec::with_capacity(n.into()); let mut entries = Vec::with_capacity(n.into());
@ -213,7 +214,7 @@ mod tests {
} }
fn create_entry( fn create_entry(
repo: &git2::Repository, repo: &git::raw::Repository,
signer: &MockSigner, signer: &MockSigner,
contents: NonEmpty<Vec<u8>>, contents: NonEmpty<Vec<u8>>,
parent: Option<Oid>, parent: Option<Oid>,

View File

@ -22,7 +22,7 @@ impl Stream {
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum Ops { pub enum Ops {
#[error("failed to get a commit while iterating over stream: {source}")] #[error("failed to get a commit while iterating over stream: {source}")]
Commit { source: git2::Error }, Commit { source: crate::git::raw::Error },
#[error("failed to load COB operation: {source}")] #[error("failed to load COB operation: {source}")]
Load { source: op::LoadError }, Load { source: op::LoadError },
#[error("failed to load COB manifest: {source}")] #[error("failed to load COB manifest: {source}")]

View File

@ -39,7 +39,7 @@ impl From<PatternString> for Until {
/// from. /// from.
pub(super) struct WalkIter<'a> { pub(super) struct WalkIter<'a> {
/// Git repository for looking up the commit object during the revwalk. /// Git repository for looking up the commit object during the revwalk.
repo: &'a git2::Repository, repo: &'a git::raw::Repository,
/// The root commit that is being walked from. /// The root commit that is being walked from.
/// ///
/// N.b. This is required since ranges are non-inclusive in Git, and if the /// N.b. This is required since ranges are non-inclusive in Git, and if the
@ -47,7 +47,7 @@ pub(super) struct WalkIter<'a> {
/// error. /// error.
from: Option<Oid>, from: Option<Oid>,
/// The revwalk that is being iterated over. /// The revwalk that is being iterated over.
inner: git2::Revwalk<'a>, inner: git::raw::Revwalk<'a>,
} }
impl From<CobRange> for Walk { impl From<CobRange> for Walk {
@ -76,10 +76,10 @@ impl Walk {
} }
/// Get the iterator for the walk. /// Get the iterator for the walk.
pub(super) fn iter(self, repo: &git2::Repository) -> Result<WalkIter<'_>, git2::Error> { pub(super) fn iter(self, repo: &git::raw::Repository) -> Result<WalkIter<'_>, git::raw::Error> {
let mut walk = repo.revwalk()?; let mut walk = repo.revwalk()?;
// N.b. ensure that we start from the `self.from` commit. // N.b. ensure that we start from the `self.from` commit.
walk.set_sorting(git2::Sort::TOPOLOGICAL.union(git2::Sort::REVERSE))?; walk.set_sorting(git::raw::Sort::TOPOLOGICAL.union(git::raw::Sort::REVERSE))?;
match self.until { match self.until {
Until::Tip(tip) => walk.push_range(&format!("{}..{}", self.from, tip))?, Until::Tip(tip) => walk.push_range(&format!("{}..{}", self.from, tip))?,
Until::Glob(glob) => { Until::Glob(glob) => {
@ -97,7 +97,7 @@ impl Walk {
} }
impl<'a> Iterator for WalkIter<'a> { impl<'a> Iterator for WalkIter<'a> {
type Item = Result<git2::Commit<'a>, git2::Error>; type Item = Result<git::raw::Commit<'a>, git::raw::Error>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
// N.b. ensure that we start using the `from` commit and use the revwalk // N.b. ensure that we start using the `from` commit and use the revwalk

View File

@ -1,4 +1,5 @@
pub mod canonical; pub mod canonical;
pub mod raw;
use std::io; use std::io;
use std::path::Path; use std::path::Path;
@ -20,7 +21,6 @@ pub use ext::is_not_found_err;
pub use ext::Error; pub use ext::Error;
pub use ext::NotFound; pub use ext::NotFound;
pub use ext::Oid; pub use ext::Oid;
pub use git2 as raw;
pub use git_ext::ref_format as fmt; pub use git_ext::ref_format as fmt;
pub use git_ext::ref_format::{ pub use git_ext::ref_format::{
component, lit, name, qualified, refname, refspec, component, lit, name, qualified, refname, refspec,
@ -173,13 +173,13 @@ pub enum RefError {
err: Box<dyn std::error::Error + Send + Sync + 'static>, err: Box<dyn std::error::Error + Send + Sync + 'static>,
}, },
#[error(transparent)] #[error(transparent)]
Other(#[from] git2::Error), Other(#[from] raw::Error),
} }
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
pub enum ListRefsError { pub enum ListRefsError {
#[error("git error: {0}")] #[error("git error: {0}")]
Git(#[from] git2::Error), Git(#[from] raw::Error),
#[error("invalid ref: {0}")] #[error("invalid ref: {0}")]
InvalidRef(#[from] RefError), InvalidRef(#[from] RefError),
} }
@ -189,7 +189,7 @@ pub mod refs {
use radicle_cob as cob; use radicle_cob as cob;
/// Try to get a qualified reference from a generic reference. /// Try to get a qualified reference from a generic reference.
pub fn qualified_from<'a>(r: &'a git2::Reference) -> Result<(Qualified<'a>, Oid), RefError> { pub fn qualified_from<'a>(r: &'a raw::Reference) -> Result<(Qualified<'a>, Oid), RefError> {
let name = r.name().ok_or(RefError::InvalidName)?; let name = r.name().ok_or(RefError::InvalidName)?;
let refstr = RefStr::try_from_str(name)?; let refstr = RefStr::try_from_str(name)?;
let target = r.resolve()?.target().ok_or(RefError::NoTarget)?; let target = r.resolve()?.target().ok_or(RefError::NoTarget)?;
@ -462,9 +462,9 @@ pub mod refs {
pub fn remote_refs(url: &Url) -> Result<RandomMap<RemoteId, Refs>, ListRefsError> { pub fn remote_refs(url: &Url) -> Result<RandomMap<RemoteId, Refs>, ListRefsError> {
let url = url.to_string(); let url = url.to_string();
let mut remotes = RandomMap::default(); let mut remotes = RandomMap::default();
let mut remote = git2::Remote::create_detached(url)?; let mut remote = raw::Remote::create_detached(url)?;
remote.connect(git2::Direction::Fetch)?; remote.connect(raw::Direction::Fetch)?;
let refs = remote.list()?; let refs = remote.list()?;
for r in refs { for r in refs {
@ -557,9 +557,9 @@ where
/// Create an initial empty commit. /// Create an initial empty commit.
pub fn initial_commit<'a>( pub fn initial_commit<'a>(
repo: &'a git2::Repository, repo: &'a raw::Repository,
sig: &git2::Signature, sig: &raw::Signature,
) -> Result<git2::Commit<'a>, git2::Error> { ) -> Result<raw::Commit<'a>, raw::Error> {
let tree_id = repo.index()?.write_tree()?; let tree_id = repo.index()?.write_tree()?;
let tree = repo.find_tree(tree_id)?; let tree = repo.find_tree(tree_id)?;
let oid = repo.commit(None, sig, sig, "Initial commit", &tree, &[])?; let oid = repo.commit(None, sig, sig, "Initial commit", &tree, &[])?;
@ -570,13 +570,13 @@ pub fn initial_commit<'a>(
/// Create a commit and update the given ref to it. /// Create a commit and update the given ref to it.
pub fn commit<'a>( pub fn commit<'a>(
repo: &'a git2::Repository, repo: &'a raw::Repository,
parent: &'a git2::Commit, parent: &'a raw::Commit,
target: &RefStr, target: &RefStr,
message: &str, message: &str,
sig: &git2::Signature, sig: &raw::Signature,
tree: &git2::Tree, tree: &raw::Tree,
) -> Result<git2::Commit<'a>, git2::Error> { ) -> Result<raw::Commit<'a>, raw::Error> {
let oid = repo.commit(Some(target.as_str()), sig, sig, message, tree, &[parent])?; let oid = repo.commit(Some(target.as_str()), sig, sig, message, tree, &[parent])?;
let commit = repo.find_commit(oid)?; let commit = repo.find_commit(oid)?;
@ -585,12 +585,12 @@ pub fn commit<'a>(
/// Create an empty commit on top of the parent. /// Create an empty commit on top of the parent.
pub fn empty_commit<'a>( pub fn empty_commit<'a>(
repo: &'a git2::Repository, repo: &'a raw::Repository,
parent: &'a git2::Commit, parent: &'a raw::Commit,
target: &RefStr, target: &RefStr,
message: &str, message: &str,
sig: &git2::Signature, sig: &raw::Signature,
) -> Result<git2::Commit<'a>, git2::Error> { ) -> Result<raw::Commit<'a>, raw::Error> {
let tree = parent.tree()?; let tree = parent.tree()?;
let oid = repo.commit(Some(target.as_str()), sig, sig, message, &tree, &[parent])?; let oid = repo.commit(Some(target.as_str()), sig, sig, message, &tree, &[parent])?;
let commit = repo.find_commit(oid)?; let commit = repo.find_commit(oid)?;
@ -599,7 +599,7 @@ pub fn empty_commit<'a>(
} }
/// Get the repository head. /// Get the repository head.
pub fn head(repo: &git2::Repository) -> Result<git2::Commit, git2::Error> { pub fn head(repo: &raw::Repository) -> Result<raw::Commit, raw::Error> {
let head = repo.head()?.peel_to_commit()?; let head = repo.head()?.peel_to_commit()?;
Ok(head) Ok(head)
@ -609,8 +609,8 @@ pub fn head(repo: &git2::Repository) -> Result<git2::Commit, git2::Error> {
pub fn write_tree<'r>( pub fn write_tree<'r>(
path: &Path, path: &Path,
bytes: &[u8], bytes: &[u8],
repo: &'r git2::Repository, repo: &'r raw::Repository,
) -> Result<git2::Tree<'r>, Error> { ) -> Result<raw::Tree<'r>, Error> {
let blob_id = repo.blob(bytes)?; let blob_id = repo.blob(bytes)?;
let mut builder = repo.treebuilder(None)?; let mut builder = repo.treebuilder(None)?;
builder.insert(path, blob_id, 0o100_644)?; builder.insert(path, blob_id, 0o100_644)?;
@ -624,7 +624,7 @@ pub fn write_tree<'r>(
/// Configure a radicle repository. /// Configure a radicle repository.
/// ///
/// * Sets `push.default = upstream`. /// * Sets `push.default = upstream`.
pub fn configure_repository(repo: &git2::Repository) -> Result<(), git2::Error> { pub fn configure_repository(repo: &raw::Repository) -> Result<(), raw::Error> {
let mut cfg = repo.config()?; let mut cfg = repo.config()?;
cfg.set_str("push.default", "upstream")?; cfg.set_str("push.default", "upstream")?;
@ -652,11 +652,11 @@ pub fn configure_repository(repo: &git2::Repository) -> Result<(), git2::Error>
/// 2. `tagOpt = --no-tags` to ensure that tags are not fetched and stored /// 2. `tagOpt = --no-tags` to ensure that tags are not fetched and stored
/// under `refs/tags`, again, because these are fetched by the `rad` remote. /// under `refs/tags`, again, because these are fetched by the `rad` remote.
pub fn configure_remote<'r>( pub fn configure_remote<'r>(
repo: &'r git2::Repository, repo: &'r raw::Repository,
name: &str, name: &str,
fetch: &Url, fetch: &Url,
push: &Url, push: &Url,
) -> Result<git2::Remote<'r>, git2::Error> { ) -> Result<raw::Remote<'r>, raw::Error> {
let fetchspec = format!("+refs/heads/*:refs/remotes/{name}/*"); let fetchspec = format!("+refs/heads/*:refs/remotes/{name}/*");
let remote = repo.remote_with_fetch(name, fetch.to_string().as_str(), &fetchspec)?; let remote = repo.remote_with_fetch(name, fetch.to_string().as_str(), &fetchspec)?;
@ -679,14 +679,14 @@ pub fn configure_remote<'r>(
} }
/// Fetch from the given `remote`. /// Fetch from the given `remote`.
pub fn fetch(repo: &git2::Repository, remote: &str) -> Result<(), git2::Error> { pub fn fetch(repo: &raw::Repository, remote: &str) -> Result<(), raw::Error> {
repo.find_remote(remote)?.fetch::<&str>( repo.find_remote(remote)?.fetch::<&str>(
&[], &[],
Some( Some(
git2::FetchOptions::new() raw::FetchOptions::new()
.update_fetchhead(false) .update_fetchhead(false)
.prune(git2::FetchPrune::On) .prune(raw::FetchPrune::On)
.download_tags(git2::AutotagOption::None), .download_tags(raw::AutotagOption::None),
), ),
None, None,
) )
@ -694,10 +694,10 @@ pub fn fetch(repo: &git2::Repository, remote: &str) -> Result<(), git2::Error> {
/// Push `refspecs` to the given `remote` using the provided `namespace`. /// Push `refspecs` to the given `remote` using the provided `namespace`.
pub fn push<'a>( pub fn push<'a>(
repo: &git2::Repository, repo: &raw::Repository,
remote: &str, remote: &str,
refspecs: impl IntoIterator<Item = (&'a Qualified<'a>, &'a Qualified<'a>)>, refspecs: impl IntoIterator<Item = (&'a Qualified<'a>, &'a Qualified<'a>)>,
) -> Result<(), git2::Error> { ) -> Result<(), raw::Error> {
let refspecs = refspecs let refspecs = refspecs
.into_iter() .into_iter()
.map(|(src, dst)| format!("{src}:{dst}")); .map(|(src, dst)| format!("{src}:{dst}"));
@ -719,11 +719,11 @@ pub fn push<'a>(
/// merge = refs/heads/main /// merge = refs/heads/main
/// ``` /// ```
pub fn set_upstream( pub fn set_upstream(
repo: &git2::Repository, repo: &raw::Repository,
remote: impl AsRef<str>, remote: impl AsRef<str>,
branch: impl AsRef<str>, branch: impl AsRef<str>,
merge: impl AsRef<str>, merge: impl AsRef<str>,
) -> Result<(), git2::Error> { ) -> Result<(), raw::Error> {
let remote = remote.as_ref(); let remote = remote.as_ref();
let branch = branch.as_ref(); let branch = branch.as_ref();
let merge = merge.as_ref(); let merge = merge.as_ref();
@ -752,14 +752,14 @@ pub fn set_upstream(
Ok(()) Ok(())
} }
pub fn init_default_branch(repo: &git2::Repository) -> Result<Option<String>, git2::Error> { pub fn init_default_branch(repo: &raw::Repository) -> Result<Option<String>, raw::Error> {
let config = repo.config().and_then(|mut c| c.snapshot())?; let config = repo.config().and_then(|mut c| c.snapshot())?;
let default_branch = config.get_str("init.defaultbranch")?; let default_branch = config.get_str("init.defaultbranch")?;
let branch = repo.find_branch(default_branch, git2::BranchType::Local)?; let branch = repo.find_branch(default_branch, raw::BranchType::Local)?;
Ok(branch.into_reference().shorthand().map(ToOwned::to_owned)) Ok(branch.into_reference().shorthand().map(ToOwned::to_owned))
} }
pub fn head_refname(repo: &git2::Repository) -> Result<Option<String>, git2::Error> { pub fn head_refname(repo: &raw::Repository) -> Result<Option<String>, raw::Error> {
let head = repo.head()?; let head = repo.head()?;
match head.shorthand() { match head.shorthand() {
Some("HEAD") => Ok(None), Some("HEAD") => Ok(None),

View File

@ -167,7 +167,7 @@ pub struct GraphDescendant {
// `git2` implementations of the above effects // `git2` implementations of the above effects
// =========================================== // ===========================================
impl FindMergeBase for git2::Repository { impl FindMergeBase for git::raw::Repository {
fn merge_base(&self, a: Oid, b: Oid) -> Result<MergeBase, MergeBaseError> { fn merge_base(&self, a: Oid, b: Oid) -> Result<MergeBase, MergeBaseError> {
self.merge_base(*a, *b) self.merge_base(*a, *b)
.map_err(|err| MergeBaseError { .map_err(|err| MergeBaseError {
@ -183,7 +183,7 @@ impl FindMergeBase for git2::Repository {
} }
} }
impl Ancestry for git2::Repository { impl Ancestry for git::raw::Repository {
fn graph_ahead_behind( fn graph_ahead_behind(
&self, &self,
commit: Oid, commit: Oid,
@ -199,7 +199,7 @@ impl Ancestry for git2::Repository {
} }
} }
impl FindObjects for git2::Repository { impl FindObjects for git::raw::Repository {
fn find_objects<'a, 'b, I>( fn find_objects<'a, 'b, I>(
&self, &self,
refname: &Qualified, refname: &Qualified,

View File

@ -780,7 +780,7 @@ mod tests {
doc.delegates().clone() doc.delegates().clone()
} }
fn tag(name: RefString, head: git2::Oid, repo: &git2::Repository) -> git::Oid { fn tag(name: RefString, head: git::raw::Oid, repo: &git::raw::Repository) -> git::Oid {
let commit = fixtures::commit(name.as_str(), &[head], repo); let commit = fixtures::commit(name.as_str(), &[head], repo);
let target = repo.find_object(*commit, None).unwrap(); let target = repo.find_object(*commit, None).unwrap();
let tagger = repo.signature().unwrap(); let tagger = repo.signature().unwrap();

View File

@ -0,0 +1,34 @@
//! This module re-exports selected items from the [`git2`] crate and provides
//! an extension trait for its [`git2::Error`] type to more conveniently handle
//! errors associated with the code [`git2::ErrorCode::NotFound`].
//!
// Re-exports created by manually scanning the `heartwood` workspace on 2025-10-04.
// Re-exports that are only used within this crate.
pub(crate) use git2::{
message_trailers_strs, AutotagOption, Blob, Config, FetchOptions, FetchPrune, Object,
RemoteCallbacks, Revwalk, Sort,
};
// Re-exports that are used by other crates in the workspace, including this crate.
pub use git2::{
Branch, BranchType, Commit, Direction, Error, ErrorClass, ErrorCode, FileMode, ObjectType, Oid,
Reference, Remote, Repository, RepositoryInitOptions, RepositoryOpenFlags, Signature, Time,
Tree,
};
// Re-exports that are used by other crates in the workspace, but *not* this crate.
pub use git2::{
AnnotatedCommit, Diff, DiffFindOptions, DiffOptions, DiffStats, MergeAnalysis, MergeOptions,
};
// Re-exports for `radicle-cli`.
pub mod build {
pub use git2::build::CheckoutBuilder;
}
pub(crate) mod transport {
pub use git2::transport::{
register, Service, SmartSubtransport, SmartSubtransportStream, Transport,
};
}

View File

@ -54,7 +54,7 @@ pub enum DocError {
#[error("git: {0}")] #[error("git: {0}")]
GitExt(#[from] git::Error), GitExt(#[from] git::Error),
#[error("git: {0}")] #[error("git: {0}")]
Git(#[from] git2::Error), Git(#[from] git::raw::Error),
#[error("missing identity document")] #[error("missing identity document")]
Missing, Missing,
} }
@ -687,7 +687,7 @@ impl Doc {
} }
/// Construct a [`Doc`] contained in the provided Git blob. /// Construct a [`Doc`] contained in the provided Git blob.
pub fn from_blob(blob: &git2::Blob) -> Result<Self, DocError> { pub fn from_blob(blob: &git::raw::Blob) -> Result<Self, DocError> {
RawDoc::from_json(blob.content())?.verified() RawDoc::from_json(blob.content())?.verified()
} }
@ -830,7 +830,7 @@ impl Doc {
pub(crate) fn blob_at<R: ReadRepository>( pub(crate) fn blob_at<R: ReadRepository>(
commit: Oid, commit: Oid,
repo: &R, repo: &R,
) -> Result<git2::Blob, DocError> { ) -> Result<git::raw::Blob, DocError> {
let path = Path::new("embeds").join(*PATH); let path = Path::new("embeds").join(*PATH);
repo.blob_at(commit, path.as_path()).map_err(DocError::from) repo.blob_at(commit, path.as_path()).map_err(DocError::from)
} }
@ -843,7 +843,7 @@ impl Doc {
serde_json::Serializer::with_formatter(&mut buf, CanonicalFormatter::new()); serde_json::Serializer::with_formatter(&mut buf, CanonicalFormatter::new());
self.serialize(&mut serializer)?; self.serialize(&mut serializer)?;
let oid = git2::Oid::hash_object(git2::ObjectType::Blob, &buf)?; let oid = git::raw::Oid::hash_object(git::raw::ObjectType::Blob, &buf)?;
Ok((oid.into(), buf)) Ok((oid.into(), buf))
} }
@ -1157,7 +1157,7 @@ mod test {
let remote = arbitrary::gen::<RemoteId>(1); let remote = arbitrary::gen::<RemoteId>(1);
let proj = arbitrary::gen::<RepoId>(1); let proj = arbitrary::gen::<RepoId>(1);
let repo = storage.create(proj).unwrap(); let repo = storage.create(proj).unwrap();
let oid = git2::Oid::from_str("2d52a53ce5e4f141148a5f770cfd3ead2d6a45b8").unwrap(); let oid = git::raw::Oid::from_str("2d52a53ce5e4f141148a5f770cfd3ead2d6a45b8").unwrap();
let err = repo.identity_head_of(&remote).unwrap_err(); let err = repo.identity_head_of(&remote).unwrap_err();
matches!(err, git::ext::Error::NotFound(_)); matches!(err, git::ext::Error::NotFound(_));

View File

@ -13,7 +13,7 @@ pub const RAD_PREFIX: &str = "rad:";
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum IdError { pub enum IdError {
#[error("invalid git object id: {0}")] #[error("invalid git object id: {0}")]
InvalidOid(#[from] git2::Error), InvalidOid(#[from] git::raw::Error),
#[error(transparent)] #[error(transparent)]
Multibase(#[from] multibase::Error), Multibase(#[from] multibase::Error),
} }
@ -102,8 +102,8 @@ impl From<git::Oid> for RepoId {
} }
} }
impl From<git2::Oid> for RepoId { impl From<git::raw::Oid> for RepoId {
fn from(oid: git2::Oid) -> Self { fn from(oid: git::raw::Oid) -> Self {
Self(oid.into()) Self(oid.into())
} }
} }

View File

@ -88,7 +88,7 @@ pub mod env {
/// Get the configured pager program from the environment. /// Get the configured pager program from the environment.
pub fn pager() -> Option<String> { pub fn pager() -> Option<String> {
if let Ok(cfg) = git2::Config::open_default() { if let Ok(cfg) = crate::git::raw::Config::open_default() {
if let Ok(pager) = cfg.get_string("core.pager") { if let Ok(pager) = cfg.get_string("core.pager") {
return Some(pager); return Some(pager);
} }

View File

@ -39,7 +39,7 @@ pub enum InitError {
#[error("project payload: {0}")] #[error("project payload: {0}")]
ProjectPayload(String), ProjectPayload(String),
#[error("git: {0}")] #[error("git: {0}")]
Git(#[from] git2::Error), Git(#[from] git::raw::Error),
#[error("i/o: {0}")] #[error("i/o: {0}")]
Io(#[from] io::Error), Io(#[from] io::Error),
#[error("storage: {0}")] #[error("storage: {0}")]
@ -48,7 +48,7 @@ pub enum InitError {
/// Initialize a new radicle project from a git repository. /// Initialize a new radicle project from a git repository.
pub fn init<G, S>( pub fn init<G, S>(
repo: &git2::Repository, repo: &git::raw::Repository,
name: ProjectName, name: ProjectName,
description: &str, description: &str,
default_branch: BranchName, default_branch: BranchName,
@ -96,7 +96,7 @@ where
} }
fn init_configure<G>( fn init_configure<G>(
repo: &git2::Repository, repo: &git::raw::Repository,
stored: &Repository, stored: &Repository,
default_branch: &BranchName, default_branch: &BranchName,
url: &git::Url, url: &git::Url,
@ -152,7 +152,7 @@ where
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum ForkError { pub enum ForkError {
#[error("git: {0}")] #[error("git: {0}")]
Git(#[from] git2::Error), Git(#[from] git::raw::Error),
#[error("storage: {0}")] #[error("storage: {0}")]
Storage(#[from] storage::Error), Storage(#[from] storage::Error),
#[error("payload: {0}")] #[error("payload: {0}")]
@ -236,7 +236,7 @@ pub enum CheckoutError {
stdout: String, stdout: String,
}, },
#[error("git: {0}")] #[error("git: {0}")]
Git(#[from] git2::Error), Git(#[from] git::raw::Error),
#[error("payload: {0}")] #[error("payload: {0}")]
Payload(#[from] doc::PayloadError), Payload(#[from] doc::PayloadError),
#[error("repository `{0}` was not found in storage")] #[error("repository `{0}` was not found in storage")]
@ -253,19 +253,19 @@ pub fn checkout<P: AsRef<Path>, S: storage::ReadStorage>(
path: P, path: P,
storage: &S, storage: &S,
bare: bool, bare: bool,
) -> Result<git2::Repository, CheckoutError> { ) -> Result<git::raw::Repository, CheckoutError> {
// TODO: Decide on whether we can use `clone_local` // TODO: Decide on whether we can use `clone_local`
// TODO: Look into sharing object databases. // TODO: Look into sharing object databases.
let doc = storage.get(proj)?.ok_or(CheckoutError::NotFound(proj))?; let doc = storage.get(proj)?.ok_or(CheckoutError::NotFound(proj))?;
let project = doc.project()?; let project = doc.project()?;
let mut opts = git2::RepositoryInitOptions::new(); let mut opts = git::raw::RepositoryInitOptions::new();
opts.no_reinit(true) opts.no_reinit(true)
.external_template(false) .external_template(false)
.description(project.description()) .description(project.description())
.bare(bare); .bare(bare);
let repo = git2::Repository::init_opts(path.as_ref(), &opts)?; let repo = git::raw::Repository::init_opts(path.as_ref(), &opts)?;
let url = git::Url::from(proj); let url = git::Url::from(proj);
// Configure repository for radicle. // Configure repository for radicle.
@ -335,7 +335,7 @@ pub fn checkout<P: AsRef<Path>, S: storage::ReadStorage>(
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum RemoteError { pub enum RemoteError {
#[error("git: {0}")] #[error("git: {0}")]
Git(#[from] git2::Error), Git(#[from] git::raw::Error),
#[error("invalid remote url: {0}")] #[error("invalid remote url: {0}")]
Url(#[from] transport::local::UrlError), Url(#[from] transport::local::UrlError),
#[error("invalid utf-8 string")] #[error("invalid utf-8 string")]
@ -347,9 +347,9 @@ pub enum RemoteError {
} }
/// Get the radicle ("rad") remote of a repository, and return the associated project id. /// Get the radicle ("rad") remote of a repository, and return the associated project id.
pub fn remote(repo: &git2::Repository) -> Result<(git2::Remote<'_>, RepoId), RemoteError> { pub fn remote(repo: &git::raw::Repository) -> Result<(git::raw::Remote<'_>, RepoId), RemoteError> {
let remote = repo.find_remote(&REMOTE_NAME).map_err(|e| { let remote = repo.find_remote(&REMOTE_NAME).map_err(|e| {
if e.code() == git2::ErrorCode::NotFound { if e.code() == git::raw::ErrorCode::NotFound {
RemoteError::NotFound(REMOTE_NAME.to_string()) RemoteError::NotFound(REMOTE_NAME.to_string())
} else { } else {
RemoteError::from(e) RemoteError::from(e)
@ -362,9 +362,9 @@ pub fn remote(repo: &git2::Repository) -> Result<(git2::Remote<'_>, RepoId), Rem
} }
/// Delete the radicle ("rad") remote of a repository. /// Delete the radicle ("rad") remote of a repository.
pub fn remove_remote(repo: &git2::Repository) -> Result<(), RemoteError> { pub fn remove_remote(repo: &git::raw::Repository) -> Result<(), RemoteError> {
repo.remote_delete(&REMOTE_NAME).map_err(|e| { repo.remote_delete(&REMOTE_NAME).map_err(|e| {
if e.code() == git2::ErrorCode::NotFound { if e.code() == git::raw::ErrorCode::NotFound {
RemoteError::NotFound(REMOTE_NAME.to_string()) RemoteError::NotFound(REMOTE_NAME.to_string())
} else { } else {
RemoteError::from(e) RemoteError::from(e)
@ -380,7 +380,7 @@ pub enum CwdError {
#[error("Detection failed (git: '{git}', jj: '{jj}')")] #[error("Detection failed (git: '{git}', jj: '{jj}')")]
Detection { Detection {
git: git2::Error, git: git::raw::Error,
jj: JujutsuGitRootError, jj: JujutsuGitRootError,
}, },
} }
@ -395,7 +395,7 @@ pub enum CwdError {
/// This function should only perform read operations since we do not /// This function should only perform read operations since we do not
/// want to modify the wrong repository in the case that it found a /// want to modify the wrong repository in the case that it found a
/// Git repository that is not a Radicle repository. /// Git repository that is not a Radicle repository.
pub fn cwd() -> Result<(git2::Repository, RepoId), CwdError> { pub fn cwd() -> Result<(git::raw::Repository, RepoId), CwdError> {
let repo = let repo =
repo().or_else(|git| repo_jj_git_root().map_err(|jj| CwdError::Detection { git, jj }))?; repo().or_else(|git| repo_jj_git_root().map_err(|jj| CwdError::Detection { git, jj }))?;
@ -404,23 +404,23 @@ pub fn cwd() -> Result<(git2::Repository, RepoId), CwdError> {
} }
/// Get the repository of project in specified directory /// Get the repository of project in specified directory
pub fn at(path: impl AsRef<Path>) -> Result<(git2::Repository, RepoId), RemoteError> { pub fn at(path: impl AsRef<Path>) -> Result<(git::raw::Repository, RepoId), RemoteError> {
let repo = git2::Repository::open(path)?; let repo = git::raw::Repository::open(path)?;
let (_, id) = remote(&repo)?; let (_, id) = remote(&repo)?;
Ok((repo, id)) Ok((repo, id))
} }
/// Get the current Git repository. /// Get the current Git repository.
pub fn repo() -> Result<git2::Repository, git2::Error> { pub fn repo() -> Result<git::raw::Repository, git::raw::Error> {
let mut flags = git2::RepositoryOpenFlags::empty(); let mut flags = git::raw::RepositoryOpenFlags::empty();
// Allow to search upwards. // Allow to search upwards.
flags.set(git2::RepositoryOpenFlags::NO_SEARCH, false); flags.set(git::raw::RepositoryOpenFlags::NO_SEARCH, false);
// Allow to use `GIT_DIR` env. // Allow to use `GIT_DIR` env.
flags.set(git2::RepositoryOpenFlags::FROM_ENV, true); flags.set(git::raw::RepositoryOpenFlags::FROM_ENV, true);
let ceilings: &[&str] = &[]; let ceilings: &[&str] = &[];
let repo = git2::Repository::open_ext(Path::new("."), flags, ceilings)?; let repo = git::raw::Repository::open_ext(Path::new("."), flags, ceilings)?;
Ok(repo) Ok(repo)
} }
@ -428,7 +428,7 @@ pub fn repo() -> Result<git2::Repository, git2::Error> {
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum JujutsuGitRootError { pub enum JujutsuGitRootError {
#[error("git: {0}")] #[error("git: {0}")]
Git(#[from] git2::Error), Git(#[from] git::raw::Error),
#[error("i/o: {0}")] #[error("i/o: {0}")]
Io(#[from] io::Error), Io(#[from] io::Error),
@ -438,7 +438,7 @@ pub enum JujutsuGitRootError {
} }
/// Get the Git repo underlying the current Jujutsu repository. /// Get the Git repo underlying the current Jujutsu repository.
pub fn repo_jj_git_root() -> Result<git2::Repository, JujutsuGitRootError> { pub fn repo_jj_git_root() -> Result<git::raw::Repository, JujutsuGitRootError> {
let output = std::process::Command::new("jj") let output = std::process::Command::new("jj")
.args(["git", "root"]) .args(["git", "root"])
.output()?; .output()?;
@ -450,7 +450,7 @@ pub fn repo_jj_git_root() -> Result<git2::Repository, JujutsuGitRootError> {
} }
let path = std::path::PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string().trim()); let path = std::path::PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string().trim());
Ok(git2::Repository::open(path)?) Ok(git::raw::Repository::open(path)?)
} }
/// Setup patch upstream branch such that `git push` updates the patch. /// Setup patch upstream branch such that `git push` updates the patch.

View File

@ -94,12 +94,12 @@ pub(crate) mod git {
/// See [`crate::git::Oid`] /// See [`crate::git::Oid`]
/// See [`::git_ext::Oid`] /// See [`::git_ext::Oid`]
/// See [`::git2::Oid`] /// See [`::git::raw::Oid`]
/// ///
/// A Git Object Identifier in hexadecimal encoding. /// A Git Object Identifier in hexadecimal encoding.
#[derive(JsonSchema)] #[derive(JsonSchema)]
#[schemars( #[schemars(
remote = "git2::Oid", remote = "git::raw::Oid",
description = "A Git Object Identifier (SHA-1 or SHA-256 hash) in hexadecimal encoding." description = "A Git Object Identifier (SHA-1 or SHA-256 hash) in hexadecimal encoding."
)] )]
pub(crate) struct Oid( pub(crate) struct Oid(

View File

@ -153,7 +153,7 @@ pub enum Error {
#[error(transparent)] #[error(transparent)]
Refs(#[from] refs::Error), Refs(#[from] refs::Error),
#[error("git: {0}")] #[error("git: {0}")]
Git(#[from] git2::Error), Git(#[from] git::raw::Error),
#[error("git: {0}")] #[error("git: {0}")]
Ext(#[from] git::ext::Error), Ext(#[from] git::ext::Error),
#[error("invalid repository identifier {0:?}")] #[error("invalid repository identifier {0:?}")]
@ -179,7 +179,7 @@ impl Error {
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
pub enum FetchError { pub enum FetchError {
#[error("git: {0}")] #[error("git: {0}")]
Git(#[from] git2::Error), Git(#[from] git::raw::Error),
#[error("i/o: {0}")] #[error("i/o: {0}")]
Io(#[from] io::Error), Io(#[from] io::Error),
#[error(transparent)] #[error(transparent)]
@ -503,16 +503,20 @@ pub trait ReadRepository: Sized + ValidateRepository {
fn id(&self) -> RepoId; fn id(&self) -> RepoId;
/// Returns `true` if there are no references in the repository. /// Returns `true` if there are no references in the repository.
fn is_empty(&self) -> Result<bool, git2::Error>; fn is_empty(&self) -> Result<bool, git::raw::Error>;
/// The [`Path`] to the git repository. /// The [`Path`] to the git repository.
fn path(&self) -> &Path; fn path(&self) -> &Path;
/// Get a blob in this repository at the given commit and path. /// Get a blob in this repository at the given commit and path.
fn blob_at<P: AsRef<Path>>(&self, commit: Oid, path: P) -> Result<git2::Blob, git_ext::Error>; fn blob_at<P: AsRef<Path>>(
&self,
commit: Oid,
path: P,
) -> Result<git::raw::Blob, git_ext::Error>;
/// Get a blob in this repository, given its id. /// Get a blob in this repository, given its id.
fn blob(&self, oid: Oid) -> Result<git2::Blob, git_ext::Error>; fn blob(&self, oid: Oid) -> Result<git::raw::Blob, git_ext::Error>;
/// Get the head of this repository. /// Get the head of this repository.
/// ///
@ -572,18 +576,18 @@ pub trait ReadRepository: Sized + ValidateRepository {
&self, &self,
remote: &RemoteId, remote: &RemoteId,
reference: &Qualified, reference: &Qualified,
) -> Result<git2::Reference, git_ext::Error>; ) -> Result<git::raw::Reference, git_ext::Error>;
/// Get the [`git2::Commit`] found using its `oid`. /// Get the [`git::raw::Commit`] found using its `oid`.
/// ///
/// Returns `Err` if the commit did not exist. /// Returns `Err` if the commit did not exist.
fn commit(&self, oid: Oid) -> Result<git2::Commit, git::ext::Error>; fn commit(&self, oid: Oid) -> Result<git::raw::Commit, git::ext::Error>;
/// Perform a revision walk of a commit history starting from the given head. /// Perform a revision walk of a commit history starting from the given head.
fn revwalk(&self, head: Oid) -> Result<git2::Revwalk, git2::Error>; fn revwalk(&self, head: Oid) -> Result<git::raw::Revwalk, git::raw::Error>;
/// Check if the underlying ODB contains the given `oid`. /// Check if the underlying ODB contains the given `oid`.
fn contains(&self, oid: Oid) -> Result<bool, git2::Error>; fn contains(&self, oid: Oid) -> Result<bool, git::raw::Error>;
/// Check whether the given commit is an ancestor of another commit. /// Check whether the given commit is an ancestor of another commit.
fn is_ancestor_of(&self, ancestor: Oid, head: Oid) -> Result<bool, git::ext::Error>; fn is_ancestor_of(&self, ancestor: Oid, head: Oid) -> Result<bool, git::ext::Error>;
@ -692,7 +696,7 @@ pub trait WriteRepository: ReadRepository + SignRepository {
/// Set the user info of the Git repository. /// Set the user info of the Git repository.
fn set_user(&self, info: &UserInfo) -> Result<(), Error>; fn set_user(&self, info: &UserInfo) -> Result<(), Error>;
/// Get the underlying git repository. /// Get the underlying git repository.
fn raw(&self) -> &git2::Repository; fn raw(&self) -> &git::raw::Repository;
} }
/// Allows signing refs. /// Allows signing refs.

View File

@ -56,10 +56,10 @@ pub struct Ref {
pub namespace: Option<RemoteId>, pub namespace: Option<RemoteId>,
} }
impl TryFrom<git2::Reference<'_>> for Ref { impl TryFrom<git::raw::Reference<'_>> for Ref {
type Error = RefError; type Error = RefError;
fn try_from(r: git2::Reference) -> Result<Self, Self::Error> { fn try_from(r: git::raw::Reference) -> Result<Self, Self::Error> {
let name = r.name().ok_or(RefError::InvalidName)?; let name = r.name().ok_or(RefError::InvalidName)?;
let (namespace, name) = match git::parse_ref_namespaced::<RemoteId>(name) { let (namespace, name) = match git::parse_ref_namespaced::<RemoteId>(name) {
Ok((namespace, refname)) => (Some(namespace), refname.to_ref_string()), Ok((namespace, refname)) => (Some(namespace), refname.to_ref_string()),
@ -279,7 +279,7 @@ pub struct Repository {
/// The repository identifier (RID). /// The repository identifier (RID).
pub id: RepoId, pub id: RepoId,
/// The backing Git repository. /// The backing Git repository.
pub backend: git2::Repository, pub backend: git::raw::Repository,
} }
impl AsRef<Repository> for Repository { impl AsRef<Repository> for Repository {
@ -380,12 +380,12 @@ pub enum Validation {
impl Repository { impl Repository {
/// Open an existing repository. /// Open an existing repository.
pub fn open<P: AsRef<Path>>(path: P, id: RepoId) -> Result<Self, RepositoryError> { pub fn open<P: AsRef<Path>>(path: P, id: RepoId) -> Result<Self, RepositoryError> {
let backend = git2::Repository::open_ext( let backend = git::raw::Repository::open_ext(
path.as_ref(), path.as_ref(),
git2::RepositoryOpenFlags::empty() git::raw::RepositoryOpenFlags::empty()
| git2::RepositoryOpenFlags::BARE | git::raw::RepositoryOpenFlags::BARE
| git2::RepositoryOpenFlags::NO_DOTGIT | git::raw::RepositoryOpenFlags::NO_DOTGIT
| git2::RepositoryOpenFlags::NO_SEARCH, | git::raw::RepositoryOpenFlags::NO_SEARCH,
&[] as &[&std::ffi::OsStr], &[] as &[&std::ffi::OsStr],
)?; )?;
@ -394,9 +394,9 @@ impl Repository {
/// Create a new repository. /// Create a new repository.
pub fn create<P: AsRef<Path>>(path: P, id: RepoId, info: &UserInfo) -> Result<Self, Error> { pub fn create<P: AsRef<Path>>(path: P, id: RepoId, info: &UserInfo) -> Result<Self, Error> {
let backend = git2::Repository::init_opts( let backend = git::raw::Repository::init_opts(
&path, &path,
git2::RepositoryInitOptions::new() git::raw::RepositoryInitOptions::new()
.bare(true) .bare(true)
.no_reinit(true) .no_reinit(true)
.external_template(false), .external_template(false),
@ -506,7 +506,7 @@ impl Repository {
/// Iterate over all references. /// Iterate over all references.
pub fn references( pub fn references(
&self, &self,
) -> Result<impl Iterator<Item = Result<Ref, refs::Error>> + '_, git2::Error> { ) -> Result<impl Iterator<Item = Result<Ref, refs::Error>> + '_, git::raw::Error> {
let refs = self let refs = self
.backend .backend
.references()? .references()?
@ -539,7 +539,7 @@ impl Repository {
pub fn remote_ids( pub fn remote_ids(
&self, &self,
) -> Result<impl Iterator<Item = Result<RemoteId, refs::Error>> + '_, git2::Error> { ) -> Result<impl Iterator<Item = Result<RemoteId, refs::Error>> + '_, git::raw::Error> {
let iter = self.backend.references_glob(SIGREFS_GLOB.as_str())?.map( let iter = self.backend.references_glob(SIGREFS_GLOB.as_str())?.map(
|reference| -> Result<RemoteId, refs::Error> { |reference| -> Result<RemoteId, refs::Error> {
let r = reference?; let r = reference?;
@ -556,7 +556,7 @@ impl Repository {
&self, &self,
) -> Result< ) -> Result<
impl Iterator<Item = Result<(RemoteId, Remote<Verified>), refs::Error>> + '_, impl Iterator<Item = Result<(RemoteId, Remote<Verified>), refs::Error>> + '_,
git2::Error, git::raw::Error,
> { > {
let remotes = let remotes =
self.backend self.backend
@ -652,7 +652,7 @@ impl ReadRepository for Repository {
self.id self.id
} }
fn is_empty(&self) -> Result<bool, git2::Error> { fn is_empty(&self) -> Result<bool, git::raw::Error> {
Ok(self.remotes()?.next().is_none()) Ok(self.remotes()?.next().is_none())
} }
@ -660,7 +660,7 @@ impl ReadRepository for Repository {
self.backend.path() self.backend.path()
} }
fn blob_at<P: AsRef<Path>>(&self, commit: Oid, path: P) -> Result<git2::Blob, git::Error> { fn blob_at<P: AsRef<Path>>(&self, commit: Oid, path: P) -> Result<git::raw::Blob, git::Error> {
let commit = self.backend.find_commit(*commit)?; let commit = self.backend.find_commit(*commit)?;
let tree = commit.tree()?; let tree = commit.tree()?;
let entry = tree.get_path(path.as_ref())?; let entry = tree.get_path(path.as_ref())?;
@ -674,7 +674,7 @@ impl ReadRepository for Repository {
Ok(blob) Ok(blob)
} }
fn blob(&self, oid: Oid) -> Result<git2::Blob, git::Error> { fn blob(&self, oid: Oid) -> Result<git::raw::Blob, git::Error> {
self.backend.find_blob(oid.into()).map_err(git::Error::from) self.backend.find_blob(oid.into()).map_err(git::Error::from)
} }
@ -682,7 +682,7 @@ impl ReadRepository for Repository {
&self, &self,
remote: &RemoteId, remote: &RemoteId,
name: &git::Qualified, name: &git::Qualified,
) -> Result<git2::Reference, git::Error> { ) -> Result<git::raw::Reference, git::Error> {
let name = name.with_namespace(remote.into()); let name = name.with_namespace(remote.into());
self.backend.find_reference(&name).map_err(git::Error::from) self.backend.find_reference(&name).map_err(git::Error::from)
} }
@ -698,13 +698,13 @@ impl ReadRepository for Repository {
Ok(oid.into()) Ok(oid.into())
} }
fn commit(&self, oid: Oid) -> Result<git2::Commit, git::Error> { fn commit(&self, oid: Oid) -> Result<git::raw::Commit, git::Error> {
self.backend self.backend
.find_commit(oid.into()) .find_commit(oid.into())
.map_err(git::Error::from) .map_err(git::Error::from)
} }
fn revwalk(&self, head: Oid) -> Result<git2::Revwalk, git2::Error> { fn revwalk(&self, head: Oid) -> Result<git::raw::Revwalk, git::raw::Error> {
let mut revwalk = self.backend.revwalk()?; let mut revwalk = self.backend.revwalk()?;
revwalk.push(head.into())?; revwalk.push(head.into())?;
@ -936,7 +936,7 @@ impl WriteRepository for Repository {
Ok(()) Ok(())
} }
fn raw(&self) -> &git2::Repository { fn raw(&self) -> &git::raw::Repository {
&self.backend &self.backend
} }
} }
@ -986,7 +986,7 @@ pub mod trailers {
pub fn parse_signatures(msg: &str) -> Result<HashMap<PublicKey, Signature>, Error> { pub fn parse_signatures(msg: &str) -> Result<HashMap<PublicKey, Signature>, Error> {
let trailers = let trailers =
git2::message_trailers_strs(msg).map_err(|_| Error::SignatureTrailerFormat)?; git::raw::message_trailers_strs(msg).map_err(|_| Error::SignatureTrailerFormat)?;
let mut signatures = HashMap::with_capacity(trailers.len()); let mut signatures = HashMap::with_capacity(trailers.len());
for (key, val) in trailers.iter() { for (key, val) in trailers.iter() {
@ -1097,7 +1097,7 @@ mod tests {
fixtures::project(tmp.path().join("project"), &storage, &signer).unwrap(); fixtures::project(tmp.path().join("project"), &storage, &signer).unwrap();
let stored = storage.repository(rid).unwrap(); let stored = storage.repository(rid).unwrap();
let sig = let sig =
git2::Signature::now(&alice.to_string(), "anonymous@radicle.example.com").unwrap(); git::raw::Signature::now(&alice.to_string(), "anonymous@radicle.example.com").unwrap();
let head = working.head().unwrap().peel_to_commit().unwrap(); let head = working.head().unwrap().peel_to_commit().unwrap();
git::commit( git::commit(

View File

@ -33,7 +33,7 @@ pub enum ObjectsError {
#[error(transparent)] #[error(transparent)]
Convert(#[from] cob::object::storage::convert::Error), Convert(#[from] cob::object::storage::convert::Error),
#[error(transparent)] #[error(transparent)]
Git(#[from] git2::Error), Git(#[from] git::raw::Error),
#[error(transparent)] #[error(transparent)]
GitExt(#[from] git_ext::Error), GitExt(#[from] git_ext::Error),
} }
@ -43,7 +43,7 @@ pub enum TypesError {
#[error(transparent)] #[error(transparent)]
Convert(#[from] cob::object::storage::convert::Error), Convert(#[from] cob::object::storage::convert::Error),
#[error(transparent)] #[error(transparent)]
Git(#[from] git2::Error), Git(#[from] git::raw::Error),
#[error(transparent)] #[error(transparent)]
ParseKey(#[from] crypto::Error), ParseKey(#[from] crypto::Error),
#[error(transparent)] #[error(transparent)]
@ -55,12 +55,12 @@ pub enum TypesError {
impl cob::Store for Repository {} impl cob::Store for Repository {}
impl change::Storage for Repository { impl change::Storage for Repository {
type StoreError = <git2::Repository as change::Storage>::StoreError; type StoreError = <git::raw::Repository as change::Storage>::StoreError;
type LoadError = <git2::Repository as change::Storage>::LoadError; type LoadError = <git::raw::Repository as change::Storage>::LoadError;
type ObjectId = <git2::Repository as change::Storage>::ObjectId; type ObjectId = <git::raw::Repository as change::Storage>::ObjectId;
type Parent = <git2::Repository as change::Storage>::Parent; type Parent = <git::raw::Repository as change::Storage>::Parent;
type Signatures = <git2::Repository as change::Storage>::Signatures; type Signatures = <git::raw::Repository as change::Storage>::Signatures;
fn store<Signer>( fn store<Signer>(
&self, &self,
@ -91,8 +91,8 @@ impl change::Storage for Repository {
impl cob::object::Storage for Repository { impl cob::object::Storage for Repository {
type ObjectsError = ObjectsError; type ObjectsError = ObjectsError;
type TypesError = TypesError; type TypesError = TypesError;
type UpdateError = git2::Error; type UpdateError = git::raw::Error;
type RemoveError = git2::Error; type RemoveError = git::raw::Error;
type Namespace = NodeId; type Namespace = NodeId;
@ -200,12 +200,12 @@ impl<'a, R> DraftStore<'a, R> {
impl<R: storage::WriteRepository> cob::Store for DraftStore<'_, R> {} impl<R: storage::WriteRepository> cob::Store for DraftStore<'_, R> {}
impl<R: storage::WriteRepository> change::Storage for DraftStore<'_, R> { impl<R: storage::WriteRepository> change::Storage for DraftStore<'_, R> {
type StoreError = <git2::Repository as change::Storage>::StoreError; type StoreError = <git::raw::Repository as change::Storage>::StoreError;
type LoadError = <git2::Repository as change::Storage>::LoadError; type LoadError = <git::raw::Repository as change::Storage>::LoadError;
type ObjectId = <git2::Repository as change::Storage>::ObjectId; type ObjectId = <git::raw::Repository as change::Storage>::ObjectId;
type Parent = <git2::Repository as change::Storage>::Parent; type Parent = <git::raw::Repository as change::Storage>::Parent;
type Signatures = <git2::Repository as change::Storage>::Signatures; type Signatures = <git::raw::Repository as change::Storage>::Signatures;
fn store<Signer>( fn store<Signer>(
&self, &self,
@ -274,7 +274,7 @@ impl<R: storage::ReadRepository> ReadRepository for DraftStore<'_, R> {
self.repo.id() self.repo.id()
} }
fn is_empty(&self) -> Result<bool, git2::Error> { fn is_empty(&self) -> Result<bool, git::raw::Error> {
self.repo.is_empty() self.repo.is_empty()
} }
@ -290,11 +290,11 @@ impl<R: storage::ReadRepository> ReadRepository for DraftStore<'_, R> {
self.repo.path() self.repo.path()
} }
fn commit(&self, oid: Oid) -> Result<git2::Commit, git_ext::Error> { fn commit(&self, oid: Oid) -> Result<git::raw::Commit, git_ext::Error> {
self.repo.commit(oid) self.repo.commit(oid)
} }
fn revwalk(&self, head: Oid) -> Result<git2::Revwalk, git2::Error> { fn revwalk(&self, head: Oid) -> Result<git::raw::Revwalk, git::raw::Error> {
self.repo.revwalk(head) self.repo.revwalk(head)
} }
@ -310,7 +310,7 @@ impl<R: storage::ReadRepository> ReadRepository for DraftStore<'_, R> {
&self, &self,
oid: git_ext::Oid, oid: git_ext::Oid,
path: P, path: P,
) -> Result<git2::Blob, git_ext::Error> { ) -> Result<git::raw::Blob, git_ext::Error> {
self.repo.blob_at(oid, path) self.repo.blob_at(oid, path)
} }
@ -322,7 +322,7 @@ impl<R: storage::ReadRepository> ReadRepository for DraftStore<'_, R> {
&self, &self,
remote: &RemoteId, remote: &RemoteId,
reference: &git::Qualified, reference: &git::Qualified,
) -> Result<git2::Reference, git_ext::Error> { ) -> Result<git::raw::Reference, git_ext::Error> {
self.repo.reference(remote, reference) self.repo.reference(remote, reference)
} }
@ -381,8 +381,8 @@ impl<R: storage::ReadRepository> ReadRepository for DraftStore<'_, R> {
impl<R: storage::WriteRepository> cob::object::Storage for DraftStore<'_, R> { impl<R: storage::WriteRepository> cob::object::Storage for DraftStore<'_, R> {
type ObjectsError = ObjectsError; type ObjectsError = ObjectsError;
type TypesError = git::ext::Error; type TypesError = git::ext::Error;
type UpdateError = git2::Error; type UpdateError = git::raw::Error;
type RemoveError = git2::Error; type RemoveError = git::raw::Error;
type Namespace = NodeId; type Namespace = NodeId;

View File

@ -7,6 +7,7 @@ use std::process;
use std::str::FromStr; use std::str::FromStr;
use std::sync::Once; use std::sync::Once;
use crate::git;
use crate::storage; use crate::storage;
use crate::storage::git::Storage; use crate::storage::git::Storage;
@ -25,20 +26,19 @@ struct Local {
child: RefCell<Option<process::Child>>, child: RefCell<Option<process::Child>>,
} }
impl git2::transport::SmartSubtransport for Local { impl crate::git::raw::transport::SmartSubtransport for Local {
fn action( fn action(
&self, &self,
url: &str, url: &str,
service: git2::transport::Service, service: git::raw::transport::Service,
) -> Result<Box<dyn git2::transport::SmartSubtransportStream>, git2::Error> { ) -> Result<Box<dyn git::raw::transport::SmartSubtransportStream>, git::raw::Error> {
let url = Url::from_str(url).map_err(|e| git2::Error::from_str(e.to_string().as_str()))?; let url =
Url::from_str(url).map_err(|e| git::raw::Error::from_str(e.to_string().as_str()))?;
let service: &str = match service { let service: &str = match service {
git2::transport::Service::UploadPack | git2::transport::Service::UploadPackLs => { git::raw::transport::Service::UploadPack
"upload-pack" | git::raw::transport::Service::UploadPackLs => "upload-pack",
} git::raw::transport::Service::ReceivePack
git2::transport::Service::ReceivePack | git2::transport::Service::ReceivePackLs => { | git::raw::transport::Service::ReceivePackLs => "receive-pack",
"receive-pack"
}
}; };
let git_dir = THREAD_STORAGE let git_dir = THREAD_STORAGE
.with(|t| { .with(|t| {
@ -46,7 +46,9 @@ impl git2::transport::SmartSubtransport for Local {
.as_ref() .as_ref()
.map(|s| storage::git::paths::repository(&s, &url.repo)) .map(|s| storage::git::paths::repository(&s, &url.repo))
}) })
.ok_or_else(|| git2::Error::from_str("local transport storage was not registered"))?; .ok_or_else(|| {
git::raw::Error::from_str("local transport storage was not registered")
})?;
let mut cmd = process::Command::new("git"); let mut cmd = process::Command::new("git");
@ -61,7 +63,7 @@ impl git2::transport::SmartSubtransport for Local {
.stdout(process::Stdio::piped()) .stdout(process::Stdio::piped())
.stderr(process::Stdio::inherit()) .stderr(process::Stdio::inherit())
.spawn() .spawn()
.map_err(|e| git2::Error::from_str(e.to_string().as_str()))?; .map_err(|e| git::raw::Error::from_str(e.to_string().as_str()))?;
let stdin = child.stdin.take().expect("taking stdin is safe"); let stdin = child.stdin.take().expect("taking stdin is safe");
let stdout = child.stdout.take().expect("taking stdout is safe"); let stdout = child.stdout.take().expect("taking stdout is safe");
@ -71,19 +73,19 @@ impl git2::transport::SmartSubtransport for Local {
Ok(Box::new(ChildStream { stdout, stdin })) Ok(Box::new(ChildStream { stdout, stdin }))
} }
fn close(&self) -> Result<(), git2::Error> { fn close(&self) -> Result<(), git::raw::Error> {
if let Some(mut child) = self.child.take() { if let Some(mut child) = self.child.take() {
let result = child let result = child
.wait() .wait()
.map_err(|e| git2::Error::from_str(e.to_string().as_str()))?; .map_err(|e| git::raw::Error::from_str(e.to_string().as_str()))?;
if !result.success() { if !result.success() {
return if let Some(code) = result.code() { return if let Some(code) = result.code() {
Err(git2::Error::from_str( Err(git::raw::Error::from_str(
format!("transport: child process exited with error code {code}").as_str(), format!("transport: child process exited with error code {code}").as_str(),
)) ))
} else { } else {
Err(git2::Error::from_str( Err(git::raw::Error::from_str(
"transport: child process exited with unknown error", "transport: child process exited with unknown error",
)) ))
}; };
@ -103,8 +105,8 @@ pub fn register(storage: Storage) {
}); });
REGISTER.call_once(|| unsafe { REGISTER.call_once(|| unsafe {
git2::transport::register(Url::SCHEME, move |remote| { git::raw::transport::register(Url::SCHEME, move |remote| {
git2::transport::Transport::smart(remote, false, Local::default()) git::raw::transport::Transport::smart(remote, false, Local::default())
}) })
.expect("local transport registration"); .expect("local transport registration");
}); });

View File

@ -8,6 +8,7 @@ use std::thread::ThreadId;
use std::{process, thread}; use std::{process, thread};
use super::Url; use super::Url;
use crate::git;
use crate::storage::git::transport::ChildStream; use crate::storage::git::transport::ChildStream;
use crate::storage::RemoteId; use crate::storage::RemoteId;
@ -19,19 +20,21 @@ static NODES: LazyLock<Mutex<HashMap<(ThreadId, RemoteId), PathBuf>>> =
#[derive(Default)] #[derive(Default)]
struct MockTransport; struct MockTransport;
impl git2::transport::SmartSubtransport for MockTransport { impl git::raw::transport::SmartSubtransport for MockTransport {
fn action( fn action(
&self, &self,
url: &str, url: &str,
service: git2::transport::Service, service: git::raw::transport::Service,
) -> Result<Box<dyn git2::transport::SmartSubtransportStream>, git2::Error> { ) -> Result<Box<dyn git::raw::transport::SmartSubtransportStream>, git::raw::Error> {
let url = Url::from_str(url).map_err(|e| git2::Error::from_str(e.to_string().as_str()))?; let url =
Url::from_str(url).map_err(|e| git::raw::Error::from_str(e.to_string().as_str()))?;
let id = thread::current().id(); let id = thread::current().id();
let nodes = NODES.lock().expect("lock cannot be poisoned"); let nodes = NODES.lock().expect("lock cannot be poisoned");
let storage = if let Some(storage) = nodes.get(&(id, url.node)) { let storage = if let Some(storage) = nodes.get(&(id, url.node)) {
match service { match service {
git2::transport::Service::ReceivePack | git2::transport::Service::ReceivePackLs => { git::raw::transport::Service::ReceivePack
return Err(git2::Error::from_str( | git::raw::transport::Service::ReceivePackLs => {
return Err(git::raw::Error::from_str(
"git-receive-pack is not supported with the mock transport", "git-receive-pack is not supported with the mock transport",
)); ));
} }
@ -39,7 +42,7 @@ impl git2::transport::SmartSubtransport for MockTransport {
} }
storage storage
} else { } else {
return Err(git2::Error::from_str(&format!( return Err(git::raw::Error::from_str(&format!(
"node {} was not registered with the mock transport", "node {} was not registered with the mock transport",
url.node url.node
))); )));
@ -76,7 +79,7 @@ impl git2::transport::SmartSubtransport for MockTransport {
Ok(Box::new(ChildStream { stdout, stdin })) Ok(Box::new(ChildStream { stdout, stdin }))
} }
fn close(&self) -> Result<(), git2::Error> { fn close(&self) -> Result<(), git::raw::Error> {
Ok(()) Ok(())
} }
} }
@ -86,8 +89,8 @@ pub fn register(node: &RemoteId, path: &Path) {
static REGISTER: Once = Once::new(); static REGISTER: Once = Once::new();
REGISTER.call_once(|| unsafe { REGISTER.call_once(|| unsafe {
git2::transport::register(Url::SCHEME, move |remote| { git::raw::transport::register(Url::SCHEME, move |remote| {
git2::transport::Transport::smart(remote, false, MockTransport) git::raw::transport::Transport::smart(remote, false, MockTransport)
}) })
.expect("transport registration is successful"); .expect("transport registration is successful");
}); });

View File

@ -55,7 +55,7 @@ pub enum Error {
#[error("invalid reference: {0}")] #[error("invalid reference: {0}")]
Ref(#[from] git::RefError), Ref(#[from] git::RefError),
#[error(transparent)] #[error(transparent)]
Git(#[from] git2::Error), Git(#[from] git::raw::Error),
#[error(transparent)] #[error(transparent)]
GitExt(#[from] git_ext::Error), GitExt(#[from] git_ext::Error),
} }
@ -322,8 +322,8 @@ impl SignedRefs<Verified> {
env::GIT_COMMITTER_DATE env::GIT_COMMITTER_DATE
); );
}; };
let time = git2::Time::new(timestamp, 0); let time = git::raw::Time::new(timestamp, 0);
git2::Signature::new("radicle", remote.to_string().as_str(), &time)? git::raw::Signature::new("radicle", remote.to_string().as_str(), &time)?
} else { } else {
raw.signature()? raw.signature()?
}; };
@ -334,13 +334,13 @@ impl SignedRefs<Verified> {
&author, &author,
"Update signed refs\n", "Update signed refs\n",
&tree, &tree,
&parent.iter().collect::<Vec<&git2::Commit>>(), &parent.iter().collect::<Vec<&git::raw::Commit>>(),
); );
match commit { match commit {
Ok(oid) => Ok(Updated::Updated { oid: oid.into() }), Ok(oid) => Ok(Updated::Updated { oid: oid.into() }),
Err(e) => match (e.class(), e.code()) { Err(e) => match (e.class(), e.code()) {
(git2::ErrorClass::Object, git2::ErrorCode::Modified) => { (git::raw::ErrorClass::Object, git::raw::ErrorCode::Modified) => {
log::warn!("Concurrent modification of refs: {e:?}"); log::warn!("Concurrent modification of refs: {e:?}");
Err(Error::Git(e)) Err(Error::Git(e))
@ -471,7 +471,7 @@ pub mod canonical {
#[error(transparent)] #[error(transparent)]
Io(#[from] io::Error), Io(#[from] io::Error),
#[error(transparent)] #[error(transparent)]
Git(#[from] git2::Error), Git(#[from] git::raw::Error),
} }
} }
@ -581,7 +581,7 @@ mod tests {
.unwrap(); .unwrap();
let paris_head = bob_working.find_commit(paris_head).unwrap(); let paris_head = bob_working.find_commit(paris_head).unwrap();
let bob_sig = git2::Signature::now("bob", "bob@example.com").unwrap(); let bob_sig = git::raw::Signature::now("bob", "bob@example.com").unwrap();
let bob_head = git::empty_commit( let bob_head = git::empty_commit(
&bob_working, &bob_working,
&paris_head, &paris_head,

View File

@ -6,6 +6,7 @@ pub mod storage;
use super::storage::{Namespaces, RefUpdate}; use super::storage::{Namespaces, RefUpdate};
use crate::git;
use crate::prelude::NodeId; use crate::prelude::NodeId;
use crate::storage::WriteRepository; use crate::storage::WriteRepository;
@ -22,13 +23,13 @@ pub fn fetch<W: WriteRepository>(
Namespaces::Followed(followed) => followed.into_iter().next(), Namespaces::Followed(followed) => followed.into_iter().next(),
}; };
let mut updates = Vec::new(); let mut updates = Vec::new();
let mut callbacks = git2::RemoteCallbacks::new(); let mut callbacks = git::raw::RemoteCallbacks::new();
let mut opts = git2::FetchOptions::default(); let mut opts = git::raw::FetchOptions::default();
let refspec = if let Some(namespace) = namespace { let refspec = if let Some(namespace) = namespace {
opts.prune(git2::FetchPrune::On); opts.prune(git::raw::FetchPrune::On);
format!("refs/namespaces/{namespace}/refs/*:refs/namespaces/{namespace}/refs/*") format!("refs/namespaces/{namespace}/refs/*:refs/namespaces/{namespace}/refs/*")
} else { } else {
opts.prune(git2::FetchPrune::Off); opts.prune(git::raw::FetchPrune::Off);
"refs/namespaces/*:refs/namespaces/*".to_owned() "refs/namespaces/*:refs/namespaces/*".to_owned()
}; };
@ -295,22 +296,22 @@ pub mod setup {
} }
pub fn commit<S: AsRef<Path>, T: AsRef<[u8]>>( pub fn commit<S: AsRef<Path>, T: AsRef<[u8]>>(
repo: &git2::Repository, repo: &git::raw::Repository,
refname: &git::Qualified, refname: &git::Qualified,
blobs: impl IntoIterator<Item = (S, T)>, blobs: impl IntoIterator<Item = (S, T)>,
parents: &[&git2::Commit<'_>], parents: &[&git::raw::Commit<'_>],
) -> git::Oid { ) -> git::Oid {
let tree = { let tree = {
let mut tb = repo.treebuilder(None).unwrap(); let mut tb = repo.treebuilder(None).unwrap();
for (name, blob) in blobs.into_iter() { for (name, blob) in blobs.into_iter() {
let oid = repo.blob(blob.as_ref()).unwrap(); let oid = repo.blob(blob.as_ref()).unwrap();
tb.insert(name.as_ref(), oid, git2::FileMode::Blob.into()) tb.insert(name.as_ref(), oid, git::raw::FileMode::Blob.into())
.unwrap(); .unwrap();
} }
tb.write().unwrap() tb.write().unwrap()
}; };
let tree = repo.find_tree(tree).unwrap(); let tree = repo.find_tree(tree).unwrap();
let author = git2::Signature::now("anonymous", "anonymous@example.com").unwrap(); let author = git::raw::Signature::now("anonymous", "anonymous@example.com").unwrap();
repo.commit( repo.commit(
Some(refname.as_str()), Some(refname.as_str()),

View File

@ -72,7 +72,15 @@ pub fn project<P, G>(
path: P, path: P,
storage: &Storage, storage: &Storage,
signer: &Device<G>, signer: &Device<G>,
) -> Result<(RepoId, SignedRefs<Verified>, git2::Repository, git2::Oid), rad::InitError> ) -> Result<
(
RepoId,
SignedRefs<Verified>,
git::raw::Repository,
git::raw::Oid,
),
rad::InitError,
>
where where
P: AsRef<Path>, P: AsRef<Path>,
G: crypto::signature::Signer<crypto::Signature>, G: crypto::signature::Signer<crypto::Signature>,
@ -94,19 +102,19 @@ where
} }
/// Creates a regular repository at the given path with a couple of commits. /// Creates a regular repository at the given path with a couple of commits.
pub fn repository<P: AsRef<Path>>(path: P) -> (git2::Repository, git2::Oid) { pub fn repository<P: AsRef<Path>>(path: P) -> (git::raw::Repository, git::raw::Oid) {
let (repo, oid) = repository_with( let (repo, oid) = repository_with(
path, path,
git2::RepositoryInitOptions::new().external_template(false), git::raw::RepositoryInitOptions::new().external_template(false),
); );
repo.checkout_head(None).unwrap(); repo.checkout_head(None).unwrap();
(repo, oid) (repo, oid)
} }
pub fn bare_repository<P: AsRef<Path>>(path: P) -> (git2::Repository, git2::Oid) { pub fn bare_repository<P: AsRef<Path>>(path: P) -> (git::raw::Repository, git::raw::Oid) {
repository_with( repository_with(
path, path,
git2::RepositoryInitOptions::new() git::raw::RepositoryInitOptions::new()
.external_template(false) .external_template(false)
.bare(true), .bare(true),
) )
@ -114,17 +122,21 @@ pub fn bare_repository<P: AsRef<Path>>(path: P) -> (git2::Repository, git2::Oid)
fn repository_with<P: AsRef<Path>>( fn repository_with<P: AsRef<Path>>(
path: P, path: P,
opts: &mut git2::RepositoryInitOptions, opts: &mut git::raw::RepositoryInitOptions,
) -> (git2::Repository, git2::Oid) { ) -> (git::raw::Repository, git::raw::Oid) {
let repo = git2::Repository::init_opts(path, opts).unwrap(); let repo = git::raw::Repository::init_opts(path, opts).unwrap();
{ {
let mut config = repo.config().unwrap(); let mut config = repo.config().unwrap();
config.set_str("user.name", USER_NAME).unwrap(); config.set_str("user.name", USER_NAME).unwrap();
config.set_str("user.email", USER_EMAIL).unwrap(); config.set_str("user.email", USER_EMAIL).unwrap();
} }
let sig = let sig = git::raw::Signature::new(
git2::Signature::new(USER_NAME, USER_EMAIL, &git2::Time::new(RADICLE_EPOCH, 0)).unwrap(); USER_NAME,
USER_EMAIL,
&git::raw::Time::new(RADICLE_EPOCH, 0),
)
.unwrap();
let head = git::initial_commit(&repo, &sig).unwrap(); let head = git::initial_commit(&repo, &sig).unwrap();
let tree = git::write_tree(Path::new("README"), "Hello World!\n".as_bytes(), &repo).unwrap(); let tree = git::write_tree(Path::new("README"), "Hello World!\n".as_bytes(), &repo).unwrap();
let oid = { let oid = {
@ -149,10 +161,14 @@ fn repository_with<P: AsRef<Path>>(
} }
/// Create an empty commit on the current branch. /// Create an empty commit on the current branch.
pub fn commit(msg: &str, parents: &[git2::Oid], repo: &git2::Repository) -> git::Oid { pub fn commit(msg: &str, parents: &[git::raw::Oid], repo: &git::raw::Repository) -> git::Oid {
let head = repo.head().unwrap(); let head = repo.head().unwrap();
let sig = let sig = git::raw::Signature::new(
git2::Signature::new(USER_NAME, USER_EMAIL, &git2::Time::new(RADICLE_EPOCH, 0)).unwrap(); USER_NAME,
USER_EMAIL,
&git::raw::Time::new(RADICLE_EPOCH, 0),
)
.unwrap();
let tree = head.peel_to_commit().unwrap().tree().unwrap(); let tree = head.peel_to_commit().unwrap().tree().unwrap();
let parents = parents let parents = parents
.iter() .iter()
@ -166,19 +182,28 @@ pub fn commit(msg: &str, parents: &[git2::Oid], repo: &git2::Repository) -> git:
} }
/// Create an (annotated) tag of the given commit. /// Create an (annotated) tag of the given commit.
pub fn tag(name: &str, message: &str, commit: git2::Oid, repo: &git2::Repository) -> git::Oid { pub fn tag(
name: &str,
message: &str,
commit: git::raw::Oid,
repo: &git::raw::Repository,
) -> git::Oid {
let target = repo let target = repo
.find_object(commit, Some(git2::ObjectType::Commit)) .find_object(commit, Some(git::raw::ObjectType::Commit))
.unwrap(); .unwrap();
let tagger = let tagger = git::raw::Signature::new(
git2::Signature::new(USER_NAME, USER_EMAIL, &git2::Time::new(RADICLE_EPOCH, 0)).unwrap(); USER_NAME,
USER_EMAIL,
&git::raw::Time::new(RADICLE_EPOCH, 0),
)
.unwrap();
repo.tag(name, &target, &tagger, message, false) repo.tag(name, &target, &tagger, message, false)
.unwrap() .unwrap()
.into() .into()
} }
/// Populate a repository with commits, branches and blobs. /// Populate a repository with commits, branches and blobs.
pub fn populate(repo: &git2::Repository, scale: usize) -> Vec<git::Qualified> { pub fn populate(repo: &git::raw::Repository, scale: usize) -> Vec<git::Qualified> {
assert!( assert!(
scale <= 8, scale <= 8,
"Scale parameter must be less than or equal to 8" "Scale parameter must be less than or equal to 8"
@ -198,7 +223,7 @@ pub fn populate(repo: &git2::Repository, scale: usize) -> Vec<git::Qualified> {
.to_lowercase(); .to_lowercase();
let name = let name =
git::refname!("feature").join(git::RefString::try_from(random.as_str()).unwrap()); git::refname!("feature").join(git::RefString::try_from(random.as_str()).unwrap());
let signature = git2::Signature::now("Radicle", "radicle@radicle.xyz").unwrap(); let signature = git::raw::Signature::now("Radicle", "radicle@radicle.xyz").unwrap();
rng.fill(&mut buffer); rng.fill(&mut buffer);
@ -241,13 +266,13 @@ pub mod gen {
} }
/// Creates a regular repository at the given path with a couple of commits. /// Creates a regular repository at the given path with a couple of commits.
pub fn repository<P: AsRef<Path>>(path: P) -> (git2::Repository, git2::Oid) { pub fn repository<P: AsRef<Path>>(path: P) -> (git::raw::Repository, git::raw::Oid) {
let repo = git2::Repository::init_opts( let repo = git::raw::Repository::init_opts(
path, path,
git2::RepositoryInitOptions::new().external_template(false), git::raw::RepositoryInitOptions::new().external_template(false),
) )
.unwrap(); .unwrap();
let sig = git2::Signature::now(string(6).as_str(), email().as_str()).unwrap(); let sig = git::raw::Signature::now(string(6).as_str(), email().as_str()).unwrap();
let head = git::initial_commit(&repo, &sig).unwrap(); let head = git::initial_commit(&repo, &sig).unwrap();
let tree = let tree =
git::write_tree(Path::new("README"), "Hello World!\n".as_bytes(), &repo).unwrap(); git::write_tree(Path::new("README"), "Hello World!\n".as_bytes(), &repo).unwrap();

View File

@ -199,7 +199,7 @@ impl ReadRepository for MockRepository {
self.id self.id
} }
fn is_empty(&self) -> Result<bool, git2::Error> { fn is_empty(&self) -> Result<bool, git::raw::Error> {
Ok(self.remotes.is_empty()) Ok(self.remotes.is_empty())
} }
@ -215,17 +215,17 @@ impl ReadRepository for MockRepository {
todo!() todo!()
} }
fn commit(&self, oid: Oid) -> Result<git2::Commit, git_ext::Error> { fn commit(&self, oid: Oid) -> Result<git::raw::Commit, git_ext::Error> {
Err(git_ext::Error::NotFound(git_ext::NotFound::NoSuchObject( Err(git_ext::Error::NotFound(git_ext::NotFound::NoSuchObject(
*oid, *oid,
))) )))
} }
fn revwalk(&self, _head: Oid) -> Result<git2::Revwalk, git2::Error> { fn revwalk(&self, _head: Oid) -> Result<git::raw::Revwalk, git::raw::Error> {
todo!() todo!()
} }
fn contains(&self, oid: Oid) -> Result<bool, git2::Error> { fn contains(&self, oid: Oid) -> Result<bool, git::raw::Error> {
Ok(self Ok(self
.remotes .remotes
.values() .values()
@ -236,7 +236,7 @@ impl ReadRepository for MockRepository {
Ok(true) Ok(true)
} }
fn blob(&self, _oid: Oid) -> Result<git2::Blob, git_ext::Error> { fn blob(&self, _oid: Oid) -> Result<git::raw::Blob, git_ext::Error> {
todo!() todo!()
} }
@ -244,7 +244,7 @@ impl ReadRepository for MockRepository {
&self, &self,
_oid: git_ext::Oid, _oid: git_ext::Oid,
_path: P, _path: P,
) -> Result<git2::Blob, git_ext::Error> { ) -> Result<git::raw::Blob, git_ext::Error> {
todo!() todo!()
} }
@ -252,7 +252,7 @@ impl ReadRepository for MockRepository {
&self, &self,
_remote: &RemoteId, _remote: &RemoteId,
_reference: &git::Qualified, _reference: &git::Qualified,
) -> Result<git2::Reference, git_ext::Error> { ) -> Result<git::raw::Reference, git_ext::Error> {
todo!() todo!()
} }
@ -322,7 +322,7 @@ impl ReadRepository for MockRepository {
} }
impl WriteRepository for MockRepository { impl WriteRepository for MockRepository {
fn raw(&self) -> &git2::Repository { fn raw(&self) -> &git::raw::Repository {
todo!() todo!()
} }