forked from mirrors/jj
revset: avoid using evolution for resolving a change id to its commits
This rewrites the code for resolving a change id to simply walk the entire index. That's obviously not optimal, but it's not worse than what we did in the evolution-based resolution. This is yet another step towards removing support for evolution (#32).
This commit is contained in:
parent
108c38d816
commit
56c7f32023
2 changed files with 18 additions and 41 deletions
|
@ -20,7 +20,6 @@ use itertools::Itertools;
|
|||
use crate::backend::{ChangeId, CommitId};
|
||||
use crate::commit::Commit;
|
||||
use crate::dag_walk::{bfs, leaves};
|
||||
use crate::index::{HexPrefix, PrefixResolution};
|
||||
use crate::repo::{MutableRepo, ReadonlyRepo, RepoRef};
|
||||
|
||||
// TODO: Combine some maps/sets and use a struct as value instead.
|
||||
|
@ -137,21 +136,6 @@ impl State {
|
|||
.map_or(false, |non_obsoletes| non_obsoletes.len() > 1)
|
||||
}
|
||||
|
||||
// TODO: We should probably add a change id table to the commit index and move
|
||||
// this there
|
||||
fn resolve_change_id_prefix(&self, prefix: &HexPrefix) -> PrefixResolution<ChangeId> {
|
||||
let mut result = PrefixResolution::NoMatch;
|
||||
for change_id in self.non_obsoletes_by_changeid.keys() {
|
||||
if change_id.hex().starts_with(prefix.hex()) {
|
||||
if result != PrefixResolution::NoMatch {
|
||||
return PrefixResolution::AmbiguousMatch;
|
||||
}
|
||||
result = PrefixResolution::SingleMatch(change_id.clone());
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn non_obsoletes(&self, change_id: &ChangeId) -> HashSet<CommitId> {
|
||||
self.non_obsoletes_by_changeid
|
||||
.get(change_id)
|
||||
|
@ -359,13 +343,6 @@ impl EvolutionRef<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn resolve_change_id_prefix(&self, prefix: &HexPrefix) -> PrefixResolution<ChangeId> {
|
||||
match self {
|
||||
EvolutionRef::Readonly(evolution) => evolution.resolve_change_id_prefix(prefix),
|
||||
EvolutionRef::Mutable(evolution) => evolution.resolve_change_id_prefix(prefix),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_divergent(&self, change_id: &ChangeId) -> bool {
|
||||
match self {
|
||||
EvolutionRef::Readonly(evolution) => evolution.is_divergent(change_id),
|
||||
|
@ -414,10 +391,6 @@ impl ReadonlyEvolution {
|
|||
self.state.is_divergent(change_id)
|
||||
}
|
||||
|
||||
pub fn resolve_change_id_prefix(&self, prefix: &HexPrefix) -> PrefixResolution<ChangeId> {
|
||||
self.state.resolve_change_id_prefix(prefix)
|
||||
}
|
||||
|
||||
pub fn non_obsoletes(&self, change_id: &ChangeId) -> HashSet<CommitId> {
|
||||
self.state.non_obsoletes(change_id)
|
||||
}
|
||||
|
@ -454,10 +427,6 @@ impl MutableEvolution {
|
|||
self.state.is_divergent(change_id)
|
||||
}
|
||||
|
||||
pub fn resolve_change_id_prefix(&self, prefix: &HexPrefix) -> PrefixResolution<ChangeId> {
|
||||
self.state.resolve_change_id_prefix(prefix)
|
||||
}
|
||||
|
||||
pub fn non_obsoletes(&self, change_id: &ChangeId) -> HashSet<CommitId> {
|
||||
self.state.non_obsoletes(change_id)
|
||||
}
|
||||
|
|
|
@ -99,18 +99,26 @@ fn resolve_commit_id(repo: RepoRef, symbol: &str) -> Result<Vec<CommitId>, Revse
|
|||
|
||||
fn resolve_change_id(repo: RepoRef, change_id_prefix: &str) -> Result<Vec<CommitId>, RevsetError> {
|
||||
if let Some(hex_prefix) = HexPrefix::new(change_id_prefix.to_owned()) {
|
||||
let evolution = repo.evolution();
|
||||
match evolution.resolve_change_id_prefix(&hex_prefix) {
|
||||
PrefixResolution::NoMatch => {
|
||||
Err(RevsetError::NoSuchRevision(change_id_prefix.to_owned()))
|
||||
}
|
||||
PrefixResolution::AmbiguousMatch => Err(RevsetError::AmbiguousChangeIdPrefix(
|
||||
change_id_prefix.to_owned(),
|
||||
)),
|
||||
PrefixResolution::SingleMatch(change_id) => {
|
||||
Ok(evolution.non_obsoletes(&change_id).into_iter().collect())
|
||||
let mut found_change_id = None;
|
||||
let mut commit_ids = vec![];
|
||||
// TODO: Create a persistent lookup from change id to (visible?) commit ids.
|
||||
for index_entry in RevsetExpression::all().evaluate(repo).unwrap().iter() {
|
||||
let change_id = index_entry.change_id();
|
||||
if change_id.hex().starts_with(hex_prefix.hex()) {
|
||||
if let Some(previous_change_id) = found_change_id.replace(change_id.clone()) {
|
||||
if previous_change_id != change_id {
|
||||
return Err(RevsetError::AmbiguousChangeIdPrefix(
|
||||
change_id_prefix.to_owned(),
|
||||
));
|
||||
}
|
||||
}
|
||||
commit_ids.push(index_entry.commit_id());
|
||||
}
|
||||
}
|
||||
if found_change_id.is_none() {
|
||||
return Err(RevsetError::NoSuchRevision(change_id_prefix.to_owned()));
|
||||
}
|
||||
Ok(commit_ids)
|
||||
} else {
|
||||
Err(RevsetError::NoSuchRevision(change_id_prefix.to_owned()))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue