remote-helper: remove check for fast-forward
Since the commit is now always pushed to the Radicle storage, there is no need to check for fast-forward. If heads diverge, it will be reported by the quorum error.
This commit is contained in:
parent
119a124897
commit
690f6b02c0
|
|
@ -361,9 +361,9 @@ pub fn run(
|
||||||
.ok_or(Error::UnknownObjectType { oid: *src })?;
|
.ok_or(Error::UnknownObjectType { oid: *src })?;
|
||||||
|
|
||||||
let canonical = canonical::Canonical::new(me, object, canonical)?;
|
let canonical = canonical::Canonical::new(me, object, canonical)?;
|
||||||
match canonical.quorum(&working) {
|
match canonical.quorum() {
|
||||||
Ok(quorum) => set_canonical_refs.push(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)
|
Ok(explorer)
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,12 @@
|
||||||
use radicle::git;
|
use radicle::git;
|
||||||
use radicle::git::canonical;
|
use radicle::git::canonical;
|
||||||
use radicle::git::canonical::effects;
|
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 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.
|
/// Validates a vote to update a canonical reference during push.
|
||||||
pub(crate) struct Canonical<'a, 'b, 'r, R> {
|
pub(crate) struct Canonical<'a, 'b, 'r, R> {
|
||||||
vote: Vote,
|
|
||||||
canonical: canonical::CanonicalWithConvergence<'a, 'b, 'r, R>,
|
canonical: canonical::CanonicalWithConvergence<'a, 'b, 'r, R>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -33,7 +21,6 @@ where
|
||||||
) -> Result<Self, canonical::error::FindObjectsError> {
|
) -> Result<Self, canonical::error::FindObjectsError> {
|
||||||
let canonical = canonical.find_objects()?;
|
let canonical = canonical.find_objects()?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
vote: Vote { object },
|
|
||||||
canonical: canonical.with_convergence(me, object),
|
canonical: canonical.with_convergence(me, object),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -55,89 +42,47 @@ where
|
||||||
/// Ensures that the new head and the canonical commit do not diverge.
|
/// Ensures that the new head and the canonical commit do not diverge.
|
||||||
///
|
///
|
||||||
/// [`head`]: crate::push::canonical::Canonical::head
|
/// [`head`]: crate::push::canonical::Canonical::head
|
||||||
pub fn quorum(
|
pub fn quorum(self) -> Result<(git::Qualified<'a>, canonical::Object), QuorumError> {
|
||||||
self,
|
self.canonical
|
||||||
working: &Repository,
|
.quorum()
|
||||||
) -> Result<(git::Qualified<'a>, canonical::Object), error::Canonical> {
|
.map(|QuorumWithConvergence { quorum, .. }| (quorum.refname, quorum.object))
|
||||||
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(crate) mod io {
|
pub(crate) mod io {
|
||||||
use radicle::git;
|
|
||||||
use radicle::git::canonical::error::QuorumError;
|
use radicle::git::canonical::error::QuorumError;
|
||||||
|
|
||||||
use crate::push::error;
|
use crate::push::error;
|
||||||
use crate::{hint, warn};
|
use crate::warn;
|
||||||
|
|
||||||
/// Handle recoverable errors, printing relevant information to the
|
/// Handle recoverable errors, printing relevant information to the
|
||||||
/// terminal. Otherwise, convert the error into an unrecoverable error
|
/// terminal. Otherwise, convert the error into an unrecoverable error
|
||||||
/// [`error::CanonicalUnrecoverable`].
|
/// [`error::CanonicalUnrecoverable`].
|
||||||
pub fn handle_error(
|
pub fn handle_error(e: QuorumError) -> Result<(), error::CanonicalUnrecoverable> {
|
||||||
e: error::Canonical,
|
|
||||||
canonical: &git::Qualified,
|
|
||||||
hints: bool,
|
|
||||||
) -> Result<(), error::CanonicalUnrecoverable> {
|
|
||||||
match e {
|
match e {
|
||||||
error::Canonical::GraphDescendant(e) => Err(e.into()),
|
QuorumError::Convergence(err) => Err(err.into()),
|
||||||
error::Canonical::HeadsDiverge(e) => {
|
QuorumError::MergeBase(err) => Err(err.into()),
|
||||||
if hints {
|
e @ QuorumError::DivergingCommits { .. } => {
|
||||||
hint(
|
warn(e.to_string());
|
||||||
format!("you are attempting to push a commit that would cause \
|
warn("it is recommended to find a commit to agree upon");
|
||||||
your upstream to diverge from the canonical reference {canonical}"),
|
Ok(())
|
||||||
);
|
|
||||||
hint(
|
|
||||||
"to integrate the remote changes, run `git pull --rebase` \
|
|
||||||
and try again",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Err(e.into())
|
|
||||||
}
|
}
|
||||||
error::Canonical::Quorum(e) => {
|
e @ QuorumError::DivergingTags { .. } => {
|
||||||
match e {
|
warn(e.to_string());
|
||||||
QuorumError::Convergence(err) => Err(err.into()),
|
warn("it is recommended to find a tag to agree upon");
|
||||||
QuorumError::MergeBase(err) => Err(err.into()),
|
Ok(())
|
||||||
e @ QuorumError::DivergingCommits { .. } => {
|
}
|
||||||
warn(e.to_string());
|
e @ QuorumError::DifferentTypes { .. } => {
|
||||||
warn("it is recommended to find a commit to agree upon");
|
warn(e.to_string());
|
||||||
Ok(())
|
warn(
|
||||||
}
|
"it is recommended to find an object type (either commit or tag) to agree upon",
|
||||||
e @ QuorumError::DivergingTags { .. } => {
|
);
|
||||||
warn(e.to_string());
|
Ok(())
|
||||||
warn("it is recommended to find a tag to agree upon");
|
}
|
||||||
Ok(())
|
e @ QuorumError::NoCandidates { .. } => {
|
||||||
}
|
warn(e.to_string());
|
||||||
e @ QuorumError::DifferentTypes { .. } => {
|
warn("it is recommended to find an object (either commit or tag) to agree upon");
|
||||||
warn(e.to_string());
|
Ok(())
|
||||||
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(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,30 +18,6 @@ pub enum CanonicalUnrecoverable {
|
||||||
Git { source: git::raw::Error },
|
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)]
|
#[derive(Debug, Error)]
|
||||||
#[error("failed to check if {head} is an ancestor of {canonical} due to: {source}")]
|
#[error("failed to check if {head} is an ancestor of {canonical} due to: {source}")]
|
||||||
pub struct GraphDescendant {
|
pub struct GraphDescendant {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue