diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 7bbadee..da7635a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -85,10 +85,13 @@ jobs: with: fetch-depth: 0 # The 'main' branch is needed for radicle-surf vcs::git::tests::test_submodule_failure, - # however actions/checkout uses the init.defaultBranch 'master' at this moment. - # We will improve the test soon to remove this need. - - run: git branch -f main # -f in case of running against 'main' branch. - - run: git branch -u origin/main main + # however actions/checkout uses the init.defaultBranch 'master' at this moment, even if + # the repo does not use 'master' branch. We create 'main' branch as needed for the test. + # + # awk magic: create 'main' branch only if not exist yet. + # END: do things at the end of the input. + # NR: Number of Records in the input. + - run: git branch --list main | awk 'END { if (NR == 0) system("git branch main; git branch -u origin/main main"); }' - uses: actions-rs/toolchain@v1 with: profile: minimal @@ -120,8 +123,7 @@ jobs: - uses: actions/checkout@master with: fetch-depth: 0 - - run: git branch -f main - - run: git branch -u origin/main main + - run: git branch --list main | awk 'END { if (NR == 0) system("git branch main; git branch -u origin/main main"); }' - uses: actions-rs/toolchain@v1 with: profile: minimal diff --git a/radicle-surf/examples/diff.rs b/radicle-surf/examples/diff.rs index 3f932fa..22d67c4 100644 --- a/radicle-surf/examples/diff.rs +++ b/radicle-surf/examples/diff.rs @@ -17,11 +17,11 @@ extern crate radicle_surf; -use std::{env::Args, time::Instant}; +use std::{env::Args, str::FromStr, time::Instant}; -use git2::Oid; use nonempty::NonEmpty; +use radicle_git_ext::Oid; use radicle_surf::{ diff::Diff, file_system::Directory, diff --git a/radicle-surf/src/commit.rs b/radicle-surf/src/commit.rs index 4bd83ae..5d1491f 100644 --- a/radicle-surf/src/commit.rs +++ b/radicle-surf/src/commit.rs @@ -33,6 +33,8 @@ use crate::{ vcs::git::{self, BranchName, Browser, Rev}, }; +use radicle_git_ext::Oid; + /// Commit statistics. #[cfg_attr(feature = "serialize", derive(Serialize))] #[derive(Clone)] @@ -62,7 +64,7 @@ pub struct Commit { pub struct Header { /// Identifier of the commit in the form of a sha1 hash. Often referred to /// as oid or object id. - pub sha1: git2::Oid, + pub sha1: Oid, /// The author of the commit. pub author: Person, /// The summary of the commit message body. @@ -139,7 +141,7 @@ pub struct Commits { /// /// Will return [`Error`] if the project doesn't exist or the surf interaction /// fails. -pub fn commit(browser: &mut Browser<'_>, sha1: git2::Oid) -> Result { +pub fn commit(browser: &mut Browser<'_>, sha1: Oid) -> Result { browser.commit(sha1)?; let history = browser.get(); @@ -215,7 +217,7 @@ pub fn commit(browser: &mut Browser<'_>, sha1: git2::Oid) -> Result, sha1: git2::Oid) -> Result { +pub fn header(browser: &mut Browser<'_>, sha1: Oid) -> Result { browser.commit(sha1)?; let history = browser.get(); diff --git a/radicle-surf/src/revision.rs b/radicle-surf/src/revision.rs index 76cfaf6..66dda79 100644 --- a/radicle-surf/src/revision.rs +++ b/radicle-surf/src/revision.rs @@ -94,10 +94,7 @@ where }, None => git::Branch::local(&name).into(), }), - Revision::Sha { sha } => { - let oid: git2::Oid = sha.into(); - Ok(oid.into()) - }, + Revision::Sha { sha } => Ok(sha.into()), } } } diff --git a/radicle-surf/src/vcs/git.rs b/radicle-surf/src/vcs/git.rs index 76f9e8f..59c15d1 100644 --- a/radicle-surf/src/vcs/git.rs +++ b/radicle-surf/src/vcs/git.rs @@ -21,6 +21,7 @@ //! use radicle_surf::file_system::unsound; //! use radicle_surf::vcs::git::*; //! use std::collections::HashMap; +//! use std::str::FromStr; //! # use std::error::Error; //! //! # fn main() -> Result<(), Box> { @@ -63,7 +64,8 @@ //! ``` // Re-export git2 as sub-module -pub use git2::{self, Error as Git2Error, Oid, Time}; +pub use git2::{self, Error as Git2Error, Time}; +pub use radicle_git_ext::Oid; /// Provides ways of selecting a particular reference/revision. mod reference; @@ -387,6 +389,7 @@ impl<'a> Browser<'a> { /// use nonempty::NonEmpty; /// use radicle_surf::vcs::History; /// use radicle_surf::vcs::git::{TagName, Branch, Browser, Oid, Repository}; + /// use std::str::FromStr; /// # use std::error::Error; /// /// # fn main() -> Result<(), Box> { @@ -646,6 +649,7 @@ impl<'a> Browser<'a> { /// ``` /// use radicle_surf::vcs::git::{Branch, RefScope, Browser, Namespace, Oid, Repository, Tag, TagName, Author, Time}; /// use std::convert::TryFrom; + /// use std::str::FromStr; /// # use std::error::Error; /// /// # fn main() -> Result<(), Box> { @@ -915,6 +919,7 @@ impl<'a> Browser<'a> { /// /// ``` /// use radicle_surf::vcs::git::{Branch, Browser, Repository, Oid, error}; + /// use std::str::FromStr; /// # use std::error::Error; /// /// # fn main() -> Result<(), Box> { @@ -967,6 +972,7 @@ impl<'a> Browser<'a> { /// ``` /// use radicle_surf::vcs::git::{Browser, Repository, Branch, BranchName, Namespace, Oid}; /// use std::convert::TryFrom; + /// use std::str::FromStr; /// # use std::error::Error; /// /// # fn main() -> Result<(), Box> { @@ -1017,7 +1023,7 @@ impl<'a> Browser<'a> { /// ``` pub fn revision_branches(&self, rev: impl Into) -> Result, Error> { let commit = self.repository.rev_to_commit(&rev.into())?; - self.repository.revision_branches(&commit.id()) + self.repository.revision_branches(&commit.id().into()) } /// Get the [`Stats`] of the underlying [`Repository`]. @@ -1078,7 +1084,7 @@ impl<'a> Browser<'a> { Error, > = Ok(HashMap::new()); - let commit = repo.find_commit(commit.id)?; + let commit = repo.find_commit(commit.id.into())?; let tree = commit.as_object().peel_to_tree()?; tree.walk( @@ -1117,8 +1123,8 @@ impl<'a> Browser<'a> { /// /// See [`git2::Repository::merge_base`] for details. pub fn merge_base(&self, one: Oid, two: Oid) -> Result, Error> { - match self.repository.repo_ref.merge_base(one, two) { - Ok(merge_base) => Ok(Some(merge_base)), + match self.repository.repo_ref.merge_base(one.into(), two.into()) { + Ok(merge_base) => Ok(Some(merge_base.into())), Err(err) => { if err.code() == git2::ErrorCode::NotFound { Ok(None) @@ -1317,6 +1323,7 @@ mod tests { #[cfg(test)] mod rev { use super::{Branch, Browser, Error, Oid, Repository, TagName}; + use std::str::FromStr; // **FIXME**: This seems to break occasionally on // buildkite. For some reason the commit @@ -1440,6 +1447,7 @@ mod tests { file_system::{unsound, Path}, vcs::git::{Branch, Browser, Oid, Repository}, }; + use std::str::FromStr; #[test] fn readme_missing_and_memory() { @@ -1571,6 +1579,7 @@ mod tests { #[cfg(test)] mod diff { use crate::{diff::*, vcs::git::*}; + use std::str::FromStr; #[test] fn test_initial_diff() -> Result<(), Error> { @@ -1579,7 +1588,7 @@ mod tests { let oid = Oid::from_str("d3464e33d75c75c99bfb90fa2e9d16efc0b7d0e3")?; let repo = Repository::new("./data/git-platinum")?; - let commit = repo.0.find_commit(oid).unwrap(); + let commit = repo.0.find_commit(oid.into()).unwrap(); assert!(commit.parents().count() == 0); assert!(commit.parent(0).is_err()); @@ -1617,13 +1626,15 @@ mod tests { let repo = Repository::new("./data/git-platinum")?; let commit = repo .0 - .find_commit(Oid::from_str("80bacafba303bf0cdf6142921f430ff265f25095")?) + .find_commit(git2::Oid::from_str( + "80bacafba303bf0cdf6142921f430ff265f25095", + )?) .unwrap(); let parent = commit.parent(0)?; let bro = Browser::new(&repo, Branch::local("master"))?; - let diff = bro.diff(parent.id(), commit.id())?; + let diff = bro.diff(parent.id().into(), commit.id().into())?; let expected_diff = Diff { created: vec![], diff --git a/radicle-surf/src/vcs/git/commit.rs b/radicle-surf/src/vcs/git/commit.rs index f892c6a..84b36ee 100644 --- a/radicle-surf/src/vcs/git/commit.rs +++ b/radicle-surf/src/vcs/git/commit.rs @@ -16,7 +16,7 @@ // along with this program. If not, see . use crate::vcs::git::error::Error; -use git2::Oid; +use radicle_git_ext::Oid; use std::{convert::TryFrom, str}; #[cfg(feature = "serialize")] @@ -92,9 +92,7 @@ impl<'repo> TryFrom> for Author { #[cfg_attr(feature = "serialize", derive(Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct Commit { - // TODO: Replace git2::Oid with git_ext::Oid (https://github.com/radicle-dev/radicle-git/issues/5) - /// Object ID of the Commit, i.e. the SHA1 digest. - #[cfg_attr(feature = "serialize", serde(deserialize_with = "deserialize_oid"))] + /// Object Id pub id: Oid, /// The author of the commit. pub author: Author, @@ -105,7 +103,6 @@ pub struct Commit { /// The summary message of the commit. pub summary: String, /// The parents of this commit. - #[cfg_attr(feature = "serialize", serde(deserialize_with = "deserialize_vec_oid"))] pub parents: Vec, } @@ -146,44 +143,18 @@ impl Serialize for Commit { } } -#[cfg(feature = "serialize")] -fn deserialize_oid<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let oid: &str = Deserialize::deserialize(deserializer)?; - Oid::from_str(oid).map_err(|_| { - serde::de::Error::invalid_type( - serde::de::Unexpected::Str(oid), - &"a SHA1 hash not longer than 40 hex characters", - ) - }) -} - -#[cfg(feature = "serialize")] -fn deserialize_vec_oid<'de, D>(deserializer: D) -> Result, D::Error> -where - D: Deserializer<'de>, -{ - let oids: Vec<&str> = Deserialize::deserialize(deserializer)?; - oids.iter() - .map(|key| Oid::from_str(key)) - .collect::, _>>() - .map_err(de::Error::custom) -} - impl<'repo> TryFrom> for Commit { type Error = Error; fn try_from(commit: git2::Commit) -> Result { - let id = commit.id(); + let id = commit.id().into(); let author = Author::try_from(commit.author())?; let committer = Author::try_from(commit.committer())?; let message_raw = commit.message_bytes(); let message = str::from_utf8(message_raw)?.into(); let summary_raw = commit.summary_bytes().ok_or(Error::MissingSummary)?; let summary = str::from_utf8(summary_raw)?.into(); - let parents = commit.parent_ids().collect(); + let parents = commit.parent_ids().map(|oid| oid.into()).collect(); Ok(Commit { id, @@ -199,8 +170,8 @@ impl<'repo> TryFrom> for Commit { #[cfg(feature = "serialize")] #[cfg(test)] pub mod tests { - use git2::Oid; use proptest::prelude::*; + use radicle_git_ext::Oid; use test_helpers::roundtrip; use super::{Author, Commit}; diff --git a/radicle-surf/src/vcs/git/namespace.rs b/radicle-surf/src/vcs/git/namespace.rs index 1435d59..6a4c382 100644 --- a/radicle-surf/src/vcs/git/namespace.rs +++ b/radicle-surf/src/vcs/git/namespace.rs @@ -16,8 +16,8 @@ // along with this program. If not, see . use crate::vcs::git::error::Error; -pub use git2::Oid; use nonempty::NonEmpty; +pub use radicle_git_ext::Oid; use std::{convert::TryFrom, fmt, str}; /// A `Namespace` value allows us to switch the git namespace of diff --git a/radicle-surf/src/vcs/git/reference.rs b/radicle-surf/src/vcs/git/reference.rs index 314b0e6..3b93eaa 100644 --- a/radicle-surf/src/vcs/git/reference.rs +++ b/radicle-surf/src/vcs/git/reference.rs @@ -20,7 +20,7 @@ use std::{fmt, str}; use thiserror::Error; use crate::vcs::git::{repo::RepositoryRef, BranchName, Namespace, TagName}; - +use radicle_git_ext::Oid; pub(super) mod glob; /// A revision within the repository. @@ -29,7 +29,7 @@ pub enum Rev { /// A reference to a branch or tag. Ref(Ref), /// A particular commit identifier. - Oid(git2::Oid), + Oid(Oid), } impl From for Rev @@ -41,8 +41,8 @@ where } } -impl From for Rev { - fn from(other: git2::Oid) -> Self { +impl From for Rev { + fn from(other: Oid) -> Self { Self::Oid(other) } } diff --git a/radicle-surf/src/vcs/git/repo.rs b/radicle-surf/src/vcs/git/repo.rs index f3e38f5..54afa79 100644 --- a/radicle-surf/src/vcs/git/repo.rs +++ b/radicle-surf/src/vcs/git/repo.rs @@ -33,8 +33,8 @@ use crate::{ Vcs, }, }; -use git2::Oid; use nonempty::NonEmpty; +use radicle_git_ext::Oid; use std::{collections::HashSet, convert::TryFrom, str}; /// This is for flagging to the `file_history` function that it should @@ -156,24 +156,24 @@ impl<'a> RepositoryRef<'a> { /// Get the [`Diff`] between two commits. pub fn diff(&self, from: Oid, to: Oid) -> Result { - self.diff_commits(None, Some(from), to) + self.diff_commits(None, Some(from.into()), to.into()) .and_then(|diff| Diff::try_from(diff).map_err(Error::from)) } /// Get the [`Diff`] of a commit with no parents. pub fn initial_diff(&self, oid: Oid) -> Result { - self.diff_commits(None, None, oid) + self.diff_commits(None, None, oid.into()) .and_then(|diff| Diff::try_from(diff).map_err(Error::from)) } /// Parse an [`Oid`] from the given string. pub fn oid(&self, oid: &str) -> Result { - Ok(self.repo_ref.revparse_single(oid)?.id()) + Ok(self.repo_ref.revparse_single(oid)?.id().into()) } pub(super) fn rev_to_commit(&self, rev: &Rev) -> Result { match rev { - Rev::Oid(oid) => Ok(self.repo_ref.find_commit(*oid)?), + Rev::Oid(oid) => Ok(self.repo_ref.find_commit((*oid).into())?), Rev::Ref(reference) => Ok(reference.find_ref(self)?.peel_to_commit()?), } } @@ -184,7 +184,7 @@ impl<'a> RepositoryRef<'a> { /// Get a particular `Commit`. pub(super) fn get_commit(&self, oid: Oid) -> Result, Error> { - let commit = self.repo_ref.find_commit(oid)?; + let commit = self.repo_ref.find_commit(oid.into())?; Ok(commit) } @@ -214,7 +214,7 @@ impl<'a> RepositoryRef<'a> { for commit_result_id in revwalk { // The revwalk iter returns results so // we unpack these and push them to the history - let commit_id: Oid = commit_result_id?; + let commit_id = commit_result_id?; // Skip the head commit since we have processed it if commit_id == head_id { @@ -278,10 +278,11 @@ impl<'a> RepositoryRef<'a> { } fn reachable_from(&self, reference: &git2::Reference, oid: &Oid) -> Result { + let git2_oid = (*oid).into(); let other = reference.peel_to_commit()?.id(); - let is_descendant = self.repo_ref.graph_descendant_of(other, *oid)?; + let is_descendant = self.repo_ref.graph_descendant_of(other, git2_oid)?; - Ok(other == *oid || is_descendant) + Ok(other == git2_oid || is_descendant) } /// Get the history of the file system where the head of the [`NonEmpty`] is @@ -296,10 +297,10 @@ impl<'a> RepositoryRef<'a> { let mut commits = vec![]; // Set the revwalk to the head commit - revwalk.push(commit.id)?; + revwalk.push(commit.id.into())?; for commit in revwalk { - let parent_id: Oid = commit?; + let parent_id = commit?; let parent = self.repo_ref.find_commit(parent_id)?; let paths = self.diff_commit_and_parents(path, &parent)?; if let Some(_path) = paths { @@ -333,8 +334,8 @@ impl<'a> RepositoryRef<'a> { fn diff_commits( &self, path: Option<&file_system::Path>, - from: Option, - to: Oid, + from: Option, + to: git2::Oid, ) -> Result { let new_tree = self.repo_ref.find_commit(to)?.tree()?; let old_tree = from.map_or(Ok(None), |oid| { diff --git a/radicle-surf/src/vcs/git/stats.rs b/radicle-surf/src/vcs/git/stats.rs index 25f4e71..5f0ad79 100644 --- a/radicle-surf/src/vcs/git/stats.rs +++ b/radicle-surf/src/vcs/git/stats.rs @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -pub use git2::Oid; +pub use radicle_git_ext::Oid; #[cfg(feature = "serialize")] use serde::Serialize; diff --git a/radicle-surf/src/vcs/git/tag.rs b/radicle-surf/src/vcs/git/tag.rs index 755dc64..606f1ae 100644 --- a/radicle-surf/src/vcs/git/tag.rs +++ b/radicle-surf/src/vcs/git/tag.rs @@ -16,7 +16,7 @@ // along with this program. If not, see . use crate::vcs::git::{self, error::Error, reference::Ref, Author}; -use git2::Oid; +use radicle_git_ext::Oid; use std::{convert::TryFrom, fmt, str}; /// A newtype wrapper over `String` to separate out the fact that a caller wants @@ -112,9 +112,9 @@ impl<'repo> TryFrom> for Tag { type Error = str::Utf8Error; fn try_from(tag: git2::Tag) -> Result { - let id = tag.id(); + let id = tag.id().into(); - let target_id = tag.target_id(); + let target_id = tag.target_id().into(); let name = TagName::try_from(tag.name_bytes())?; @@ -163,7 +163,7 @@ impl<'repo> TryFrom> for Tag { { let commit = reference.peel_to_commit()?; Ok(Tag::Light { - id: commit.id(), + id: commit.id().into(), name, remote, })