diff --git a/crates/radicle-remote-helper/src/push.rs b/crates/radicle-remote-helper/src/push.rs index 494875c1..c41770a8 100644 --- a/crates/radicle-remote-helper/src/push.rs +++ b/crates/radicle-remote-helper/src/push.rs @@ -361,9 +361,9 @@ pub fn run( .ok_or(Error::UnknownObjectType { oid: *src })?; let canonical = canonical::Canonical::new(me, object, canonical)?; - match canonical.quorum(&working) { + match canonical.quorum() { Ok(quorum) => set_canonical_refs.push(quorum), - Err(e) => canonical::io::handle_error(e, &dst, hints)?, + Err(e) => canonical::io::handle_error(e)?, } } Ok(explorer) diff --git a/crates/radicle-remote-helper/src/push/canonical.rs b/crates/radicle-remote-helper/src/push/canonical.rs index 2691b8ad..ba0640e5 100644 --- a/crates/radicle-remote-helper/src/push/canonical.rs +++ b/crates/radicle-remote-helper/src/push/canonical.rs @@ -1,24 +1,12 @@ use radicle::git; use radicle::git::canonical; use radicle::git::canonical::effects; -use radicle::git::raw::Repository; +use radicle::git::canonical::error::QuorumError; +use radicle::git::canonical::QuorumWithConvergence; use radicle::prelude::Did; -use super::error; - -pub(crate) struct Vote { - object: canonical::Object, -} - -impl Vote { - pub(crate) fn id(&self) -> git::Oid { - self.object.id() - } -} - /// Validates a vote to update a canonical reference during push. pub(crate) struct Canonical<'a, 'b, 'r, R> { - vote: Vote, canonical: canonical::CanonicalWithConvergence<'a, 'b, 'r, R>, } @@ -33,7 +21,6 @@ where ) -> Result { let canonical = canonical.find_objects()?; Ok(Self { - vote: Vote { object }, canonical: canonical.with_convergence(me, object), }) } @@ -55,89 +42,47 @@ where /// Ensures that the new head and the canonical commit do not diverge. /// /// [`head`]: crate::push::canonical::Canonical::head - pub fn quorum( - self, - working: &Repository, - ) -> Result<(git::Qualified<'a>, canonical::Object), error::Canonical> { - match self.canonical.quorum() { - Ok(result) => { - let canonical::QuorumWithConvergence { quorum, converges } = result; - let canonical::Quorum { refname, object } = quorum; - let quorum_head = object.id(); - // Canonical head is an ancestor of head. - let is_ff = self.vote.id() == quorum_head - || working - .graph_descendant_of(*self.vote.id(), *quorum_head) - .map_err(|err| { - error::Canonical::graph_descendant(self.vote.id(), quorum_head, err) - })?; - - if !is_ff && !converges { - Err(error::Canonical::heads_diverge(self.vote.id(), quorum_head)) - } else { - Ok((refname, object)) - } - } - Err(err) => Err(err.into()), - } + pub fn quorum(self) -> Result<(git::Qualified<'a>, canonical::Object), QuorumError> { + self.canonical + .quorum() + .map(|QuorumWithConvergence { quorum, .. }| (quorum.refname, quorum.object)) } } pub(crate) mod io { - use radicle::git; use radicle::git::canonical::error::QuorumError; use crate::push::error; - use crate::{hint, warn}; + use crate::warn; /// Handle recoverable errors, printing relevant information to the /// terminal. Otherwise, convert the error into an unrecoverable error /// [`error::CanonicalUnrecoverable`]. - pub fn handle_error( - e: error::Canonical, - canonical: &git::Qualified, - hints: bool, - ) -> Result<(), error::CanonicalUnrecoverable> { + pub fn handle_error(e: QuorumError) -> Result<(), error::CanonicalUnrecoverable> { match e { - error::Canonical::GraphDescendant(e) => Err(e.into()), - error::Canonical::HeadsDiverge(e) => { - if hints { - hint( - format!("you are attempting to push a commit that would cause \ - your upstream to diverge from the canonical reference {canonical}"), - ); - hint( - "to integrate the remote changes, run `git pull --rebase` \ - and try again", - ); - } - Err(e.into()) + QuorumError::Convergence(err) => Err(err.into()), + QuorumError::MergeBase(err) => Err(err.into()), + e @ QuorumError::DivergingCommits { .. } => { + warn(e.to_string()); + warn("it is recommended to find a commit to agree upon"); + Ok(()) } - error::Canonical::Quorum(e) => { - match e { - QuorumError::Convergence(err) => Err(err.into()), - QuorumError::MergeBase(err) => Err(err.into()), - e @ QuorumError::DivergingCommits { .. } => { - warn(e.to_string()); - warn("it is recommended to find a commit to agree upon"); - Ok(()) - } - e @ QuorumError::DivergingTags { .. } => { - warn(e.to_string()); - warn("it is recommended to find a tag to agree upon"); - Ok(()) - } - e @ QuorumError::DifferentTypes { .. } => { - warn(e.to_string()); - warn("it is recommended to find an object type (either commit or tag) to agree upon"); - Ok(()) - } - e @ QuorumError::NoCandidates { .. } => { - warn(e.to_string()); - warn("it is recommended to find an object (either commit or tag) to agree upon"); - Ok(()) - } - } + e @ QuorumError::DivergingTags { .. } => { + warn(e.to_string()); + warn("it is recommended to find a tag to agree upon"); + Ok(()) + } + e @ QuorumError::DifferentTypes { .. } => { + warn(e.to_string()); + warn( + "it is recommended to find an object type (either commit or tag) to agree upon", + ); + Ok(()) + } + e @ QuorumError::NoCandidates { .. } => { + warn(e.to_string()); + warn("it is recommended to find an object (either commit or tag) to agree upon"); + Ok(()) } } } diff --git a/crates/radicle-remote-helper/src/push/error.rs b/crates/radicle-remote-helper/src/push/error.rs index abc2abc0..e65be9e1 100644 --- a/crates/radicle-remote-helper/src/push/error.rs +++ b/crates/radicle-remote-helper/src/push/error.rs @@ -18,30 +18,6 @@ pub enum CanonicalUnrecoverable { Git { source: git::raw::Error }, } -#[derive(Debug, Error)] -pub enum Canonical { - #[error(transparent)] - GraphDescendant(GraphDescendant), - #[error(transparent)] - HeadsDiverge(HeadsDiverge), - #[error(transparent)] - Quorum(#[from] canonical::error::QuorumError), -} - -impl Canonical { - pub fn graph_descendant(head: git::Oid, canonical: git::Oid, source: git::raw::Error) -> Self { - Self::GraphDescendant(GraphDescendant { - head, - canonical, - source, - }) - } - - pub fn heads_diverge(head: git::Oid, canonical: git::Oid) -> Self { - Self::HeadsDiverge(HeadsDiverge { head, canonical }) - } -} - #[derive(Debug, Error)] #[error("failed to check if {head} is an ancestor of {canonical} due to: {source}")] pub struct GraphDescendant {