ok/jj
1
0
Fork 0
forked from mirrors/jj

view: create helper for enforcing view's invariants

The only invariant we currently enforce is that the set of heads does
not include any ancestors of other commits in the set. I'm about to
make sure that we don't end up with dangling git refs (pointing to
commits no reachable from the heads). It will be useful to have a
single place to enforce that since we'll need to do the same thing
after updating the view as after merging views.
This commit is contained in:
Martin von Zweigbergk 2021-01-15 16:23:33 -08:00
parent 1f27a78957
commit 1f593a4193

View file

@ -62,6 +62,13 @@ pub struct MutableView {
data: op_store::View,
}
fn enforce_invariants(store: &StoreWrapper, view: &mut op_store::View) {
// TODO: This is surely terribly slow on large repos, at least in its current
// form. We should make it faster (using the index) and avoid calling it in
// most cases (avoid adding a head that's already reachable in the view).
view.head_ids = heads_of_set(store, view.head_ids.iter().cloned());
}
fn heads_of_set(
store: &StoreWrapper,
commit_ids: impl Iterator<Item = CommitId>,
@ -148,7 +155,7 @@ pub fn merge_views(
for added_head in right.head_ids.difference(&base.head_ids) {
result.head_ids.insert(added_head.clone());
}
result.head_ids = heads_of_set(store, result.head_ids.into_iter());
enforce_invariants(store, &mut result);
// TODO: Should it be considered a conflict if a commit-head is removed on one
// side while a child or successor is created on another side? Maybe a
// warning?
@ -417,19 +424,12 @@ impl MutableView {
self.data.checkout = id;
}
// TODO: This is surely terribly slow on large repos, at least in its current
// form. We should make it faster (using the index) and avoid calling it in
// most cases (avoid adding a head that's already reachable in the view).
fn remove_non_heads(&mut self) {
self.data.head_ids = heads_of_set(&self.store, self.heads().cloned());
}
pub fn add_head(&mut self, head: &Commit) {
self.data.head_ids.insert(head.id().clone());
for parent in head.parents() {
self.data.head_ids.remove(parent.id());
}
self.remove_non_heads();
enforce_invariants(&self.store, &mut self.data);
}
pub fn remove_head(&mut self, head: &Commit) {
@ -446,7 +446,7 @@ impl MutableView {
pub fn set_view(&mut self, data: op_store::View) {
self.data = data;
self.remove_non_heads();
enforce_invariants(&self.store, &mut self.data);
}
pub fn save(self, description: String, operation_start_time: Timestamp) -> Operation {