node: Allow most refs to be force-updated

Previously, during the "transfer" stage of a fetch, we used `force:
false`, which didn't allow refs to be force-updated.

This change makes it possible to fetch force-updated refs, but ensures
that the sigrefs branch is never force-updated.
This commit is contained in:
Alexis Sellier 2023-04-11 14:11:23 +02:00
parent 89b9eb53b7
commit eeec2008e8
No known key found for this signature in database
2 changed files with 45 additions and 10 deletions

View File

@ -234,24 +234,59 @@ impl<'a> StagingPhaseFinal<'a> {
{ {
let specs = verifications let specs = verifications
.into_iter() .into_iter()
.filter_map(|(remote, verified)| match verified { .flat_map(|(remote, verified)| match verified {
VerifiedRemote::Failed { reason } => { VerifiedRemote::Failed { reason } => {
log::warn!( log::warn!(
target: "worker", target: "worker",
"{remote} failed to verify, will not fetch any further refs: {reason}", "{remote} failed to verify, will not fetch any further refs: {reason}",
); );
None vec![]
} }
VerifiedRemote::Success { remote, .. } => { VerifiedRemote::Success { remote, .. } => {
let ns = remote.id.to_namespace().with_pattern(git::refspec::STAR); let ns = remote.id.to_namespace();
Some( let mut refspecs = vec![];
// First add the standard git refs.
let heads = ns.join(git::refname!("refs/heads"));
let cobs = ns.join(git::refname!("refs/cobs"));
let tags = ns.join(git::refname!("refs/tags"));
let notes = ns.join(git::refname!("refs/notes"));
for refname in [heads, cobs, tags, notes] {
let pattern = refname.with_pattern(git::refspec::STAR);
refspecs.push(
Refspec {
src: pattern.clone(),
dst: pattern,
force: true,
}
.to_string(),
);
}
// Then add the special refs.
let id = ns.join(&*radicle::git::refs::storage::IDENTITY_BRANCH);
let sigrefs = ns.join(&*radicle::git::refs::storage::SIGREFS_BRANCH);
refspecs.push(
Refspec { Refspec {
src: ns.clone(), src: id.clone(),
dst: ns, dst: id,
// Nb. The identity branch is allowed to be force-updated.
force: true,
}
.to_string(),
);
refspecs.push(
Refspec {
src: sigrefs.clone(),
dst: sigrefs,
// Nb. Sigrefs are never force-updated.
force: false, force: false,
} }
.to_string(), .to_string(),
) );
refspecs
} }
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();

View File

@ -21,14 +21,14 @@ pub struct Refspec<T, U> {
impl<T, U> fmt::Display for Refspec<T, U> impl<T, U> fmt::Display for Refspec<T, U>
where where
T: AsRef<git::PatternStr>, T: fmt::Display,
U: AsRef<git::PatternStr>, U: fmt::Display,
{ {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.force { if self.force {
f.write_char('+')?; f.write_char('+')?;
} }
write!(f, "{}:{}", self.src.as_ref(), self.dst.as_ref()) write!(f, "{}:{}", self.src, self.dst)
} }
} }