mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-18 10:07:28 +00:00
revset: introduce wrapper struct to pass around workspace information
More workspace-derived parameters will be added, and I don't think wrapping with Option for each makes sense because all parameters should be available if workspace exists.
This commit is contained in:
parent
efb8c5e58a
commit
5c52b4e819
3 changed files with 44 additions and 30 deletions
|
@ -419,9 +419,9 @@ impl RevsetExpression {
|
||||||
pub fn evaluate<'repo>(
|
pub fn evaluate<'repo>(
|
||||||
&self,
|
&self,
|
||||||
repo: RepoRef<'repo>,
|
repo: RepoRef<'repo>,
|
||||||
workspace_id: Option<&WorkspaceId>,
|
workspace_ctx: Option<&RevsetWorkspaceContext>,
|
||||||
) -> Result<Box<dyn Revset<'repo> + 'repo>, RevsetError> {
|
) -> Result<Box<dyn Revset<'repo> + 'repo>, RevsetError> {
|
||||||
evaluate_expression(repo, self, workspace_id)
|
evaluate_expression(repo, self, workspace_ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1137,10 +1137,16 @@ impl<'revset, 'repo> Iterator for DifferenceRevsetIterator<'revset, 'repo> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Workspace information needed to evaluate revset expression.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct RevsetWorkspaceContext<'a> {
|
||||||
|
pub workspace_id: &'a WorkspaceId,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn evaluate_expression<'repo>(
|
pub fn evaluate_expression<'repo>(
|
||||||
repo: RepoRef<'repo>,
|
repo: RepoRef<'repo>,
|
||||||
expression: &RevsetExpression,
|
expression: &RevsetExpression,
|
||||||
workspace_id: Option<&WorkspaceId>,
|
workspace_ctx: Option<&RevsetWorkspaceContext>,
|
||||||
) -> Result<Box<dyn Revset<'repo> + 'repo>, RevsetError> {
|
) -> Result<Box<dyn Revset<'repo> + 'repo>, RevsetError> {
|
||||||
match expression {
|
match expression {
|
||||||
RevsetExpression::None => Ok(Box::new(EagerRevset {
|
RevsetExpression::None => Ok(Box::new(EagerRevset {
|
||||||
|
@ -1148,12 +1154,12 @@ pub fn evaluate_expression<'repo>(
|
||||||
})),
|
})),
|
||||||
RevsetExpression::Commits(commit_ids) => Ok(revset_for_commit_ids(repo, commit_ids)),
|
RevsetExpression::Commits(commit_ids) => Ok(revset_for_commit_ids(repo, commit_ids)),
|
||||||
RevsetExpression::Symbol(symbol) => {
|
RevsetExpression::Symbol(symbol) => {
|
||||||
let commit_ids = resolve_symbol(repo, symbol, workspace_id)?;
|
let commit_ids = resolve_symbol(repo, symbol, workspace_ctx.map(|c| c.workspace_id))?;
|
||||||
evaluate_expression(repo, &RevsetExpression::Commits(commit_ids), workspace_id)
|
evaluate_expression(repo, &RevsetExpression::Commits(commit_ids), workspace_ctx)
|
||||||
}
|
}
|
||||||
RevsetExpression::Parents(base_expression) => {
|
RevsetExpression::Parents(base_expression) => {
|
||||||
// TODO: Make this lazy
|
// TODO: Make this lazy
|
||||||
let base_set = base_expression.evaluate(repo, workspace_id)?;
|
let base_set = base_expression.evaluate(repo, workspace_ctx)?;
|
||||||
let mut parent_entries = base_set
|
let mut parent_entries = base_set
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|entry| entry.parents())
|
.flat_map(|entry| entry.parents())
|
||||||
|
@ -1165,9 +1171,9 @@ pub fn evaluate_expression<'repo>(
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
RevsetExpression::Children(roots) => {
|
RevsetExpression::Children(roots) => {
|
||||||
let root_set = roots.evaluate(repo, workspace_id)?;
|
let root_set = roots.evaluate(repo, workspace_ctx)?;
|
||||||
let candidates_expression = roots.descendants();
|
let candidates_expression = roots.descendants();
|
||||||
let candidate_set = candidates_expression.evaluate(repo, workspace_id)?;
|
let candidate_set = candidates_expression.evaluate(repo, workspace_ctx)?;
|
||||||
Ok(Box::new(ChildrenRevset {
|
Ok(Box::new(ChildrenRevset {
|
||||||
root_set,
|
root_set,
|
||||||
candidate_set,
|
candidate_set,
|
||||||
|
@ -1175,11 +1181,11 @@ pub fn evaluate_expression<'repo>(
|
||||||
}
|
}
|
||||||
RevsetExpression::Ancestors(base_expression) => RevsetExpression::none()
|
RevsetExpression::Ancestors(base_expression) => RevsetExpression::none()
|
||||||
.range(base_expression)
|
.range(base_expression)
|
||||||
.evaluate(repo, workspace_id),
|
.evaluate(repo, workspace_ctx),
|
||||||
RevsetExpression::Range { roots, heads } => {
|
RevsetExpression::Range { roots, heads } => {
|
||||||
let root_set = roots.evaluate(repo, workspace_id)?;
|
let root_set = roots.evaluate(repo, workspace_ctx)?;
|
||||||
let root_ids = root_set.iter().commit_ids().collect_vec();
|
let root_ids = root_set.iter().commit_ids().collect_vec();
|
||||||
let head_set = heads.evaluate(repo, workspace_id)?;
|
let head_set = heads.evaluate(repo, workspace_ctx)?;
|
||||||
let head_ids = head_set.iter().commit_ids().collect_vec();
|
let head_ids = head_set.iter().commit_ids().collect_vec();
|
||||||
let walk = repo.index().walk_revs(&head_ids, &root_ids);
|
let walk = repo.index().walk_revs(&head_ids, &root_ids);
|
||||||
Ok(Box::new(RevWalkRevset { walk }))
|
Ok(Box::new(RevWalkRevset { walk }))
|
||||||
|
@ -1188,8 +1194,8 @@ pub fn evaluate_expression<'repo>(
|
||||||
// reverse
|
// reverse
|
||||||
#[allow(clippy::needless_collect)]
|
#[allow(clippy::needless_collect)]
|
||||||
RevsetExpression::DagRange { roots, heads } => {
|
RevsetExpression::DagRange { roots, heads } => {
|
||||||
let root_set = roots.evaluate(repo, workspace_id)?;
|
let root_set = roots.evaluate(repo, workspace_ctx)?;
|
||||||
let candidate_set = heads.ancestors().evaluate(repo, workspace_id)?;
|
let candidate_set = heads.ancestors().evaluate(repo, workspace_ctx)?;
|
||||||
let mut reachable: HashSet<_> = root_set.iter().map(|entry| entry.position()).collect();
|
let mut reachable: HashSet<_> = root_set.iter().map(|entry| entry.position()).collect();
|
||||||
let mut result = vec![];
|
let mut result = vec![];
|
||||||
let candidates = candidate_set.iter().collect_vec();
|
let candidates = candidate_set.iter().collect_vec();
|
||||||
|
@ -1214,7 +1220,7 @@ pub fn evaluate_expression<'repo>(
|
||||||
&repo.view().heads().iter().cloned().collect_vec(),
|
&repo.view().heads().iter().cloned().collect_vec(),
|
||||||
)),
|
)),
|
||||||
RevsetExpression::Heads(candidates) => {
|
RevsetExpression::Heads(candidates) => {
|
||||||
let candidate_set = candidates.evaluate(repo, workspace_id)?;
|
let candidate_set = candidates.evaluate(repo, workspace_ctx)?;
|
||||||
let candidate_ids = candidate_set.iter().commit_ids().collect_vec();
|
let candidate_ids = candidate_set.iter().commit_ids().collect_vec();
|
||||||
Ok(revset_for_commit_ids(
|
Ok(revset_for_commit_ids(
|
||||||
repo,
|
repo,
|
||||||
|
@ -1222,10 +1228,10 @@ pub fn evaluate_expression<'repo>(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
RevsetExpression::Roots(candidates) => {
|
RevsetExpression::Roots(candidates) => {
|
||||||
let connected_set = candidates.connected().evaluate(repo, workspace_id)?;
|
let connected_set = candidates.connected().evaluate(repo, workspace_ctx)?;
|
||||||
let filled: HashSet<_> = connected_set.iter().map(|entry| entry.position()).collect();
|
let filled: HashSet<_> = connected_set.iter().map(|entry| entry.position()).collect();
|
||||||
let mut index_entries = vec![];
|
let mut index_entries = vec![];
|
||||||
let candidate_set = candidates.evaluate(repo, workspace_id)?;
|
let candidate_set = candidates.evaluate(repo, workspace_ctx)?;
|
||||||
for candidate in candidate_set.iter() {
|
for candidate in candidate_set.iter() {
|
||||||
if !candidate
|
if !candidate
|
||||||
.parent_positions()
|
.parent_positions()
|
||||||
|
@ -1241,7 +1247,7 @@ pub fn evaluate_expression<'repo>(
|
||||||
candidates,
|
candidates,
|
||||||
parent_count_range,
|
parent_count_range,
|
||||||
} => {
|
} => {
|
||||||
let candidates = candidates.evaluate(repo, workspace_id)?;
|
let candidates = candidates.evaluate(repo, workspace_ctx)?;
|
||||||
let parent_count_range = parent_count_range.clone();
|
let parent_count_range = parent_count_range.clone();
|
||||||
Ok(Box::new(FilterRevset {
|
Ok(Box::new(FilterRevset {
|
||||||
candidates,
|
candidates,
|
||||||
|
@ -1289,7 +1295,7 @@ pub fn evaluate_expression<'repo>(
|
||||||
Ok(revset_for_commit_ids(repo, &commit_ids))
|
Ok(revset_for_commit_ids(repo, &commit_ids))
|
||||||
}
|
}
|
||||||
RevsetExpression::Description { needle, candidates } => {
|
RevsetExpression::Description { needle, candidates } => {
|
||||||
let candidates = candidates.evaluate(repo, workspace_id)?;
|
let candidates = candidates.evaluate(repo, workspace_ctx)?;
|
||||||
let repo = repo;
|
let repo = repo;
|
||||||
let needle = needle.clone();
|
let needle = needle.clone();
|
||||||
Ok(Box::new(FilterRevset {
|
Ok(Box::new(FilterRevset {
|
||||||
|
@ -1304,7 +1310,7 @@ pub fn evaluate_expression<'repo>(
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
RevsetExpression::Author { needle, candidates } => {
|
RevsetExpression::Author { needle, candidates } => {
|
||||||
let candidates = candidates.evaluate(repo, workspace_id)?;
|
let candidates = candidates.evaluate(repo, workspace_ctx)?;
|
||||||
let repo = repo;
|
let repo = repo;
|
||||||
let needle = needle.clone();
|
let needle = needle.clone();
|
||||||
// TODO: Make these functions that take a needle to search for accept some
|
// TODO: Make these functions that take a needle to search for accept some
|
||||||
|
@ -1320,7 +1326,7 @@ pub fn evaluate_expression<'repo>(
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
RevsetExpression::Committer { needle, candidates } => {
|
RevsetExpression::Committer { needle, candidates } => {
|
||||||
let candidates = candidates.evaluate(repo, workspace_id)?;
|
let candidates = candidates.evaluate(repo, workspace_ctx)?;
|
||||||
let repo = repo;
|
let repo = repo;
|
||||||
let needle = needle.clone();
|
let needle = needle.clone();
|
||||||
Ok(Box::new(FilterRevset {
|
Ok(Box::new(FilterRevset {
|
||||||
|
@ -1333,18 +1339,18 @@ pub fn evaluate_expression<'repo>(
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
RevsetExpression::Union(expression1, expression2) => {
|
RevsetExpression::Union(expression1, expression2) => {
|
||||||
let set1 = expression1.evaluate(repo, workspace_id)?;
|
let set1 = expression1.evaluate(repo, workspace_ctx)?;
|
||||||
let set2 = expression2.evaluate(repo, workspace_id)?;
|
let set2 = expression2.evaluate(repo, workspace_ctx)?;
|
||||||
Ok(Box::new(UnionRevset { set1, set2 }))
|
Ok(Box::new(UnionRevset { set1, set2 }))
|
||||||
}
|
}
|
||||||
RevsetExpression::Intersection(expression1, expression2) => {
|
RevsetExpression::Intersection(expression1, expression2) => {
|
||||||
let set1 = expression1.evaluate(repo, workspace_id)?;
|
let set1 = expression1.evaluate(repo, workspace_ctx)?;
|
||||||
let set2 = expression2.evaluate(repo, workspace_id)?;
|
let set2 = expression2.evaluate(repo, workspace_ctx)?;
|
||||||
Ok(Box::new(IntersectionRevset { set1, set2 }))
|
Ok(Box::new(IntersectionRevset { set1, set2 }))
|
||||||
}
|
}
|
||||||
RevsetExpression::Difference(expression1, expression2) => {
|
RevsetExpression::Difference(expression1, expression2) => {
|
||||||
let set1 = expression1.evaluate(repo, workspace_id)?;
|
let set1 = expression1.evaluate(repo, workspace_ctx)?;
|
||||||
let set2 = expression2.evaluate(repo, workspace_id)?;
|
let set2 = expression2.evaluate(repo, workspace_ctx)?;
|
||||||
Ok(Box::new(DifferenceRevset { set1, set2 }))
|
Ok(Box::new(DifferenceRevset { set1, set2 }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,9 @@ use jujutsu_lib::matchers::{FilesMatcher, Matcher};
|
||||||
use jujutsu_lib::op_store::{RefTarget, WorkspaceId};
|
use jujutsu_lib::op_store::{RefTarget, WorkspaceId};
|
||||||
use jujutsu_lib::repo::RepoRef;
|
use jujutsu_lib::repo::RepoRef;
|
||||||
use jujutsu_lib::repo_path::RepoPath;
|
use jujutsu_lib::repo_path::RepoPath;
|
||||||
use jujutsu_lib::revset::{self, parse, resolve_symbol, RevsetError, RevsetExpression};
|
use jujutsu_lib::revset::{
|
||||||
|
self, parse, resolve_symbol, RevsetError, RevsetExpression, RevsetWorkspaceContext,
|
||||||
|
};
|
||||||
use jujutsu_lib::testutils::{CommitGraphBuilder, TestRepo};
|
use jujutsu_lib::testutils::{CommitGraphBuilder, TestRepo};
|
||||||
use jujutsu_lib::{git, testutils};
|
use jujutsu_lib::{git, testutils};
|
||||||
use test_case::test_case;
|
use test_case::test_case;
|
||||||
|
@ -433,8 +435,9 @@ fn resolve_commit_ids_in_workspace(
|
||||||
workspace_id: &WorkspaceId,
|
workspace_id: &WorkspaceId,
|
||||||
) -> Vec<CommitId> {
|
) -> Vec<CommitId> {
|
||||||
let expression = parse(revset_str).unwrap();
|
let expression = parse(revset_str).unwrap();
|
||||||
|
let workspace_ctx = RevsetWorkspaceContext { workspace_id };
|
||||||
expression
|
expression
|
||||||
.evaluate(repo, Some(workspace_id))
|
.evaluate(repo, Some(&workspace_ctx))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.commit_ids()
|
.commit_ids()
|
||||||
|
|
|
@ -33,7 +33,9 @@ use jujutsu_lib::op_store::{OpStore, OpStoreError, OperationId, WorkspaceId};
|
||||||
use jujutsu_lib::operation::Operation;
|
use jujutsu_lib::operation::Operation;
|
||||||
use jujutsu_lib::repo::{BackendFactories, MutableRepo, ReadonlyRepo, RepoRef, RewriteRootCommit};
|
use jujutsu_lib::repo::{BackendFactories, MutableRepo, ReadonlyRepo, RepoRef, RewriteRootCommit};
|
||||||
use jujutsu_lib::repo_path::{FsPathParseError, RepoPath};
|
use jujutsu_lib::repo_path::{FsPathParseError, RepoPath};
|
||||||
use jujutsu_lib::revset::{Revset, RevsetError, RevsetExpression, RevsetParseError};
|
use jujutsu_lib::revset::{
|
||||||
|
Revset, RevsetError, RevsetExpression, RevsetParseError, RevsetWorkspaceContext,
|
||||||
|
};
|
||||||
use jujutsu_lib::settings::UserSettings;
|
use jujutsu_lib::settings::UserSettings;
|
||||||
use jujutsu_lib::transaction::Transaction;
|
use jujutsu_lib::transaction::Transaction;
|
||||||
use jujutsu_lib::tree::{Tree, TreeMergeError};
|
use jujutsu_lib::tree::{Tree, TreeMergeError};
|
||||||
|
@ -587,7 +589,10 @@ impl WorkspaceCommandHelper {
|
||||||
&'repo self,
|
&'repo self,
|
||||||
revset_expression: &RevsetExpression,
|
revset_expression: &RevsetExpression,
|
||||||
) -> Result<Box<dyn Revset<'repo> + 'repo>, RevsetError> {
|
) -> Result<Box<dyn Revset<'repo> + 'repo>, RevsetError> {
|
||||||
revset_expression.evaluate(self.repo.as_repo_ref(), Some(&self.workspace_id()))
|
let workspace_ctx = RevsetWorkspaceContext {
|
||||||
|
workspace_id: self.workspace.workspace_id(),
|
||||||
|
};
|
||||||
|
revset_expression.evaluate(self.repo.as_repo_ref(), Some(&workspace_ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_rewriteable(&self, commit: &Commit) -> Result<(), CommandError> {
|
pub fn check_rewriteable(&self, commit: &Commit) -> Result<(), CommandError> {
|
||||||
|
|
Loading…
Reference in a new issue