From 44a3a09e5cb7ccdab0f06e91433da8c02a91534e Mon Sep 17 00:00:00 2001 From: Fintan Halpenny Date: Thu, 27 Apr 2023 15:21:43 +0100 Subject: [PATCH] radicle: check if ref exists when removing a cob If the reference did not exist it is not necessary to create a new `sigrefs` entry. Check that the reference exists before removing from the cob store and only sign if it did. Signed-off-by: Fintan Halpenny X-Clacks-Overhead: GNU Terry Pratchett --- radicle/src/cob/store.rs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/radicle/src/cob/store.rs b/radicle/src/cob/store.rs index ad44befa..82d7048c 100644 --- a/radicle/src/cob/store.rs +++ b/radicle/src/cob/store.rs @@ -105,6 +105,12 @@ pub enum Error { NotFound(TypeName, ObjectId), #[error("signed refs: {0}")] SignRefs(#[from] storage::Error), + #[error("failed to find reference '{name}': {err}")] + RefLookup { + name: git::RefString, + #[source] + err: git::Error, + }, } /// Storage for collaborative objects of a specific type `T` in a single repository. @@ -237,10 +243,23 @@ where /// Remove an object. pub fn remove(&self, id: &ObjectId, signer: &G) -> Result<(), Error> { - cob::remove(self.repo, signer.public_key(), T::type_name(), id)?; - self.repo.sign_refs(signer).map_err(Error::SignRefs)?; - - Ok(()) + let name = git::refs::storage::cob(signer.public_key(), T::type_name(), id); + match self + .repo + .reference_oid(signer.public_key(), &name.strip_namespace()) + { + Ok(_) => { + cob::remove(self.repo, signer.public_key(), T::type_name(), id)?; + self.repo.sign_refs(signer).map_err(Error::SignRefs)?; + Ok(()) + } + Err(git::Error::NotFound(_)) => Ok(()), + Err(git::Error::Git(err)) if err.code() == git::raw::ErrorCode::NotFound => Ok(()), + Err(err) => Err(Error::RefLookup { + name: name.to_ref_string(), + err, + }), + } } }