patch: Fix bug where revisions can be replaced

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
This commit is contained in:
Alexis Sellier 2022-12-01 14:01:10 +01:00
parent ce11d69f23
commit eb92ac9036
No known key found for this signature in database
1 changed files with 39 additions and 6 deletions

View File

@ -1,4 +1,5 @@
#![allow(clippy::too_many_arguments)]
use std::collections::btree_map::Entry;
use std::collections::BTreeMap;
use std::fmt;
use std::ops::ControlFlow;
@ -261,10 +262,16 @@ impl Patch {
}
}
Action::Revision { base, oid } => {
self.revisions.insert(
id,
Redactable::Present(Revision::new(author, base, oid, timestamp)),
);
let revision = Redactable::Present(Revision::new(author, base, oid, timestamp));
match self.revisions.entry(id) {
Entry::Vacant(e) => {
e.insert(revision);
}
Entry::Occupied(mut e) => {
e.get_mut().merge(revision);
}
}
}
Action::Redact { revision } => {
if let Some(revision) = self.revisions.get_mut(&revision) {
@ -859,6 +866,14 @@ mod test {
Some((clock.tick(), Action::Merge { revision, commit }))
})
.variant(1, |(clock, revisions, _), rng| {
if revisions.is_empty() {
return None;
}
let revision = revisions[rng.usize(..revisions.len())];
Some((clock.tick(), Action::Redact { revision }))
})
.variant(1, |(clock, _, tags), rng| {
let add = iter::repeat_with(|| rng.alphabetic())
.take(rng.usize(0..=3))
@ -878,8 +893,9 @@ mod test {
let oid = oids[rng.usize(..oids.len())];
let base = oids[rng.usize(..oids.len())];
revisions.push((clock.tick(), author));
if rng.bool() {
revisions.push((clock.tick(), author));
}
Some((*clock, Action::Revision { base, oid }))
});
@ -1086,6 +1102,23 @@ mod test {
patch.apply([a4]).unwrap_err();
}
#[test]
fn test_revision_redacted_reinsert() {
let base = git::Oid::from_str("cb18e95ada2bb38aadd8e6cef0963ce37a87add3").unwrap();
let oid = git::Oid::from_str("518d5069f94c03427f694bb494ac1cd7d1339380").unwrap();
let mut alice = Actor::<_, Action>::new(MockSigner::default());
let mut p1 = Patch::default();
let mut p2 = Patch::default();
let a1 = alice.change(Action::Revision { base, oid });
let a2 = alice.change(Action::Redact { revision: a1.id() });
p1.apply([a1.clone(), a2.clone(), a1.clone()]).unwrap();
p2.apply([a1.clone(), a1, a2]).unwrap();
assert_eq!(p1, p2);
}
#[test]
fn test_patch_review_edit() {
let tmp = tempfile::tempdir().unwrap();