| |
pub static SIGNATURES_GLOB: Lazy<refspec::PatternString> =
|
| |
Lazy::new(|| refspec::pattern!("refs/remotes/*/radicle/signature"));
|
| |
|
| + |
#[derive(Error, Debug)]
|
| + |
pub enum IdentityError {
|
| + |
#[error("identity branches diverge from each other")]
|
| + |
BranchesDiverge,
|
| + |
#[error("identity branches are in an invalid state")]
|
| + |
InvalidState,
|
| + |
#[error("git: {0}")]
|
| + |
Git(#[from] git2::Error),
|
| + |
#[error("git: {0}")]
|
| + |
GitExt(#[from] git::Error),
|
| + |
#[error("refs: {0}")]
|
| + |
Refs(#[from] refs::Error),
|
| + |
}
|
| + |
|
| |
pub struct Storage {
|
| |
path: PathBuf,
|
| |
}
|
| |
}
|
| |
}
|
| |
|
| - |
pub fn identity(&self) -> Result<identity::Doc<Unverified>, refs::Error> {
|
| + |
/// Return the canonical identity [`git::Oid`] and document.
|
| + |
pub fn identity(&self) -> Result<(git::Oid, identity::Doc<Unverified>), IdentityError> {
|
| |
let mut heads = Vec::new();
|
| |
for remote in self.remote_ids()? {
|
| |
let remote = remote?;
|
| |
let oid = Doc::<Unverified>::head(&remote, self)?.unwrap();
|
| |
|
| - |
heads.push(*oid);
|
| + |
heads.push(oid.into());
|
| + |
}
|
| + |
// Keep track of the longest identity branch.
|
| + |
let mut longest = heads.pop().ok_or(IdentityError::InvalidState)?;
|
| + |
|
| + |
for head in &heads {
|
| + |
let base = self.raw().merge_base(*head, longest)?;
|
| + |
|
| + |
if base == longest {
|
| + |
// `head` is a successor of `longest`. Update `longest`.
|
| + |
//
|
| + |
// o head
|
| + |
// |
|
| + |
// o longest (base)
|
| + |
// |
|
| + |
//
|
| + |
longest = *head;
|
| + |
} else if base == *head || *head == longest {
|
| + |
// `head` is an ancestor of `longest`, or equal to it. Do nothing.
|
| + |
//
|
| + |
// o longest o longest, head (base)
|
| + |
// | |
|
| + |
// o head (base) OR o
|
| + |
// | |
|
| + |
//
|
| + |
} else {
|
| + |
// The merge base between `head` and `longest` (`base`)
|
| + |
// is neither `head` nor `longest`. Therefore, the branches have
|
| + |
// diverged.
|
| + |
//
|
| + |
// longest head
|
| + |
// \ /
|
| + |
// o (base)
|
| + |
// |
|
| + |
//
|
| + |
return Err(IdentityError::BranchesDiverge);
|
| + |
}
|
| |
}
|
| - |
let oid = self.raw().merge_base_many(&heads)?;
|
| - |
let (doc, _) = Doc::load_at(oid.into(), self)?.ok_or(refs::Error::NotFound)?;
|
| |
|
| - |
Ok(doc)
|
| + |
Doc::load_at(longest.into(), self)?
|
| + |
.ok_or(refs::Error::NotFound)
|
| + |
.map(|(doc, _)| (longest.into(), doc))
|
| + |
.map_err(IdentityError::from)
|
| |
}
|
| |
|
| |
pub fn remote_ids(
|