repo: add a workaround for merging repo views with Google's index

We do a 3-way merge of repo views in a few different
scenarios. Perhaps the most obvious one is when merging concurrent
operations. Another case is when undoing an operation.

One step of the 3-way repo view merge is to find which added commits
are rewrites of which removed commits (by comparing change IDs). With
the high commit rate in the Google repo (combined with storing the
commits on a server), this step can get extremely slow.

This patch adds a hack to disable the slow step when using a
non-standard `Index` implementation. The Google index is the only
non-standard implementation I'm aware of, so I don't think this will
affect anyone else. The patch is also small enough that I don't think
it will cause much maintenance overhead for the project.
This commit is contained in:
Martin von Zweigbergk 2024-05-11 16:34:35 -07:00 committed by Martin von Zweigbergk
parent 728e9e0772
commit 256988de65

View file

@ -35,7 +35,7 @@ use crate::backend::{
};
use crate::commit::{Commit, CommitByCommitterTimestamp};
use crate::commit_builder::CommitBuilder;
use crate::default_index::DefaultIndexStore;
use crate::default_index::{DefaultIndexStore, DefaultMutableIndex};
use crate::default_submodule_store::DefaultSubmoduleStore;
use crate::file_util::{IoResultExt as _, PathError};
use crate::git_backend::GitBackend;
@ -1612,12 +1612,20 @@ impl MutableRepo {
.set_wc_commit(workspace_id.clone(), other_wc_commit.clone());
}
}
let base_heads = base.heads().iter().cloned().collect_vec();
let own_heads = self.view().heads().iter().cloned().collect_vec();
let other_heads = other.heads().iter().cloned().collect_vec();
// HACK: Don't walk long ranges of commits to find rewrites when using other
// custom implementations. The only custom index implementation we're currently
// aware of is Google's. That repo has too high commit rate for it to be
// feasible to walk all added and removed commits.
// TODO: Fix this somehow. Maybe a method on `Index` to find rewritten commits
// given `base_heads`, `own_heads` and `other_heads`?
if self.index.as_any().is::<DefaultMutableIndex>() {
self.record_rewrites(&base_heads, &own_heads);
self.record_rewrites(&base_heads, &other_heads);
}
// No need to remove heads removed by `other` because we already marked them
// abandoned or rewritten.
for added_head in other.heads().difference(base.heads()) {