From 09feb2e28186e3584a62d89cb98aec8e4b9732bf Mon Sep 17 00:00:00 2001 From: Martin von Zweigbergk Date: Wed, 6 Oct 2021 22:50:11 -0700 Subject: [PATCH] cli: reimplement `divergent` template keyword without evolution (#32) This rewrites the `divergent` template keyword to be based on the number of visible commits with a given change id. That's the same as before; it's just that it's not based on the `Evolution` object's view of which commits are visible anymore. This is the last thing that depended on the evolution state! --- src/template_parser.rs | 2 +- src/templater.rs | 35 +++++++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/template_parser.rs b/src/template_parser.rs index 3cf5959db..e6fa8cebf 100644 --- a/src/template_parser.rs +++ b/src/template_parser.rs @@ -242,7 +242,7 @@ fn parse_commit_keyword<'a>(repo: RepoRef<'a>, pair: Pair) -> (Property<'a "branches" => Property::String(Box::new(BranchProperty { repo })), "tags" => Property::String(Box::new(TagProperty { repo })), "git_refs" => Property::String(Box::new(GitRefsProperty { repo })), - "divergent" => Property::Boolean(Box::new(DivergentProperty { repo })), + "divergent" => Property::Boolean(Box::new(DivergentProperty::new(repo))), "conflict" => Property::Boolean(Box::new(ConflictProperty)), name => panic!("unexpected identifier: {}", name), }; diff --git a/src/templater.rs b/src/templater.rs index c5203f0c6..d5a39155c 100644 --- a/src/templater.rs +++ b/src/templater.rs @@ -13,13 +13,15 @@ // limitations under the License. use std::borrow::BorrowMut; +use std::collections::{HashMap, HashSet}; use std::io; -use std::ops::Add; +use std::ops::{Add, AddAssign}; use itertools::Itertools; -use jujutsu_lib::backend::{CommitId, Signature}; +use jujutsu_lib::backend::{ChangeId, CommitId, Signature}; use jujutsu_lib::commit::Commit; use jujutsu_lib::repo::RepoRef; +use jujutsu_lib::revset::RevsetExpression; use crate::formatter::Formatter; @@ -286,13 +288,34 @@ impl TemplateProperty for GitRefsProperty<'_> { } } -pub struct DivergentProperty<'a> { - pub repo: RepoRef<'a>, +pub struct DivergentProperty { + divergent_changes: HashSet, } -impl TemplateProperty for DivergentProperty<'_> { +impl DivergentProperty { + pub fn new(repo: RepoRef) -> Self { + // TODO: Create a persistent index from change id to commit ids. + let mut commit_count_by_change: HashMap = HashMap::new(); + for index_entry in RevsetExpression::all().evaluate(repo).unwrap().iter() { + let change_id = index_entry.change_id(); + commit_count_by_change + .entry(change_id) + .or_default() + .add_assign(1); + } + let mut divergent_changes = HashSet::new(); + for (change_id, count) in commit_count_by_change { + if count > 1 { + divergent_changes.insert(change_id); + } + } + Self { divergent_changes } + } +} + +impl TemplateProperty for DivergentProperty { fn extract(&self, context: &Commit) -> bool { - self.repo.evolution().is_divergent(context.change_id()) + self.divergent_changes.contains(context.change_id()) } }