Skip to content

Commit

Permalink
replication: update delegate on fast-forward
Browse files Browse the repository at this point in the history
When a delegate's rad/id already exists we check that the
rad/ids/<urn.id> for the project being replicated is a fast-forward for
rad/id. If that's the case we can safely update the rad/id to the latest
tip.

The `fast_forward` function works as follows:
1. Get tip of rad/id
2. Check the verified person's tip is a descendant of 1.
3. If so, update rad/id

Signed-off-by: Fintan Halpenny <[email protected]>
  • Loading branch information
FintanH committed Aug 9, 2021
1 parent 8c5650b commit c01da9f
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 6 deletions.
17 changes: 16 additions & 1 deletion librad/src/git/identities/person.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

use std::{convert::TryFrom, fmt::Debug};

use radicle_git_ext::{is_not_found_err, OneLevel};
use radicle_git_ext::{self as ext, is_not_found_err, OneLevel};

use super::{
super::{
Expand Down Expand Up @@ -189,6 +189,21 @@ where
Ok(verified(storage).newer(a, b)?)
}

pub fn fast_forward(storage: &Storage, latest: &VerifiedPerson) -> Result<Option<ext::Oid>, Error> {
let urn = latest.urn().with_path(None);
let id_ref = super::common::IdRef::from(&urn);
let canonical = id_ref.oid(storage)?;
let tip = latest.content_id;
Ok(if storage.as_raw().graph_descendant_of(*tip, *canonical)? {
id_ref
.update(storage, tip, &format!("fast-forward to {}", tip))
.map_err(|e| Error::Store(e.into()))?;
Some(tip)
} else {
None
})
}

fn identities<S>(storage: &S) -> Identities<Person>
where
S: AsRef<storage::ReadOnly>,
Expand Down
14 changes: 10 additions & 4 deletions librad/src/git/replication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -805,9 +805,15 @@ mod project {
project_urn: &Urn,
) -> Result<(), Error> {
let delegate_urn = person.urn();
ensure_rad_id(storage, &delegate_urn, person.content_id)?;
tracking::track(storage, &delegate_urn, peer)?;
tracking::track(storage, project_urn, peer)?;

// if the identity is known we see if we can fast-forward it
if storage.has_urn(&delegate_urn)? {
identities::person::fast_forward(storage, person)?;
} else {
ensure_rad_id(storage, &delegate_urn, person.content_id)?;
tracking::track(storage, &delegate_urn, peer)?;
tracking::track(storage, project_urn, peer)?;
}

// Now point our view to the top-level
symref(
Expand Down Expand Up @@ -927,7 +933,7 @@ mod project {
S: AsRef<storage::ReadOnly>,
{
let storage = storage.as_ref();
identities::project::verify_with(storage, &urn, |delegate| {
identities::project::verify_with(storage, urn, |delegate| {
let refname =
Reference::rad_delegate(Namespace::from(urn.clone()), &delegate).with_remote(peer);
storage.reference_oid(&refname).map(|oid| oid.into())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2019-2020 The Radicle Foundation <[email protected]>
// Copyright © 2021 The Radicle Link Contributors
//
// This file is part of radicle-link, distributed under the GPLv3 with Radicle
// Linking Exception. For full terms see the included LICENSE file.
Expand Down

0 comments on commit c01da9f

Please sign in to comment.