cli: pass &Ui to parse fileset/revset/template functions

Deprecation warnings will be printed there. auto_tracking_matcher(ui) could
be cached, but there aren't many callers right now, so it should be okay to
parse and emit warnings for each invocation. Other than that, the changes are
straightforward.
This commit is contained in:
Yuya Nishihara 2024-09-19 14:27:34 +09:00
parent 09cedd83a7
commit 4533e81957
48 changed files with 179 additions and 131 deletions

View file

@ -41,7 +41,7 @@ fn run_custom_command(
match command {
CustomCommand::Frobnicate(args) => {
let mut workspace_command = command_helper.workspace_helper(ui)?;
let commit = workspace_command.resolve_single_rev(&args.revision)?;
let commit = workspace_command.resolve_single_rev(ui, &args.revision)?;
let mut tx = workspace_command.start_transaction();
let new_commit = tx
.repo_mut()

View file

@ -375,7 +375,7 @@ impl CommandHelper {
let op_head = self.resolve_operation(ui, workspace.repo_loader())?;
let repo = workspace.repo_loader().load_at(&op_head)?;
let env = self.workspace_environment(ui, &workspace)?;
WorkspaceCommandHelper::new(workspace, repo, env, self.is_at_head_operation())
WorkspaceCommandHelper::new(ui, workspace, repo, env, self.is_at_head_operation())
}
pub fn get_working_copy_factory(&self) -> Result<&dyn WorkingCopyFactory, CommandError> {
@ -491,7 +491,7 @@ impl CommandHelper {
) -> Result<WorkspaceCommandHelper, CommandError> {
let env = self.workspace_environment(ui, &workspace)?;
let loaded_at_head = true;
WorkspaceCommandHelper::new(workspace, repo, env, loaded_at_head)
WorkspaceCommandHelper::new(ui, workspace, repo, env, loaded_at_head)
}
}
@ -618,8 +618,8 @@ impl WorkspaceCommandEnvironment {
immutable_heads_expression: RevsetExpression::root(),
short_prefixes_expression: None,
};
env.immutable_heads_expression = env.load_immutable_heads_expression()?;
env.short_prefixes_expression = env.load_short_prefixes_expression()?;
env.immutable_heads_expression = env.load_immutable_heads_expression(ui)?;
env.short_prefixes_expression = env.load_short_prefixes_expression(ui)?;
Ok(env)
}
@ -678,12 +678,18 @@ impl WorkspaceCommandEnvironment {
&self.immutable_heads_expression
}
fn load_immutable_heads_expression(&self) -> Result<Rc<RevsetExpression>, CommandError> {
fn load_immutable_heads_expression(
&self,
_ui: &Ui,
) -> Result<Rc<RevsetExpression>, CommandError> {
revset_util::parse_immutable_heads_expression(&self.revset_parse_context())
.map_err(|e| config_error_with_message("Invalid `revset-aliases.immutable_heads()`", e))
}
fn load_short_prefixes_expression(&self) -> Result<Option<Rc<RevsetExpression>>, CommandError> {
fn load_short_prefixes_expression(
&self,
_ui: &Ui,
) -> Result<Option<Rc<RevsetExpression>>, CommandError> {
let revset_string = self
.settings()
.config()
@ -761,6 +767,7 @@ impl WorkspaceCommandEnvironment {
/// be one of the `L::wrap_*()` functions.
pub fn parse_template<'a, C: Clone + 'a, L: TemplateLanguage<'a> + ?Sized>(
&self,
_ui: &Ui,
language: &L,
template_text: &str,
wrap_self: impl Fn(PropertyPlaceholder<C>) -> L::Property,
@ -808,6 +815,7 @@ pub struct WorkspaceCommandHelper {
impl WorkspaceCommandHelper {
#[instrument(skip_all)]
fn new(
ui: &Ui,
workspace: Workspace,
repo: Arc<ReadonlyRepo>,
env: WorkspaceCommandEnvironment,
@ -831,9 +839,9 @@ impl WorkspaceCommandHelper {
};
// Parse commit_summary template early to report error before starting
// mutable operation.
helper.parse_operation_template(&helper.op_summary_template_text)?;
helper.parse_commit_template(&helper.commit_summary_template_text)?;
helper.parse_commit_template(SHORT_CHANGE_ID_TEMPLATE_TEXT)?;
helper.parse_operation_template(ui, &helper.op_summary_template_text)?;
helper.parse_commit_template(ui, &helper.commit_summary_template_text)?;
helper.parse_commit_template(ui, SHORT_CHANGE_ID_TEMPLATE_TEXT)?;
Ok(helper)
}
@ -1051,6 +1059,7 @@ impl WorkspaceCommandHelper {
/// Parses the given strings as file patterns.
pub fn parse_file_patterns(
&self,
ui: &Ui,
values: &[String],
) -> Result<FilesetExpression, CommandError> {
// TODO: This function might be superseded by parse_union_filesets(),
@ -1059,7 +1068,7 @@ impl WorkspaceCommandHelper {
if values.is_empty() {
Ok(FilesetExpression::all())
} else if self.settings().config().get_bool("ui.allow-filesets")? {
self.parse_union_filesets(values)
self.parse_union_filesets(ui, values)
} else {
let expressions = values
.iter()
@ -1073,6 +1082,7 @@ impl WorkspaceCommandHelper {
/// Parses the given fileset expressions and concatenates them all.
pub fn parse_union_filesets(
&self,
_ui: &Ui,
file_args: &[String], // TODO: introduce FileArg newtype?
) -> Result<FilesetExpression, CommandError> {
let expressions: Vec<_> = file_args
@ -1082,7 +1092,7 @@ impl WorkspaceCommandHelper {
Ok(FilesetExpression::union_all(expressions))
}
pub fn auto_tracking_matcher(&self) -> Result<Box<dyn Matcher>, CommandError> {
pub fn auto_tracking_matcher(&self, _ui: &Ui) -> Result<Box<dyn Matcher>, CommandError> {
let pattern = self.settings().config().get_string("snapshot.auto-track")?;
let expression = fileset::parse(
&pattern,
@ -1223,8 +1233,12 @@ impl WorkspaceCommandHelper {
/// Resolve a revset to a single revision. Return an error if the revset is
/// empty or has multiple revisions.
pub fn resolve_single_rev(&self, revision_arg: &RevisionArg) -> Result<Commit, CommandError> {
let expression = self.parse_revset(revision_arg)?;
pub fn resolve_single_rev(
&self,
ui: &Ui,
revision_arg: &RevisionArg,
) -> Result<Commit, CommandError> {
let expression = self.parse_revset(ui, revision_arg)?;
let should_hint_about_all_prefix = false;
revset_util::evaluate_revset_to_single_commit(
revision_arg.as_ref(),
@ -1241,11 +1255,12 @@ impl WorkspaceCommandHelper {
/// any number of revisions (including 0.)
pub fn resolve_some_revsets_default_single(
&self,
ui: &Ui,
revision_args: &[RevisionArg],
) -> Result<IndexSet<Commit>, CommandError> {
let mut all_commits = IndexSet::new();
for revision_arg in revision_args {
let (expression, modifier) = self.parse_revset_with_modifier(revision_arg)?;
let (expression, modifier) = self.parse_revset_with_modifier(ui, revision_arg)?;
let all = match modifier {
Some(RevsetModifier::All) => true,
None => self
@ -1282,9 +1297,10 @@ impl WorkspaceCommandHelper {
pub fn parse_revset(
&self,
ui: &Ui,
revision_arg: &RevisionArg,
) -> Result<RevsetExpressionEvaluator<'_>, CommandError> {
let (expression, modifier) = self.parse_revset_with_modifier(revision_arg)?;
let (expression, modifier) = self.parse_revset_with_modifier(ui, revision_arg)?;
// Whether the caller accepts multiple revisions or not, "all:" should
// be valid. For example, "all:@" is a valid single-rev expression.
let (None | Some(RevsetModifier::All)) = modifier;
@ -1293,6 +1309,7 @@ impl WorkspaceCommandHelper {
fn parse_revset_with_modifier(
&self,
_ui: &Ui,
revision_arg: &RevisionArg,
) -> Result<(RevsetExpressionEvaluator<'_>, Option<RevsetModifier>), CommandError> {
let context = self.revset_parse_context();
@ -1303,6 +1320,7 @@ impl WorkspaceCommandHelper {
/// Parses the given revset expressions and concatenates them all.
pub fn parse_union_revsets(
&self,
_ui: &Ui,
revision_args: &[RevisionArg],
) -> Result<RevsetExpressionEvaluator<'_>, CommandError> {
let context = self.revset_parse_context();
@ -1347,11 +1365,13 @@ impl WorkspaceCommandHelper {
/// be one of the `L::wrap_*()` functions.
pub fn parse_template<'a, C: Clone + 'a, L: TemplateLanguage<'a> + ?Sized>(
&self,
ui: &Ui,
language: &L,
template_text: &str,
wrap_self: impl Fn(PropertyPlaceholder<C>) -> L::Property,
) -> TemplateParseResult<TemplateRenderer<'a, C>> {
self.env.parse_template(language, template_text, wrap_self)
self.env
.parse_template(ui, language, template_text, wrap_self)
}
/// Parses template that is validated by `Self::new()`.
@ -1369,10 +1389,12 @@ impl WorkspaceCommandHelper {
/// Parses commit template into evaluation tree.
pub fn parse_commit_template(
&self,
ui: &Ui,
template_text: &str,
) -> TemplateParseResult<TemplateRenderer<'_, Commit>> {
let language = self.commit_template_language();
self.parse_template(
ui,
&language,
template_text,
CommitTemplateLanguage::wrap_commit,
@ -1382,10 +1404,12 @@ impl WorkspaceCommandHelper {
/// Parses commit template into evaluation tree.
pub fn parse_operation_template(
&self,
ui: &Ui,
template_text: &str,
) -> TemplateParseResult<TemplateRenderer<'_, Operation>> {
let language = self.operation_template_language();
self.parse_template(
ui,
&language,
template_text,
OperationTemplateLanguage::wrap_operation,
@ -1484,7 +1508,7 @@ impl WorkspaceCommandHelper {
return Ok(());
};
let base_ignores = self.base_ignores()?;
let auto_tracking_matcher = self.auto_tracking_matcher()?;
let auto_tracking_matcher = self.auto_tracking_matcher(ui)?;
// Compare working-copy tree and operation with repo's, and reload as needed.
let fsmonitor_settings = self.settings().fsmonitor_settings()?;
@ -2003,10 +2027,12 @@ impl WorkspaceCommandTransaction<'_> {
/// Parses commit template with the current transaction state.
pub fn parse_commit_template(
&self,
ui: &Ui,
template_text: &str,
) -> TemplateParseResult<TemplateRenderer<'_, Commit>> {
let language = self.commit_template_language();
self.helper.env.parse_template(
ui,
&language,
template_text,
CommitTemplateLanguage::wrap_commit,

View file

@ -53,7 +53,7 @@ pub(crate) fn cmd_abandon(
) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let to_abandon: Vec<_> = workspace_command
.parse_union_revsets(&args.revisions)?
.parse_union_revsets(ui, &args.revisions)?
.evaluate_to_commits()?
.try_collect()?;
if to_abandon.is_empty() {

View file

@ -43,7 +43,7 @@ pub(crate) fn cmd_backout(
) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let to_back_out: Vec<_> = workspace_command
.parse_union_revsets(&args.revisions)?
.parse_union_revsets(ui, &args.revisions)?
.evaluate_to_commits()?
.try_collect()?; // in reverse topological order
if to_back_out.is_empty() {
@ -52,7 +52,7 @@ pub(crate) fn cmd_backout(
}
let mut parents = vec![];
for revision_str in &args.destination {
let destination = workspace_command.resolve_single_rev(revision_str)?;
let destination = workspace_command.resolve_single_rev(ui, revision_str)?;
parents.push(destination);
}
let mut tx = workspace_command.start_transaction();

View file

@ -143,8 +143,8 @@ pub(crate) fn cmd_bench(
match subcommand {
BenchCommand::CommonAncestors(args) => {
let workspace_command = command.workspace_helper(ui)?;
let commit1 = workspace_command.resolve_single_rev(&args.revision1)?;
let commit2 = workspace_command.resolve_single_rev(&args.revision2)?;
let commit1 = workspace_command.resolve_single_rev(ui, &args.revision1)?;
let commit2 = workspace_command.resolve_single_rev(ui, &args.revision2)?;
let index = workspace_command.repo().index();
let routine =
|| index.common_ancestors(&[commit1.id().clone()], &[commit2.id().clone()]);
@ -157,8 +157,8 @@ pub(crate) fn cmd_bench(
}
BenchCommand::IsAncestor(args) => {
let workspace_command = command.workspace_helper(ui)?;
let ancestor_commit = workspace_command.resolve_single_rev(&args.ancestor)?;
let descendant_commit = workspace_command.resolve_single_rev(&args.descendant)?;
let ancestor_commit = workspace_command.resolve_single_rev(ui, &args.ancestor)?;
let descendant_commit = workspace_command.resolve_single_rev(ui, &args.descendant)?;
let index = workspace_command.repo().index();
let routine = || index.is_ancestor(ancestor_commit.id(), descendant_commit.id());
run_bench(
@ -213,7 +213,12 @@ fn bench_revset<M: Measurement>(
revset: &RevisionArg,
) -> Result<(), CommandError> {
writeln!(ui.status(), "----------Testing revset: {revset}----------")?;
let expression = revset::optimize(workspace_command.parse_revset(revset)?.expression().clone());
let expression = revset::optimize(
workspace_command
.parse_revset(ui, revset)?
.expression()
.clone(),
);
// Time both evaluation and iteration.
let routine = |workspace_command: &WorkspaceCommandHelper, expression: Rc<RevsetExpression>| {
// Evaluate the expression without parsing/evaluating short-prefixes.

View file

@ -44,8 +44,8 @@ pub fn cmd_bookmark_create(
args: &BookmarkCreateArgs,
) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let target_commit =
workspace_command.resolve_single_rev(args.revision.as_ref().unwrap_or(&RevisionArg::AT))?;
let target_commit = workspace_command
.resolve_single_rev(ui, args.revision.as_ref().unwrap_or(&RevisionArg::AT))?;
let view = workspace_command.repo().view();
let bookmark_names = &args.names;
for name in bookmark_names {

View file

@ -96,7 +96,7 @@ pub fn cmd_bookmark_list(
}
if !args.revisions.is_empty() {
// Match against local targets only, which is consistent with "jj git push".
let mut expression = workspace_command.parse_union_revsets(&args.revisions)?;
let mut expression = workspace_command.parse_union_revsets(ui, &args.revisions)?;
// Intersects with the set of local bookmark targets to minimize the lookup
// space.
expression.intersect_with(&RevsetExpression::bookmarks(StringPattern::everything()));
@ -121,7 +121,7 @@ pub fn cmd_bookmark_list(
None => command.settings().config().get("templates.bookmark_list")?,
};
workspace_command
.parse_template(&language, &text, CommitTemplateLanguage::wrap_ref_name)?
.parse_template(ui, &language, &text, CommitTemplateLanguage::wrap_ref_name)?
.labeled("bookmark_list")
};

View file

@ -70,11 +70,11 @@ pub fn cmd_bookmark_move(
let mut workspace_command = command.workspace_helper(ui)?;
let repo = workspace_command.repo().clone();
let target_commit = workspace_command.resolve_single_rev(&args.to)?;
let target_commit = workspace_command.resolve_single_rev(ui, &args.to)?;
let matched_bookmarks = {
let is_source_commit = if !args.from.is_empty() {
workspace_command
.parse_union_revsets(&args.from)?
.parse_union_revsets(ui, &args.from)?
.evaluate()?
.containing_fn()
} else {

View file

@ -46,8 +46,8 @@ pub fn cmd_bookmark_set(
args: &BookmarkSetArgs,
) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let target_commit =
workspace_command.resolve_single_rev(args.revision.as_ref().unwrap_or(&RevisionArg::AT))?;
let target_commit = workspace_command
.resolve_single_rev(ui, args.revision.as_ref().unwrap_or(&RevisionArg::AT))?;
let repo = workspace_command.repo().as_ref();
let bookmark_names = &args.names;
let mut new_bookmark_count = 0;

View file

@ -87,7 +87,7 @@ pub fn cmd_bookmark_track(
.config()
.get::<String>("templates.bookmark_list")?;
workspace_command
.parse_template(&language, &text, CommitTemplateLanguage::wrap_ref_name)?
.parse_template(ui, &language, &text, CommitTemplateLanguage::wrap_ref_name)?
.labeled("bookmark_list")
};

View file

@ -53,7 +53,7 @@ pub(crate) fn cmd_checkout(
"`jj checkout` will be removed in a future version, and this will be a hard error"
)?;
let mut workspace_command = command.workspace_helper(ui)?;
let target = workspace_command.resolve_single_rev(&args.revision)?;
let target = workspace_command.resolve_single_rev(ui, &args.revision)?;
let mut tx = workspace_command.start_transaction();
let commit_builder = tx
.repo_mut()

View file

@ -65,7 +65,7 @@ pub(crate) fn cmd_commit(
.ok_or_else(|| user_error("This command requires a working copy"))?;
let commit = workspace_command.repo().store().get_commit(commit_id)?;
let matcher = workspace_command
.parse_file_patterns(&args.paths)?
.parse_file_patterns(ui, &args.paths)?
.to_matcher();
let advanceable_bookmarks = workspace_command.get_advanceable_bookmarks(commit.parent_ids())?;
let diff_selector =
@ -114,7 +114,7 @@ new working-copy commit.
commit_builder.set_description(command.settings().default_description());
}
let temp_commit = commit_builder.write_hidden()?;
let template = description_template(&tx, "", &temp_commit)?;
let template = description_template(ui, &tx, "", &temp_commit)?;
edit_description(tx.base_workspace_helper(), &template, command.settings())?
};
commit_builder.set_description(description);

View file

@ -42,7 +42,7 @@ pub fn cmd_debug_copy_detection(
writeln!(ui.stderr(), "Not a git backend.")?;
return Ok(());
};
let commit = ws.resolve_single_rev(&args.revision)?;
let commit = ws.resolve_single_rev(ui, &args.revision)?;
for parent_id in commit.parent_ids() {
for CopyRecord { target, source, .. } in
block_on_stream(git.get_copy_records(None, parent_id, commit.id())?)

View file

@ -58,11 +58,11 @@ pub fn cmd_debug_tree(
MergedTree::resolved(tree)
} else {
let commit = workspace_command
.resolve_single_rev(args.revision.as_ref().unwrap_or(&RevisionArg::AT))?;
.resolve_single_rev(ui, args.revision.as_ref().unwrap_or(&RevisionArg::AT))?;
commit.tree()?
};
let matcher = workspace_command
.parse_file_patterns(&args.paths)?
.parse_file_patterns(ui, &args.paths)?
.to_matcher();
for (path, value) in tree.entries_matching(matcher.as_ref()) {
let ui_path = workspace_command.format_file_path(&path);

View file

@ -82,7 +82,7 @@ pub(crate) fn cmd_describe(
) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let commits: Vec<_> = workspace_command
.parse_union_revsets(&args.revisions)?
.parse_union_revsets(ui, &args.revisions)?
.evaluate_to_commits()?
.try_collect()?; // in reverse topological order
if commits.is_empty() {
@ -145,7 +145,7 @@ pub(crate) fn cmd_describe(
.try_collect()?;
if let [(_, temp_commit)] = &*temp_commits {
let template = description_template(&tx, "", temp_commit)?;
let template = description_template(ui, &tx, "", temp_commit)?;
let description =
edit_description(tx.base_workspace_helper(), &template, command.settings())?;
@ -156,7 +156,7 @@ pub(crate) fn cmd_describe(
missing,
duplicates,
unexpected,
} = edit_multiple_descriptions(&tx, &temp_commits, command.settings())?;
} = edit_multiple_descriptions(ui, &tx, &temp_commits, command.settings())?;
if !missing.is_empty() {
return Err(user_error(format!(
"The description for the following commits were not found in the edited \

View file

@ -67,10 +67,10 @@ pub(crate) fn cmd_diff(
) -> Result<(), CommandError> {
let workspace_command = command.workspace_helper(ui)?;
let repo = workspace_command.repo();
let fileset_expression = workspace_command.parse_file_patterns(&args.paths)?;
let fileset_expression = workspace_command.parse_file_patterns(ui, &args.paths)?;
let matcher = fileset_expression.to_matcher();
let resolve_revision = |r: &Option<RevisionArg>| {
workspace_command.resolve_single_rev(r.as_ref().unwrap_or(&RevisionArg::AT))
workspace_command.resolve_single_rev(ui, r.as_ref().unwrap_or(&RevisionArg::AT))
};
let from_tree;

View file

@ -76,18 +76,17 @@ pub(crate) fn cmd_diffedit(
let (target_commit, base_commits, diff_description);
if args.from.is_some() || args.to.is_some() {
target_commit =
workspace_command.resolve_single_rev(args.to.as_ref().unwrap_or(&RevisionArg::AT))?;
base_commits =
vec![workspace_command
.resolve_single_rev(args.from.as_ref().unwrap_or(&RevisionArg::AT))?];
target_commit = workspace_command
.resolve_single_rev(ui, args.to.as_ref().unwrap_or(&RevisionArg::AT))?;
base_commits = vec![workspace_command
.resolve_single_rev(ui, args.from.as_ref().unwrap_or(&RevisionArg::AT))?];
diff_description = format!(
"The diff initially shows the commit's changes relative to:\n{}",
workspace_command.format_commit_summary(&base_commits[0])
);
} else {
target_commit = workspace_command
.resolve_single_rev(args.revision.as_ref().unwrap_or(&RevisionArg::AT))?;
.resolve_single_rev(ui, args.revision.as_ref().unwrap_or(&RevisionArg::AT))?;
base_commits = target_commit.parents().try_collect()?;
diff_description = "The diff initially shows the commit's changes.".to_string();
};

View file

@ -46,7 +46,7 @@ pub(crate) fn cmd_duplicate(
) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let to_duplicate: Vec<CommitId> = workspace_command
.parse_union_revsets(&args.revisions)?
.parse_union_revsets(ui, &args.revisions)?
.evaluate_to_commit_ids()?
.collect(); // in reverse topological order
if to_duplicate.is_empty() {

View file

@ -44,7 +44,7 @@ pub(crate) fn cmd_edit(
args: &EditArgs,
) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let new_commit = workspace_command.resolve_single_rev(&args.revision)?;
let new_commit = workspace_command.resolve_single_rev(ui, &args.revision)?;
workspace_command.check_rewritable([new_commit.id()])?;
if workspace_command.get_wc_commit_id() == Some(new_commit.id()) {
writeln!(ui.status(), "Already editing that commit")?;

View file

@ -77,7 +77,7 @@ pub(crate) fn cmd_evolog(
) -> Result<(), CommandError> {
let workspace_command = command.workspace_helper(ui)?;
let start_commit = workspace_command.resolve_single_rev(&args.revision)?;
let start_commit = workspace_command.resolve_single_rev(ui, &args.revision)?;
let diff_renderer = workspace_command.diff_renderer_for_log(&args.diff_format, args.patch)?;
let graph_style = GraphStyle::from_settings(command.settings())?;
@ -93,6 +93,7 @@ pub(crate) fn cmd_evolog(
};
template = workspace_command
.parse_template(
ui,
&language,
&template_string,
CommitTemplateLanguage::wrap_commit,
@ -100,6 +101,7 @@ pub(crate) fn cmd_evolog(
.labeled("log");
node_template = workspace_command
.parse_template(
ui,
&language,
&get_node_template(graph_style, command.settings())?,
CommitTemplateLanguage::wrap_commit_opt,

View file

@ -62,12 +62,12 @@ pub(crate) fn cmd_file_chmod(
};
let mut workspace_command = command.workspace_helper(ui)?;
let commit = workspace_command.resolve_single_rev(&args.revision)?;
let commit = workspace_command.resolve_single_rev(ui, &args.revision)?;
workspace_command.check_rewritable([commit.id()])?;
let tree = commit.tree()?;
// TODO: No need to add special case for empty paths when switching to
// parse_union_filesets(). paths = [] should be "none()" if supported.
let fileset_expression = workspace_command.parse_file_patterns(&args.paths)?;
let fileset_expression = workspace_command.parse_file_patterns(ui, &args.paths)?;
let matcher = fileset_expression.to_matcher();
print_unmatched_explicit_paths(ui, &workspace_command, &fileset_expression, [&tree])?;

View file

@ -39,10 +39,10 @@ pub(crate) fn cmd_file_list(
args: &FileListArgs,
) -> Result<(), CommandError> {
let workspace_command = command.workspace_helper(ui)?;
let commit = workspace_command.resolve_single_rev(&args.revision)?;
let commit = workspace_command.resolve_single_rev(ui, &args.revision)?;
let tree = commit.tree()?;
let matcher = workspace_command
.parse_file_patterns(&args.paths)?
.parse_file_patterns(ui, &args.paths)?
.to_matcher();
ui.request_pager();
for (name, _value) in tree.entries_matching(matcher.as_ref()) {

View file

@ -56,11 +56,11 @@ pub(crate) fn cmd_file_show(
args: &FileShowArgs,
) -> Result<(), CommandError> {
let workspace_command = command.workspace_helper(ui)?;
let commit = workspace_command.resolve_single_rev(&args.revision)?;
let commit = workspace_command.resolve_single_rev(ui, &args.revision)?;
let tree = commit.tree()?;
// TODO: No need to add special case for empty paths when switching to
// parse_union_filesets(). paths = [] should be "none()" if supported.
let fileset_expression = workspace_command.parse_file_patterns(&args.paths)?;
let fileset_expression = workspace_command.parse_file_patterns(ui, &args.paths)?;
// Try fast path for single file entry
if let Some(path) = get_single_path(&fileset_expression) {

View file

@ -45,7 +45,7 @@ pub(crate) fn cmd_file_track(
) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let matcher = workspace_command
.parse_file_patterns(&args.paths)?
.parse_file_patterns(ui, &args.paths)?
.to_matcher();
let mut tx = workspace_command.start_transaction().into_inner();

View file

@ -46,12 +46,12 @@ pub(crate) fn cmd_file_untrack(
let mut workspace_command = command.workspace_helper(ui)?;
let store = workspace_command.repo().store().clone();
let matcher = workspace_command
.parse_file_patterns(&args.paths)?
.parse_file_patterns(ui, &args.paths)?
.to_matcher();
let mut tx = workspace_command.start_transaction().into_inner();
let base_ignores = workspace_command.base_ignores()?;
let auto_tracking_matcher = workspace_command.auto_tracking_matcher()?;
let auto_tracking_matcher = workspace_command.auto_tracking_matcher(ui)?;
let (mut locked_ws, wc_commit) = workspace_command.start_working_copy_mutation()?;
// Create a new tree without the unwanted files
let mut tree_builder = MergedTreeBuilder::new(wc_commit.tree_id().clone());

View file

@ -142,17 +142,16 @@ pub(crate) fn cmd_fix(
let mut workspace_command = command.workspace_helper(ui)?;
let tools_config = get_tools_config(ui, command.settings().config())?;
let root_commits: Vec<CommitId> = if args.source.is_empty() {
workspace_command.parse_revset(&RevisionArg::from(
command.settings().config().get_string("revsets.fix")?,
))?
let revs = command.settings().config().get_string("revsets.fix")?;
workspace_command.parse_revset(ui, &RevisionArg::from(revs))?
} else {
workspace_command.parse_union_revsets(&args.source)?
workspace_command.parse_union_revsets(ui, &args.source)?
}
.evaluate_to_commit_ids()?
.collect();
workspace_command.check_rewritable(root_commits.iter())?;
let matcher = workspace_command
.parse_file_patterns(&args.paths)?
.parse_file_patterns(ui, &args.paths)?
.to_matcher();
let mut tx = workspace_command.start_transaction();

View file

@ -263,7 +263,7 @@ pub fn cmd_git_push(
return Ok(());
}
validate_commits_ready_to_push(&bookmark_updates, &remote, &tx, command, args)?;
validate_commits_ready_to_push(ui, &bookmark_updates, &remote, &tx, command, args)?;
if let Some(mut formatter) = ui.status_formatter() {
writeln!(formatter, "Changes to push to {remote}:")?;
print_commits_ready_to_push(formatter.as_mut(), repo.as_ref(), &bookmark_updates)?;
@ -305,6 +305,7 @@ pub fn cmd_git_push(
/// Validates that the commits that will be pushed are ready (have authorship
/// information, are not conflicted, etc.)
fn validate_commits_ready_to_push(
ui: &Ui,
bookmark_updates: &[(String, BookmarkPushUpdate)],
remote: &str,
tx: &WorkspaceCommandTransaction,
@ -331,7 +332,7 @@ fn validate_commits_ready_to_push(
let config = command.settings().config();
let is_private = if let Ok(revset) = config.get_string("git.private-commits") {
workspace_helper
.parse_revset(&RevisionArg::from(revset))?
.parse_revset(ui, &RevisionArg::from(revset))?
.evaluate()?
.containing_fn()
} else {
@ -528,7 +529,7 @@ fn update_change_bookmarks(
let mut bookmark_names = Vec::new();
let workspace_command = tx.base_workspace_helper();
let all_commits = workspace_command.resolve_some_revsets_default_single(changes)?;
let all_commits = workspace_command.resolve_some_revsets_default_single(ui, changes)?;
for commit in all_commits {
let workspace_command = tx.base_workspace_helper();
@ -539,7 +540,7 @@ fn update_change_bookmarks(
// A local bookmark with the full change ID doesn't exist already, so use the
// short ID if it's not ambiguous (which it shouldn't be most of the time).
if workspace_command
.resolve_single_rev(&RevisionArg::from(short_change_id.clone()))
.resolve_single_rev(ui, &RevisionArg::from(short_change_id.clone()))
.is_ok()
{
// Short change ID is not ambiguous, so update the bookmark name to use it.
@ -621,7 +622,7 @@ fn find_bookmarks_targeted_by_revisions<'a>(
}
}
for rev_arg in revisions {
let mut expression = workspace_command.parse_revset(rev_arg)?;
let mut expression = workspace_command.parse_revset(ui, rev_arg)?;
expression.intersect_with(&RevsetExpression::bookmarks(StringPattern::everything()));
let mut commit_ids = expression.evaluate_to_commit_ids()?.peekable();
if commit_ids.peek().is_none() {

View file

@ -63,7 +63,7 @@ fn cmd_submodule_print(
) -> Result<(), CommandError> {
let workspace_command = command.workspace_helper(ui)?;
let repo = workspace_command.repo();
let commit = workspace_command.resolve_single_rev(&args.revisions)?;
let commit = workspace_command.resolve_single_rev(ui, &args.revisions)?;
let tree = commit.tree()?;
let gitmodules_path = RepoPath::from_internal_string(".gitmodules");
let mut gitmodules_file = match tree.path_value(gitmodules_path)?.into_resolved() {

View file

@ -52,10 +52,11 @@ pub(crate) fn cmd_interdiff(
) -> Result<(), CommandError> {
let workspace_command = command.workspace_helper(ui)?;
let from =
workspace_command.resolve_single_rev(args.from.as_ref().unwrap_or(&RevisionArg::AT))?;
let to = workspace_command.resolve_single_rev(args.to.as_ref().unwrap_or(&RevisionArg::AT))?;
workspace_command.resolve_single_rev(ui, args.from.as_ref().unwrap_or(&RevisionArg::AT))?;
let to =
workspace_command.resolve_single_rev(ui, args.to.as_ref().unwrap_or(&RevisionArg::AT))?;
let matcher = workspace_command
.parse_file_patterns(&args.paths)?
.parse_file_patterns(ui, &args.paths)?
.to_matcher();
let diff_renderer = workspace_command.diff_renderer_for(&args.format)?;
ui.request_pager();

View file

@ -93,14 +93,14 @@ pub(crate) fn cmd_log(
) -> Result<(), CommandError> {
let workspace_command = command.workspace_helper(ui)?;
let fileset_expression = workspace_command.parse_file_patterns(&args.paths)?;
let fileset_expression = workspace_command.parse_file_patterns(ui, &args.paths)?;
let revset_expression = {
// only use default revset if neither revset nor path are specified
let mut expression = if args.revisions.is_empty() && args.paths.is_empty() {
workspace_command
.parse_revset(&RevisionArg::from(command.settings().default_revset()))?
.parse_revset(ui, &RevisionArg::from(command.settings().default_revset()))?
} else if !args.revisions.is_empty() {
workspace_command.parse_union_revsets(&args.revisions)?
workspace_command.parse_union_revsets(ui, &args.revisions)?
} else {
// a path was specified so we use all() and add path filter later
workspace_command.attach_revset_evaluator(RevsetExpression::all())
@ -138,6 +138,7 @@ pub(crate) fn cmd_log(
};
template = workspace_command
.parse_template(
ui,
&language,
&template_string,
CommitTemplateLanguage::wrap_commit,
@ -145,6 +146,7 @@ pub(crate) fn cmd_log(
.labeled("log");
node_template = workspace_command
.parse_template(
ui,
&language,
&get_node_template(graph_style, command.settings())?,
CommitTemplateLanguage::wrap_commit_opt,
@ -281,7 +283,7 @@ pub(crate) fn cmd_log(
)?;
} else if revset.is_empty()
&& workspace_command
.parse_revset(&RevisionArg::from(only_path.to_owned()))
.parse_revset(ui, &RevisionArg::from(only_path.to_owned()))
.is_ok()
{
writeln!(

View file

@ -75,14 +75,14 @@ pub(crate) fn cmd_move(
)?;
let mut workspace_command = command.workspace_helper(ui)?;
let source =
workspace_command.resolve_single_rev(args.from.as_ref().unwrap_or(&RevisionArg::AT))?;
workspace_command.resolve_single_rev(ui, args.from.as_ref().unwrap_or(&RevisionArg::AT))?;
let destination =
workspace_command.resolve_single_rev(args.to.as_ref().unwrap_or(&RevisionArg::AT))?;
workspace_command.resolve_single_rev(ui, args.to.as_ref().unwrap_or(&RevisionArg::AT))?;
if source.id() == destination.id() {
return Err(user_error("Source and destination cannot be the same."));
}
let matcher = workspace_command
.parse_file_patterns(&args.paths)?
.parse_file_patterns(ui, &args.paths)?
.to_matcher();
let diff_selector =
workspace_command.diff_selector(ui, args.tool.as_deref(), args.interactive)?;

View file

@ -97,12 +97,12 @@ pub(crate) fn cmd_new(
if !args.insert_before.is_empty() && !args.insert_after.is_empty() {
parent_commits = workspace_command
.resolve_some_revsets_default_single(&args.insert_after)?
.resolve_some_revsets_default_single(ui, &args.insert_after)?
.into_iter()
.collect_vec();
parent_commit_ids = parent_commits.iter().ids().cloned().collect();
children_commits = workspace_command
.resolve_some_revsets_default_single(&args.insert_before)?
.resolve_some_revsets_default_single(ui, &args.insert_before)?
.into_iter()
.collect_vec();
let children_commit_ids = children_commits.iter().ids().cloned().collect();
@ -119,7 +119,7 @@ pub(crate) fn cmd_new(
// The parents of the new commit will be the parents of the target commits
// which are not descendants of other target commits.
children_commits = workspace_command
.resolve_some_revsets_default_single(&args.insert_before)?
.resolve_some_revsets_default_single(ui, &args.insert_before)?
.into_iter()
.collect_vec();
let children_commit_ids = children_commits.iter().ids().cloned().collect();
@ -144,7 +144,7 @@ pub(crate) fn cmd_new(
.try_collect()?;
} else if !args.insert_after.is_empty() {
parent_commits = workspace_command
.resolve_some_revsets_default_single(&args.insert_after)?
.resolve_some_revsets_default_single(ui, &args.insert_after)?
.into_iter()
.collect_vec();
parent_commit_ids = parent_commits.iter().ids().cloned().collect();
@ -162,7 +162,7 @@ pub(crate) fn cmd_new(
.try_collect()?;
} else {
parent_commits = workspace_command
.resolve_some_revsets_default_single(&args.revisions)?
.resolve_some_revsets_default_single(ui, &args.revisions)?
.into_iter()
.collect_vec();
parent_commit_ids = parent_commits.iter().ids().cloned().collect();

View file

@ -119,7 +119,7 @@ pub fn cmd_op_diff(
.settings()
.config()
.get_string("templates.commit_summary")?;
workspace_env.parse_template(&language, &text, CommitTemplateLanguage::wrap_commit)?
workspace_env.parse_template(ui, &language, &text, CommitTemplateLanguage::wrap_commit)?
};
let op_summary_template = workspace_command.operation_summary_template();

View file

@ -124,10 +124,16 @@ fn do_op_log(
None => settings.config().get_string("templates.op_log")?,
};
template = workspace_env
.parse_template(&language, &text, OperationTemplateLanguage::wrap_operation)?
.parse_template(
ui,
&language,
&text,
OperationTemplateLanguage::wrap_operation,
)?
.labeled("op_log");
op_node_template = workspace_env
.parse_template(
ui,
&language,
&get_node_template(graph_style, settings)?,
OperationTemplateLanguage::wrap_operation,
@ -152,6 +158,7 @@ fn do_op_log(
let language =
workspace_env.commit_template_language(repo.as_ref(), &id_prefix_context);
workspace_env.parse_template(
ui,
&language,
&template_text,
CommitTemplateLanguage::wrap_commit,

View file

@ -66,7 +66,7 @@ pub fn cmd_op_show(
.settings()
.config()
.get_string("templates.commit_summary")?;
workspace_env.parse_template(&language, &text, CommitTemplateLanguage::wrap_commit)?
workspace_env.parse_template(ui, &language, &text, CommitTemplateLanguage::wrap_commit)?
};
let graph_style = GraphStyle::from_settings(command.settings())?;
@ -81,7 +81,7 @@ pub fn cmd_op_show(
let template = {
let text = command.settings().config().get_string("templates.op_log")?;
workspace_command
.parse_operation_template(&text)?
.parse_operation_template(ui, &text)?
.labeled("op_log")
};

View file

@ -68,7 +68,7 @@ pub(crate) fn cmd_parallelize(
// The target commits are the commits being parallelized. They are ordered
// here with children before parents.
let target_commits: Vec<Commit> = workspace_command
.parse_union_revsets(&args.revisions)?
.parse_union_revsets(ui, &args.revisions)?
.evaluate_to_commits()?
.try_collect()?;
workspace_command.check_rewritable(target_commits.iter().ids())?;

View file

@ -246,14 +246,14 @@ pub(crate) fn cmd_rebase(
"clap should forbid `-r --skip-empty`"
);
let target_commits: Vec<_> = workspace_command
.parse_union_revsets(&args.revisions)?
.parse_union_revsets(ui, &args.revisions)?
.evaluate_to_commits()?
.try_collect()?; // in reverse topological order
if !args.insert_after.is_empty() && !args.insert_before.is_empty() {
let after_commits =
workspace_command.resolve_some_revsets_default_single(&args.insert_after)?;
workspace_command.resolve_some_revsets_default_single(ui, &args.insert_after)?;
let before_commits =
workspace_command.resolve_some_revsets_default_single(&args.insert_before)?;
workspace_command.resolve_some_revsets_default_single(ui, &args.insert_before)?;
rebase_revisions_after_before(
ui,
command.settings(),
@ -264,7 +264,7 @@ pub(crate) fn cmd_rebase(
)?;
} else if !args.insert_after.is_empty() {
let after_commits =
workspace_command.resolve_some_revsets_default_single(&args.insert_after)?;
workspace_command.resolve_some_revsets_default_single(ui, &args.insert_after)?;
rebase_revisions_after(
ui,
command.settings(),
@ -274,7 +274,7 @@ pub(crate) fn cmd_rebase(
)?;
} else if !args.insert_before.is_empty() {
let before_commits =
workspace_command.resolve_some_revsets_default_single(&args.insert_before)?;
workspace_command.resolve_some_revsets_default_single(ui, &args.insert_before)?;
rebase_revisions_before(
ui,
command.settings(),
@ -284,7 +284,7 @@ pub(crate) fn cmd_rebase(
)?;
} else {
let new_parents = workspace_command
.resolve_some_revsets_default_single(&args.destination)?
.resolve_some_revsets_default_single(ui, &args.destination)?
.into_iter()
.collect_vec();
rebase_revisions(
@ -297,10 +297,11 @@ pub(crate) fn cmd_rebase(
}
} else if !args.source.is_empty() {
let new_parents = workspace_command
.resolve_some_revsets_default_single(&args.destination)?
.resolve_some_revsets_default_single(ui, &args.destination)?
.into_iter()
.collect_vec();
let source_commits = workspace_command.resolve_some_revsets_default_single(&args.source)?;
let source_commits =
workspace_command.resolve_some_revsets_default_single(ui, &args.source)?;
rebase_descendants_transaction(
ui,
command.settings(),
@ -311,13 +312,13 @@ pub(crate) fn cmd_rebase(
)?;
} else {
let new_parents = workspace_command
.resolve_some_revsets_default_single(&args.destination)?
.resolve_some_revsets_default_single(ui, &args.destination)?
.into_iter()
.collect_vec();
let branch_commits = if args.branch.is_empty() {
IndexSet::from([workspace_command.resolve_single_rev(&RevisionArg::AT)?])
IndexSet::from([workspace_command.resolve_single_rev(ui, &RevisionArg::AT)?])
} else {
workspace_command.resolve_some_revsets_default_single(&args.branch)?
workspace_command.resolve_some_revsets_default_single(ui, &args.branch)?
};
rebase_branch(
ui,

View file

@ -68,9 +68,9 @@ pub(crate) fn cmd_resolve(
) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let matcher = workspace_command
.parse_file_patterns(&args.paths)?
.parse_file_patterns(ui, &args.paths)?
.to_matcher();
let commit = workspace_command.resolve_single_rev(&args.revision)?;
let commit = workspace_command.resolve_single_rev(ui, &args.revision)?;
let tree = commit.tree()?;
let conflicts = tree
.conflicts()

View file

@ -88,20 +88,20 @@ pub(crate) fn cmd_restore(
));
}
if args.from.is_some() || args.to.is_some() {
to_commit =
workspace_command.resolve_single_rev(args.to.as_ref().unwrap_or(&RevisionArg::AT))?;
to_commit = workspace_command
.resolve_single_rev(ui, args.to.as_ref().unwrap_or(&RevisionArg::AT))?;
from_tree = workspace_command
.resolve_single_rev(args.from.as_ref().unwrap_or(&RevisionArg::AT))?
.resolve_single_rev(ui, args.from.as_ref().unwrap_or(&RevisionArg::AT))?
.tree()?;
} else {
to_commit = workspace_command
.resolve_single_rev(args.changes_in.as_ref().unwrap_or(&RevisionArg::AT))?;
.resolve_single_rev(ui, args.changes_in.as_ref().unwrap_or(&RevisionArg::AT))?;
from_tree = to_commit.parent_tree(workspace_command.repo().as_ref())?;
}
workspace_command.check_rewritable([to_commit.id()])?;
let matcher = workspace_command
.parse_file_patterns(&args.paths)?
.parse_file_patterns(ui, &args.paths)?
.to_matcher();
let to_tree = to_commit.tree()?;
let new_tree_id = restore_tree(&from_tree, &to_tree, matcher.as_ref())?;

View file

@ -53,7 +53,7 @@ pub struct RunArgs {
pub fn cmd_run(ui: &mut Ui, command: &CommandHelper, args: &RunArgs) -> Result<(), CommandError> {
let workspace_command = command.workspace_helper(ui)?;
let _resolved_commits: Vec<_> = workspace_command
.parse_union_revsets(&args.revisions)?
.parse_union_revsets(ui, &args.revisions)?
.evaluate_to_commits()?
.try_collect()?;
// Jobs are resolved in this order:

View file

@ -46,12 +46,12 @@ pub(crate) fn cmd_show(
args: &ShowArgs,
) -> Result<(), CommandError> {
let workspace_command = command.workspace_helper(ui)?;
let commit = workspace_command.resolve_single_rev(&args.revision)?;
let commit = workspace_command.resolve_single_rev(ui, &args.revision)?;
let template_string = match &args.template {
Some(value) => value.to_string(),
None => command.settings().config().get_string("templates.show")?,
};
let template = workspace_command.parse_commit_template(&template_string)?;
let template = workspace_command.parse_commit_template(ui, &template_string)?;
let diff_renderer = workspace_command.diff_renderer_for(&args.format)?;
ui.request_pager();
let mut formatter = ui.stdout_formatter();

View file

@ -71,7 +71,7 @@ pub(crate) fn cmd_split(
args: &SplitArgs,
) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let commit = workspace_command.resolve_single_rev(&args.revision)?;
let commit = workspace_command.resolve_single_rev(ui, &args.revision)?;
if commit.is_empty(workspace_command.repo().as_ref())? {
return Err(user_error_with_hint(
format!("Refusing to split empty commit {}.", commit.id().hex()),
@ -81,7 +81,7 @@ pub(crate) fn cmd_split(
workspace_command.check_rewritable([commit.id()])?;
let matcher = workspace_command
.parse_file_patterns(&args.paths)?
.parse_file_patterns(ui, &args.paths)?
.to_matcher();
let diff_selector = workspace_command.diff_selector(
ui,
@ -136,6 +136,7 @@ the operation will be aborted.
}
let temp_commit = commit_builder.write_hidden()?;
let template = description_template(
ui,
&tx,
"Enter a description for the first commit.",
&temp_commit,
@ -179,6 +180,7 @@ the operation will be aborted.
} else {
let temp_commit = commit_builder.write_hidden()?;
let template = description_template(
ui,
&tx,
"Enter a description for the second commit.",
&temp_commit,

View file

@ -98,14 +98,14 @@ pub(crate) fn cmd_squash(
let destination;
if !args.from.is_empty() || args.into.is_some() {
sources = if args.from.is_empty() {
workspace_command.parse_revset(&RevisionArg::AT)?
workspace_command.parse_revset(ui, &RevisionArg::AT)?
} else {
workspace_command.parse_union_revsets(&args.from)?
workspace_command.parse_union_revsets(ui, &args.from)?
}
.evaluate_to_commits()?
.try_collect()?;
destination =
workspace_command.resolve_single_rev(args.into.as_ref().unwrap_or(&RevisionArg::AT))?;
destination = workspace_command
.resolve_single_rev(ui, args.into.as_ref().unwrap_or(&RevisionArg::AT))?;
if sources.iter().any(|source| source.id() == destination.id()) {
return Err(user_error("Source and destination cannot be the same"));
}
@ -115,7 +115,7 @@ pub(crate) fn cmd_squash(
sources.reverse();
} else {
let source = workspace_command
.resolve_single_rev(args.revision.as_ref().unwrap_or(&RevisionArg::AT))?;
.resolve_single_rev(ui, args.revision.as_ref().unwrap_or(&RevisionArg::AT))?;
let mut parents: Vec<_> = source.parents().try_collect()?;
if parents.len() != 1 {
return Err(user_error_with_hint(
@ -128,7 +128,7 @@ pub(crate) fn cmd_squash(
}
let matcher = workspace_command
.parse_file_patterns(&args.paths)?
.parse_file_patterns(ui, &args.paths)?
.to_matcher();
let diff_selector =
workspace_command.diff_selector(ui, args.tool.as_deref(), args.interactive)?;
@ -252,7 +252,7 @@ from the source will be moved into the destination.
if no_rev_arg
&& tx
.base_workspace_helper()
.parse_revset(&RevisionArg::from(only_path.to_owned()))
.parse_revset(ui, &RevisionArg::from(only_path.to_owned()))
.is_ok()
{
writeln!(

View file

@ -54,7 +54,7 @@ pub(crate) fn cmd_status(
.map(|id| repo.store().get_commit(id))
.transpose()?;
let matcher = workspace_command
.parse_file_patterns(&args.paths)?
.parse_file_patterns(ui, &args.paths)?
.to_matcher();
ui.request_pager();
let mut formatter = ui.stdout_formatter();

View file

@ -72,7 +72,7 @@ fn cmd_tag_list(
None => command.settings().config().get("templates.tag_list")?,
};
workspace_command
.parse_template(&language, &text, CommitTemplateLanguage::wrap_ref_name)?
.parse_template(ui, &language, &text, CommitTemplateLanguage::wrap_ref_name)?
.labeled("tag_list")
};

View file

@ -57,7 +57,7 @@ pub(crate) fn cmd_unsquash(
args: &UnsquashArgs,
) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let commit = workspace_command.resolve_single_rev(&args.revision)?;
let commit = workspace_command.resolve_single_rev(ui, &args.revision)?;
workspace_command.check_rewritable([commit.id()])?;
if commit.parent_ids().len() > 1 {
return Err(user_error("Cannot unsquash merge commits"));

View file

@ -177,7 +177,7 @@ pub fn cmd_workspace_add(
}
} else {
old_workspace_command
.resolve_some_revsets_default_single(&args.revision)?
.resolve_some_revsets_default_single(ui, &args.revision)?
.into_iter()
.collect_vec()
};

View file

@ -17,6 +17,7 @@ use crate::cli_util::WorkspaceCommandTransaction;
use crate::command_error::CommandError;
use crate::formatter::PlainTextFormatter;
use crate::text_util;
use crate::ui::Ui;
/// Cleanup a description by normalizing line endings, and removing leading and
/// trailing blank lines.
@ -57,6 +58,7 @@ JJ: Lines starting with "JJ: " (like this one) will be removed.
/// Edits the descriptions of the given commits in a single editor session.
pub fn edit_multiple_descriptions(
ui: &Ui,
tx: &WorkspaceCommandTransaction,
commits: &[(&CommitId, Commit)],
settings: &UserSettings,
@ -77,7 +79,7 @@ pub fn edit_multiple_descriptions(
bulk_message.push_str(&commit_hash);
bulk_message.push_str(" -------\n");
commits_map.insert(commit_hash, *commit_id);
let template = description_template(tx, "", temp_commit)?;
let template = description_template(ui, tx, "", temp_commit)?;
bulk_message.push_str(&template);
bulk_message.push('\n');
}
@ -225,6 +227,7 @@ pub fn join_message_paragraphs(paragraphs: &[String]) -> String {
/// Renders commit description template, which will be edited by user.
pub fn description_template(
ui: &Ui,
tx: &WorkspaceCommandTransaction,
intro: &str,
commit: &Commit,
@ -238,7 +241,7 @@ pub fn description_template(
// Named as "draft" because the output can contain "JJ: " comment lines.
let template_key = "templates.draft_commit_description";
let template_text = tx.settings().config().get_string(template_key)?;
let template = tx.parse_commit_template(&template_text)?;
let template = tx.parse_commit_template(ui, &template_text)?;
let mut output = Vec::new();
if !intro.is_empty() {