Skip to content

Commit

Permalink
cli: add convenient method to intersect user revset with other expres…
Browse files Browse the repository at this point in the history
…sion

This pattern is common, and most callers of evaluate_revset() can now be
migrated to the wrapper API.
  • Loading branch information
yuja committed Apr 1, 2024
1 parent 6902706 commit 784d735
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 26 deletions.
8 changes: 4 additions & 4 deletions cli/src/cli_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1016,10 +1016,10 @@ impl WorkspaceCommandHelper {
.map(|commit| commit.id().clone())
.collect(),
);
let immutable_revset =
revset_util::parse_immutable_expression(&self.revset_parse_context())?;
let revset = self.evaluate_revset(to_rewrite_revset.intersection(&immutable_revset))?;
if let Some(commit) = revset.iter().commits(self.repo().store()).next() {
let immutable = revset_util::parse_immutable_expression(&self.revset_parse_context())?;
let mut expression = self.attach_revset_evaluator(immutable)?;
expression.intersect_with(&to_rewrite_revset);
if let Some(commit) = expression.evaluate_to_commits()?.next() {
let commit = commit?;
let error = if commit.id() == self.repo().store().root_commit_id() {
user_error(format!(
Expand Down
12 changes: 3 additions & 9 deletions cli/src/commands/branch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use std::io::Write as _;

use clap::builder::NonEmptyStringValueParser;
use itertools::Itertools;
use jj_lib::backend::CommitId;
use jj_lib::git;
use jj_lib::object_id::ObjectId;
use jj_lib::op_store::{RefTarget, RemoteRef};
Expand Down Expand Up @@ -624,15 +623,10 @@ fn cmd_branch_list(
}
if !args.revisions.is_empty() {
// Match against local targets only, which is consistent with "jj git push".
let filter_expression = workspace_command
.parse_union_revsets(&args.revisions)?
.expression()
.clone();
let mut expression = workspace_command.parse_union_revsets(&args.revisions)?;
// Intersects with the set of local branch targets to minimize the lookup space.
let revset_expression = RevsetExpression::branches(StringPattern::everything())
.intersection(&filter_expression);
let revset = workspace_command.evaluate_revset(revset_expression)?;
let filtered_targets: HashSet<CommitId> = revset.iter().collect();
expression.intersect_with(&RevsetExpression::branches(StringPattern::everything()));
let filtered_targets: HashSet<_> = expression.evaluate_to_commit_ids()?.collect();
branch_names.extend(
view.local_branches()
.filter(|(_, target)| {
Expand Down
9 changes: 3 additions & 6 deletions cli/src/commands/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1203,12 +1203,9 @@ fn find_branches_targeted_by_revisions<'a>(
}
}
for rev_str in revisions {
let expression = workspace_command
.parse_revset(rev_str)?
.expression()
.intersection(&RevsetExpression::branches(StringPattern::everything()));
let revset = workspace_command.evaluate_revset(expression)?;
let mut commit_ids = revset.iter().peekable();
let mut expression = workspace_command.parse_revset(rev_str)?;
expression.intersect_with(&RevsetExpression::branches(StringPattern::everything()));
let mut commit_ids = expression.evaluate_to_commit_ids()?.peekable();
if commit_ids.peek().is_none() {
let rev_str: &str = rev_str;
writeln!(
Expand Down
12 changes: 5 additions & 7 deletions cli/src/commands/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,24 +81,22 @@ pub(crate) fn cmd_log(
workspace_command.parse_revset(&command.settings().default_revset())?
} else {
workspace_command.parse_union_revsets(&args.revisions)?
}
.expression()
.clone();
};
if !args.paths.is_empty() {
let repo_paths: Vec<_> = args
.paths
.iter()
.map(|path_arg| workspace_command.parse_file_path(path_arg))
.try_collect()?;
expression = expression.intersection(&RevsetExpression::filter(
RevsetFilterPredicate::File(Some(repo_paths)),
));
expression.intersect_with(&RevsetExpression::filter(RevsetFilterPredicate::File(
Some(repo_paths),
)));
}
expression
};
let repo = workspace_command.repo();
let matcher = workspace_command.matcher_from_values(&args.paths)?;
let revset = workspace_command.evaluate_revset(revset_expression)?;
let revset = revset_expression.evaluate()?;

let store = repo.store();
let diff_formats =
Expand Down
5 changes: 5 additions & 0 deletions cli/src/revset_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ impl<'repo> RevsetExpressionEvaluator<'repo> {
&self.expression
}

/// Intersects the underlying expression with the `other` expression.
pub fn intersect_with(&mut self, other: &Rc<RevsetExpression>) {
self.expression = self.expression.intersection(other);
}

/// Evaluates the expression.
pub fn evaluate(&self) -> Result<Box<dyn Revset + 'repo>, UserRevsetEvaluationError> {
let symbol_resolver = default_symbol_resolver(self.repo, self.id_prefix_context);
Expand Down

0 comments on commit 784d735

Please sign in to comment.