cli: move ui.settings() to CommandHelper, disown UserSettings from Ui

Still UserSettings is cloned to WorkspaceCommandHelper, but I think this is
slightly better since CommandHelper and WorkspaceCommandHelper are scoped
based on call stack. Perhaps, UserSettings can be shared by Arc or immutable
reference.
This commit is contained in:
Yuya Nishihara 2023-01-04 17:57:36 +09:00
parent 71102a7d4a
commit 42a044b7c7
5 changed files with 121 additions and 113 deletions

View file

@ -44,7 +44,7 @@ fn create_store_factories() -> StoreFactories {
} }
fn run_custom_command( fn run_custom_command(
ui: &mut Ui, _ui: &mut Ui,
command_helper: &CommandHelper, command_helper: &CommandHelper,
command: CustomCommands, command: CustomCommands,
) -> Result<(), CommandError> { ) -> Result<(), CommandError> {
@ -52,7 +52,7 @@ fn run_custom_command(
CustomCommands::InitJit => { CustomCommands::InitJit => {
let wc_path = command_helper.cwd(); let wc_path = command_helper.cwd();
// Initialize a workspace with the custom backend // Initialize a workspace with the custom backend
Workspace::init_with_backend(ui.settings(), wc_path, |store_path| { Workspace::init_with_backend(command_helper.settings(), wc_path, |store_path| {
Box::new(JitBackend::init(store_path)) Box::new(JitBackend::init(store_path))
})?; })?;
Ok(()) Ok(())

View file

@ -40,7 +40,7 @@ fn run_custom_command(
let mut tx = workspace_command.start_transaction("Frobnicate"); let mut tx = workspace_command.start_transaction("Frobnicate");
let new_commit = tx let new_commit = tx
.mut_repo() .mut_repo()
.rewrite_commit(ui.settings(), &commit) .rewrite_commit(command_helper.settings(), &commit)
.set_description("Frobnicated!") .set_description("Frobnicated!")
.write()?; .write()?;
workspace_command.finish_transaction(ui, tx)?; workspace_command.finish_transaction(ui, tx)?;

View file

@ -263,6 +263,7 @@ pub struct CommandHelper {
cwd: PathBuf, cwd: PathBuf,
string_args: Vec<String>, string_args: Vec<String>,
global_args: GlobalArgs, global_args: GlobalArgs,
settings: UserSettings,
store_factories: StoreFactories, store_factories: StoreFactories,
} }
@ -272,6 +273,7 @@ impl CommandHelper {
cwd: PathBuf, cwd: PathBuf,
string_args: Vec<String>, string_args: Vec<String>,
global_args: GlobalArgs, global_args: GlobalArgs,
settings: UserSettings,
store_factories: StoreFactories, store_factories: StoreFactories,
) -> Self { ) -> Self {
Self { Self {
@ -279,6 +281,7 @@ impl CommandHelper {
cwd, cwd,
string_args, string_args,
global_args, global_args,
settings,
store_factories, store_factories,
} }
} }
@ -299,17 +302,21 @@ impl CommandHelper {
&self.global_args &self.global_args
} }
pub fn settings(&self) -> &UserSettings {
&self.settings
}
pub fn workspace_helper(&self, ui: &mut Ui) -> Result<WorkspaceCommandHelper, CommandError> { pub fn workspace_helper(&self, ui: &mut Ui) -> Result<WorkspaceCommandHelper, CommandError> {
let workspace = self.load_workspace(ui)?; let workspace = self.load_workspace()?;
let mut workspace_command = self.resolve_operation(ui, workspace)?; let mut workspace_command = self.resolve_operation(ui, workspace)?;
workspace_command.snapshot(ui)?; workspace_command.snapshot(ui)?;
Ok(workspace_command) Ok(workspace_command)
} }
pub fn load_workspace(&self, ui: &Ui) -> Result<Workspace, CommandError> { pub fn load_workspace(&self) -> Result<Workspace, CommandError> {
let wc_path_str = self.global_args.repository.as_deref().unwrap_or("."); let wc_path_str = self.global_args.repository.as_deref().unwrap_or(".");
let wc_path = self.cwd.join(wc_path_str); let wc_path = self.cwd.join(wc_path_str);
Workspace::load(ui.settings(), &wc_path, &self.store_factories).map_err(|err| match err { Workspace::load(&self.settings, &wc_path, &self.store_factories).map_err(|err| match err {
WorkspaceLoadError::NoWorkspaceHere(wc_path) => { WorkspaceLoadError::NoWorkspaceHere(wc_path) => {
let message = format!("There is no jj repo in \"{wc_path_str}\""); let message = format!("There is no jj repo in \"{wc_path_str}\"");
let git_dir = wc_path.join(".git"); let git_dir = wc_path.join(".git");
@ -363,7 +370,7 @@ jj init --git-repo=.",
let mut tx = workspace_command.start_transaction("resolve concurrent operations"); let mut tx = workspace_command.start_transaction("resolve concurrent operations");
for other_op_head in op_heads.into_iter().skip(1) { for other_op_head in op_heads.into_iter().skip(1) {
tx.merge_operation(other_op_head); tx.merge_operation(other_op_head);
let num_rebased = tx.mut_repo().rebase_descendants(ui.settings())?; let num_rebased = tx.mut_repo().rebase_descendants(&self.settings)?;
if num_rebased > 0 { if num_rebased > 0 {
writeln!( writeln!(
ui, ui,
@ -393,6 +400,7 @@ jj init --git-repo=.",
self.cwd.clone(), self.cwd.clone(),
self.string_args.clone(), self.string_args.clone(),
&self.global_args, &self.global_args,
self.settings.clone(),
repo, repo,
) )
} }
@ -419,9 +427,9 @@ impl WorkspaceCommandHelper {
cwd: PathBuf, cwd: PathBuf,
string_args: Vec<String>, string_args: Vec<String>,
global_args: &GlobalArgs, global_args: &GlobalArgs,
settings: UserSettings,
repo: Arc<ReadonlyRepo>, repo: Arc<ReadonlyRepo>,
) -> Result<Self, CommandError> { ) -> Result<Self, CommandError> {
let settings = ui.settings().clone();
let revset_aliases_map = load_revset_aliases(ui, &settings)?; let revset_aliases_map = load_revset_aliases(ui, &settings)?;
let loaded_at_head = &global_args.at_operation == "@"; let loaded_at_head = &global_args.at_operation == "@";
let may_update_working_copy = loaded_at_head && !global_args.no_commit_working_copy; let may_update_working_copy = loaded_at_head && !global_args.no_commit_working_copy;
@ -509,7 +517,7 @@ impl WorkspaceCommandHelper {
self.repo = tx.commit(); self.repo = tx.commit();
locked_working_copy.finish(self.repo.op_id().clone()); locked_working_copy.finish(self.repo.op_id().clone());
} else { } else {
let num_rebased = tx.mut_repo().rebase_descendants(ui.settings())?; let num_rebased = tx.mut_repo().rebase_descendants(&self.settings)?;
if num_rebased > 0 { if num_rebased > 0 {
writeln!( writeln!(
ui, ui,
@ -938,7 +946,7 @@ impl WorkspaceCommandHelper {
writeln!(ui, "Nothing changed.")?; writeln!(ui, "Nothing changed.")?;
return Ok(()); return Ok(());
} }
let num_rebased = mut_repo.rebase_descendants(ui.settings())?; let num_rebased = mut_repo.rebase_descendants(&self.settings)?;
if num_rebased > 0 { if num_rebased > 0 {
writeln!(ui, "Rebased {num_rebased} descendant commits")?; writeln!(ui, "Rebased {num_rebased} descendant commits")?;
} }
@ -968,7 +976,7 @@ impl WorkspaceCommandHelper {
print_checkout_stats(ui, stats)?; print_checkout_stats(ui, stats)?;
} }
} }
let settings = ui.settings(); let settings = &self.settings;
if settings.user_name() == UserSettings::user_name_placeholder() if settings.user_name() == UserSettings::user_name_placeholder()
|| settings.user_email() == UserSettings::user_email_placeholder() || settings.user_email() == UserSettings::user_email_placeholder()
{ {
@ -1615,7 +1623,7 @@ fn handle_early_args(
} }
if !args.config_toml.is_empty() { if !args.config_toml.is_empty() {
settings.incorporate_toml_strings(&args.config_toml)?; settings.incorporate_toml_strings(&args.config_toml)?;
ui.reset(settings.clone()); // TODO: disown UserSettings from Ui ui.reset(settings);
} }
Ok(()) Ok(())
} }
@ -1776,7 +1784,7 @@ impl CliRunner {
pub fn run(self, ui: &mut Ui) -> Result<(), CommandError> { pub fn run(self, ui: &mut Ui) -> Result<(), CommandError> {
let cwd = env::current_dir().unwrap(); // TODO: maybe map_err to CommandError? let cwd = env::current_dir().unwrap(); // TODO: maybe map_err to CommandError?
let mut settings = crate::config::read_config()?; let mut settings = crate::config::read_config()?;
ui.reset(settings.clone()); // TODO: disown UserSettings from Ui ui.reset(&settings);
let string_args = expand_args(&self.app, std::env::args_os(), &settings)?; let string_args = expand_args(&self.app, std::env::args_os(), &settings)?;
let (matches, args) = parse_args( let (matches, args) = parse_args(
ui, ui,
@ -1791,6 +1799,7 @@ impl CliRunner {
cwd, cwd,
string_args, string_args,
args.global_args, args.global_args,
settings,
self.store_factories.unwrap_or_default(), self.store_factories.unwrap_or_default(),
); );
(self.dispatch_fn)(ui, &command_helper, &matches) (self.dispatch_fn)(ui, &command_helper, &matches)

View file

@ -1157,7 +1157,7 @@ fn cmd_init(ui: &mut Ui, command: &CommandHelper, args: &InitArgs) -> Result<(),
.join(relative_path); .join(relative_path);
} }
let (workspace, repo) = let (workspace, repo) =
Workspace::init_external_git(ui.settings(), &wc_path, &git_store_path)?; Workspace::init_external_git(command.settings(), &wc_path, &git_store_path)?;
let git_repo = repo.store().git_repo().unwrap(); let git_repo = repo.store().git_repo().unwrap();
let mut workspace_command = command.for_loaded_repo(ui, workspace, repo)?; let mut workspace_command = command.for_loaded_repo(ui, workspace, repo)?;
workspace_command.snapshot(ui)?; workspace_command.snapshot(ui)?;
@ -1170,7 +1170,7 @@ fn cmd_init(ui: &mut Ui, command: &CommandHelper, args: &InitArgs) -> Result<(),
let git_head_commit = tx.mut_repo().store().get_commit(&git_head_id)?; let git_head_commit = tx.mut_repo().store().get_commit(&git_head_id)?;
tx.mut_repo().check_out( tx.mut_repo().check_out(
workspace_command.workspace_id(), workspace_command.workspace_id(),
ui.settings(), command.settings(),
&git_head_commit, &git_head_commit,
)?; )?;
} }
@ -1179,16 +1179,16 @@ fn cmd_init(ui: &mut Ui, command: &CommandHelper, args: &InitArgs) -> Result<(),
} }
} }
} else if args.git { } else if args.git {
Workspace::init_internal_git(ui.settings(), &wc_path)?; Workspace::init_internal_git(command.settings(), &wc_path)?;
} else { } else {
if !ui.settings().allow_native_backend() { if !command.settings().allow_native_backend() {
return Err(user_error_with_hint( return Err(user_error_with_hint(
"The native backend is disallowed by default.", "The native backend is disallowed by default.",
"Did you mean to pass `--git`? "Did you mean to pass `--git`?
Set `ui.allow-init-native` to allow initializing a repo with the native backend.", Set `ui.allow-init-native` to allow initializing a repo with the native backend.",
)); ));
} }
Workspace::init_local(ui.settings(), &wc_path)?; Workspace::init_local(command.settings(), &wc_path)?;
}; };
let cwd = command.cwd().canonicalize().unwrap(); let cwd = command.cwd().canonicalize().unwrap();
let relative_wc_path = file_util::relative_path(&cwd, &wc_path); let relative_wc_path = file_util::relative_path(&cwd, &wc_path);
@ -1206,15 +1206,15 @@ Set `ui.allow-init-native` to allow initializing a repo with the native backend.
fn cmd_config( fn cmd_config(
ui: &mut Ui, ui: &mut Ui,
_command: &CommandHelper, command: &CommandHelper,
subcommand: &ConfigSubcommand, subcommand: &ConfigSubcommand,
) -> Result<(), CommandError> { ) -> Result<(), CommandError> {
ui.request_pager(); ui.request_pager();
match subcommand { match subcommand {
ConfigSubcommand::List { name } => { ConfigSubcommand::List { name } => {
let raw_values = match name { let raw_values = match name {
Some(name) => { Some(name) => command
ui.settings() .settings()
.config() .config()
.get::<config::Value>(name) .get::<config::Value>(name)
.map_err(|e| match e { .map_err(|e| match e {
@ -1222,9 +1222,8 @@ fn cmd_config(
user_error("key not found in config") user_error("key not found in config")
} }
_ => e.into(), _ => e.into(),
})? })?,
} None => command.settings().config().collect()?.into(),
None => ui.settings().config().collect()?.into(),
}; };
write_config_entry(ui, name.as_deref().unwrap_or(""), raw_values)?; write_config_entry(ui, name.as_deref().unwrap_or(""), raw_values)?;
} }
@ -1246,7 +1245,7 @@ fn cmd_checkout(
let commit_builder = tx let commit_builder = tx
.mut_repo() .mut_repo()
.new_commit( .new_commit(
ui.settings(), command.settings(),
vec![target.id().clone()], vec![target.id().clone()],
target.tree_id().clone(), target.tree_id().clone(),
) )
@ -1309,10 +1308,10 @@ Make sure they're ignored, then try again.",
} }
} }
tx.mut_repo() tx.mut_repo()
.rewrite_commit(ui.settings(), &wc_commit) .rewrite_commit(command.settings(), &wc_commit)
.set_tree(new_tree_id) .set_tree(new_tree_id)
.write()?; .write()?;
let num_rebased = tx.mut_repo().rebase_descendants(ui.settings())?; let num_rebased = tx.mut_repo().rebase_descendants(command.settings())?;
if num_rebased > 0 { if num_rebased > 0 {
writeln!(ui, "Rebased {num_rebased} descendant commits")?; writeln!(ui, "Rebased {num_rebased} descendant commits")?;
} }
@ -1384,7 +1383,7 @@ fn cmd_diff(ui: &mut Ui, command: &CommandHelper, args: &DiffArgs) -> Result<(),
&from_tree, &from_tree,
&to_tree, &to_tree,
matcher.as_ref(), matcher.as_ref(),
&diff_util::diff_formats_for(ui.settings(), &args.format), &diff_util::diff_formats_for(command.settings(), &args.format),
)?; )?;
Ok(()) Ok(())
} }
@ -1395,7 +1394,7 @@ fn cmd_show(ui: &mut Ui, command: &CommandHelper, args: &ShowArgs) -> Result<(),
// TODO: Add branches, tags, etc // TODO: Add branches, tags, etc
// TODO: Indent the description like Git does // TODO: Indent the description like Git does
let (author_timestamp_template, committer_timestamp_template) = let (author_timestamp_template, committer_timestamp_template) =
if ui.settings().relative_timestamps() { if command.settings().relative_timestamps() {
("author.timestamp().ago()", "committer.timestamp().ago()") ("author.timestamp().ago()", "committer.timestamp().ago()")
} else { } else {
("author.timestamp()", "committer.timestamp()") ("author.timestamp()", "committer.timestamp()")
@ -1424,7 +1423,7 @@ fn cmd_show(ui: &mut Ui, command: &CommandHelper, args: &ShowArgs) -> Result<(),
&workspace_command, &workspace_command,
&commit, &commit,
&EverythingMatcher, &EverythingMatcher,
&diff_util::diff_formats_for(ui.settings(), &args.format), &diff_util::diff_formats_for(command.settings(), &args.format),
)?; )?;
Ok(()) Ok(())
} }
@ -1454,7 +1453,7 @@ fn cmd_status(
repo.as_repo_ref(), repo.as_repo_ref(),
&workspace_id, &workspace_id,
&parent, &parent,
ui.settings(), command.settings(),
)?; )?;
formatter.write_str("\n")?; formatter.write_str("\n")?;
} }
@ -1464,7 +1463,7 @@ fn cmd_status(
repo.as_repo_ref(), repo.as_repo_ref(),
&workspace_id, &workspace_id,
wc_commit, wc_commit,
ui.settings(), command.settings(),
)?; )?;
formatter.write_str("\n")?; formatter.write_str("\n")?;
} else { } else {
@ -1579,7 +1578,7 @@ fn log_template(settings: &UserSettings) -> String {
fn cmd_log(ui: &mut Ui, command: &CommandHelper, args: &LogArgs) -> Result<(), CommandError> { fn cmd_log(ui: &mut Ui, command: &CommandHelper, args: &LogArgs) -> Result<(), CommandError> {
let workspace_command = command.workspace_helper(ui)?; let workspace_command = command.workspace_helper(ui)?;
let default_revset = ui.settings().default_revset(); let default_revset = command.settings().default_revset();
let revset_expression = let revset_expression =
workspace_command.parse_revset(args.revisions.as_deref().unwrap_or(&default_revset))?; workspace_command.parse_revset(args.revisions.as_deref().unwrap_or(&default_revset))?;
let repo = workspace_command.repo(); let repo = workspace_command.repo();
@ -1595,11 +1594,11 @@ fn cmd_log(ui: &mut Ui, command: &CommandHelper, args: &LogArgs) -> Result<(), C
let store = repo.store(); let store = repo.store();
let diff_formats = let diff_formats =
diff_util::diff_formats_for_log(ui.settings(), &args.diff_format, args.patch); diff_util::diff_formats_for_log(command.settings(), &args.diff_format, args.patch);
let template_string = match &args.template { let template_string = match &args.template {
Some(value) => value.to_string(), Some(value) => value.to_string(),
None => log_template(ui.settings()), None => log_template(command.settings()),
}; };
let template = crate::template_parser::parse_commit_template( let template = crate::template_parser::parse_commit_template(
repo.as_repo_ref(), repo.as_repo_ref(),
@ -1736,11 +1735,11 @@ fn cmd_obslog(ui: &mut Ui, command: &CommandHelper, args: &ObslogArgs) -> Result
.get_wc_commit_id(&workspace_id); .get_wc_commit_id(&workspace_id);
let diff_formats = let diff_formats =
diff_util::diff_formats_for_log(ui.settings(), &args.diff_format, args.patch); diff_util::diff_formats_for_log(command.settings(), &args.diff_format, args.patch);
let template_string = match &args.template { let template_string = match &args.template {
Some(value) => value.to_string(), Some(value) => value.to_string(),
None => log_template(ui.settings()), None => log_template(command.settings()),
}; };
let template = crate::template_parser::parse_commit_template( let template = crate::template_parser::parse_commit_template(
workspace_command.repo().as_repo_ref(), workspace_command.repo().as_repo_ref(),
@ -1841,7 +1840,7 @@ fn cmd_interdiff(
&from_tree, &from_tree,
&to.tree(), &to.tree(),
matcher.as_ref(), matcher.as_ref(),
&diff_util::diff_formats_for(ui.settings(), &args.format), &diff_util::diff_formats_for(command.settings(), &args.format),
) )
} }
@ -1944,7 +1943,7 @@ fn cmd_describe(
message.into() message.into()
} else { } else {
let template = description_template_for_commit(&workspace_command, &commit)?; let template = description_template_for_commit(&workspace_command, &commit)?;
edit_description(workspace_command.repo(), &template, ui.settings())? edit_description(workspace_command.repo(), &template, command.settings())?
}; };
if description == *commit.description() { if description == *commit.description() {
ui.write("Nothing changed.\n")?; ui.write("Nothing changed.\n")?;
@ -1952,7 +1951,7 @@ fn cmd_describe(
let mut tx = let mut tx =
workspace_command.start_transaction(&format!("describe commit {}", commit.id().hex())); workspace_command.start_transaction(&format!("describe commit {}", commit.id().hex()));
tx.mut_repo() tx.mut_repo()
.rewrite_commit(ui.settings(), &commit) .rewrite_commit(command.settings(), &commit)
.set_description(description) .set_description(description)
.write()?; .write()?;
workspace_command.finish_transaction(ui, tx)?; workspace_command.finish_transaction(ui, tx)?;
@ -1971,12 +1970,12 @@ fn cmd_commit(ui: &mut Ui, command: &CommandHelper, args: &CommitArgs) -> Result
let commit = workspace_command.repo().store().get_commit(commit_id)?; let commit = workspace_command.repo().store().get_commit(commit_id)?;
let mut tx = workspace_command.start_transaction(&format!("commit {}", commit.id().hex())); let mut tx = workspace_command.start_transaction(&format!("commit {}", commit.id().hex()));
let mut commit_builder = tx.mut_repo().rewrite_commit(ui.settings(), &commit); let mut commit_builder = tx.mut_repo().rewrite_commit(command.settings(), &commit);
let description = if let Some(message) = &args.message { let description = if let Some(message) = &args.message {
message.into() message.into()
} else { } else {
let template = description_template_for_commit(&workspace_command, &commit)?; let template = description_template_for_commit(&workspace_command, &commit)?;
edit_description(workspace_command.repo(), &template, ui.settings())? edit_description(workspace_command.repo(), &template, command.settings())?
}; };
commit_builder = commit_builder.set_description(description); commit_builder = commit_builder.set_description(description);
let new_commit = commit_builder.write()?; let new_commit = commit_builder.write()?;
@ -1988,7 +1987,7 @@ fn cmd_commit(ui: &mut Ui, command: &CommandHelper, args: &CommitArgs) -> Result
let new_checkout = tx let new_checkout = tx
.mut_repo() .mut_repo()
.new_commit( .new_commit(
ui.settings(), command.settings(),
vec![new_commit.id().clone()], vec![new_commit.id().clone()],
new_commit.tree_id().clone(), new_commit.tree_id().clone(),
) )
@ -2012,7 +2011,7 @@ fn cmd_duplicate(
.start_transaction(&format!("duplicate commit {}", predecessor.id().hex())); .start_transaction(&format!("duplicate commit {}", predecessor.id().hex()));
let mut_repo = tx.mut_repo(); let mut_repo = tx.mut_repo();
let new_commit = mut_repo let new_commit = mut_repo
.rewrite_commit(ui.settings(), &predecessor) .rewrite_commit(command.settings(), &predecessor)
.generate_new_change_id() .generate_new_change_id()
.write()?; .write()?;
ui.write("Created: ")?; ui.write("Created: ")?;
@ -2021,7 +2020,7 @@ fn cmd_duplicate(
mut_repo.as_repo_ref(), mut_repo.as_repo_ref(),
&workspace_command.workspace_id(), &workspace_command.workspace_id(),
&new_commit, &new_commit,
ui.settings(), command.settings(),
)?; )?;
ui.write("\n")?; ui.write("\n")?;
workspace_command.finish_transaction(ui, tx)?; workspace_command.finish_transaction(ui, tx)?;
@ -2059,7 +2058,7 @@ fn cmd_abandon(
for commit in to_abandon { for commit in to_abandon {
tx.mut_repo().record_abandoned_commit(commit.id().clone()); tx.mut_repo().record_abandoned_commit(commit.id().clone());
} }
let num_rebased = tx.mut_repo().rebase_descendants(ui.settings())?; let num_rebased = tx.mut_repo().rebase_descendants(command.settings())?;
if num_rebased > 0 { if num_rebased > 0 {
writeln!( writeln!(
ui, ui,
@ -2102,7 +2101,7 @@ fn cmd_new(ui: &mut Ui, command: &CommandHelper, args: &NewArgs) -> Result<(), C
let merged_tree = merge_commit_trees(workspace_command.repo().as_repo_ref(), &commits); let merged_tree = merge_commit_trees(workspace_command.repo().as_repo_ref(), &commits);
let new_commit = tx let new_commit = tx
.mut_repo() .mut_repo()
.new_commit(ui.settings(), parent_ids, merged_tree.id().clone()) .new_commit(command.settings(), parent_ids, merged_tree.id().clone())
.set_description(&args.message) .set_description(&args.message)
.write()?; .write()?;
let workspace_id = workspace_command.workspace_id(); let workspace_id = workspace_command.workspace_id();
@ -2194,7 +2193,7 @@ from the source will be moved into the destination.
mut_repo.record_abandoned_commit(source.id().clone()); mut_repo.record_abandoned_commit(source.id().clone());
} else { } else {
mut_repo mut_repo
.rewrite_commit(ui.settings(), &source) .rewrite_commit(command.settings(), &source)
.set_tree(new_source_tree_id) .set_tree(new_source_tree_id)
.write()?; .write()?;
} }
@ -2203,7 +2202,7 @@ from the source will be moved into the destination.
// rewritten source. Otherwise it will likely already have the content // rewritten source. Otherwise it will likely already have the content
// changes we're moving, so applying them will have no effect and the // changes we're moving, so applying them will have no effect and the
// changes will disappear. // changes will disappear.
let mut rebaser = mut_repo.create_descendant_rebaser(ui.settings()); let mut rebaser = mut_repo.create_descendant_rebaser(command.settings());
rebaser.rebase_all()?; rebaser.rebase_all()?;
let rebased_destination_id = rebaser.rebased().get(destination.id()).unwrap().clone(); let rebased_destination_id = rebaser.rebased().get(destination.id()).unwrap().clone();
destination = mut_repo.store().get_commit(&rebased_destination_id)?; destination = mut_repo.store().get_commit(&rebased_destination_id)?;
@ -2214,11 +2213,11 @@ from the source will be moved into the destination.
workspace_command.repo(), workspace_command.repo(),
&source, &source,
&destination, &destination,
ui.settings(), command.settings(),
abandon_source, abandon_source,
)?; )?;
mut_repo mut_repo
.rewrite_commit(ui.settings(), &destination) .rewrite_commit(command.settings(), &destination)
.set_tree(new_destination_tree_id) .set_tree(new_destination_tree_id)
.set_description(description) .set_description(description)
.write()?; .write()?;
@ -2274,11 +2273,11 @@ from the source will be moved into the parent.
workspace_command.repo(), workspace_command.repo(),
&commit, &commit,
parent, parent,
ui.settings(), command.settings(),
abandon_child, abandon_child,
)?; )?;
let new_parent = mut_repo let new_parent = mut_repo
.rewrite_commit(ui.settings(), parent) .rewrite_commit(command.settings(), parent)
.set_tree(new_parent_tree_id) .set_tree(new_parent_tree_id)
.set_predecessors(vec![parent.id().clone(), commit.id().clone()]) .set_predecessors(vec![parent.id().clone(), commit.id().clone()])
.set_description(description) .set_description(description)
@ -2288,7 +2287,7 @@ from the source will be moved into the parent.
} else { } else {
// Commit the remainder on top of the new parent commit. // Commit the remainder on top of the new parent commit.
mut_repo mut_repo
.rewrite_commit(ui.settings(), &commit) .rewrite_commit(command.settings(), &commit)
.set_parents(vec![new_parent.id().clone()]) .set_parents(vec![new_parent.id().clone()])
.write()?; .write()?;
} }
@ -2347,25 +2346,25 @@ aborted.
workspace_command.repo(), workspace_command.repo(),
parent, parent,
&commit, &commit,
ui.settings(), command.settings(),
true, true,
)?; )?;
// Commit the new child on top of the parent's parents. // Commit the new child on top of the parent's parents.
tx.mut_repo() tx.mut_repo()
.rewrite_commit(ui.settings(), &commit) .rewrite_commit(command.settings(), &commit)
.set_parents(parent.parent_ids().to_vec()) .set_parents(parent.parent_ids().to_vec())
.set_description(description) .set_description(description)
.write()?; .write()?;
} else { } else {
let new_parent = tx let new_parent = tx
.mut_repo() .mut_repo()
.rewrite_commit(ui.settings(), parent) .rewrite_commit(command.settings(), parent)
.set_tree(new_parent_tree_id) .set_tree(new_parent_tree_id)
.set_predecessors(vec![parent.id().clone(), commit.id().clone()]) .set_predecessors(vec![parent.id().clone(), commit.id().clone()])
.write()?; .write()?;
// Commit the new child on top of the new parent. // Commit the new child on top of the new parent.
tx.mut_repo() tx.mut_repo()
.rewrite_commit(ui.settings(), &commit) .rewrite_commit(command.settings(), &commit)
.set_parents(vec![new_parent.id().clone()]) .set_parents(vec![new_parent.id().clone()])
.write()?; .write()?;
} }
@ -2421,7 +2420,7 @@ fn cmd_resolve(
)); ));
let new_tree_id = workspace_command.run_mergetool(ui, &commit.tree(), repo_path)?; let new_tree_id = workspace_command.run_mergetool(ui, &commit.tree(), repo_path)?;
tx.mut_repo() tx.mut_repo()
.rewrite_commit(ui.settings(), &commit) .rewrite_commit(command.settings(), &commit)
.set_tree(new_tree_id) .set_tree(new_tree_id)
.write()?; .write()?;
workspace_command.finish_transaction(ui, tx) workspace_command.finish_transaction(ui, tx)
@ -2469,7 +2468,7 @@ fn cmd_restore(
.start_transaction(&format!("restore into commit {}", to_commit.id().hex())); .start_transaction(&format!("restore into commit {}", to_commit.id().hex()));
let mut_repo = tx.mut_repo(); let mut_repo = tx.mut_repo();
let new_commit = mut_repo let new_commit = mut_repo
.rewrite_commit(ui.settings(), &to_commit) .rewrite_commit(command.settings(), &to_commit)
.set_tree(tree_id) .set_tree(tree_id)
.write()?; .write()?;
ui.write("Created ")?; ui.write("Created ")?;
@ -2478,7 +2477,7 @@ fn cmd_restore(
mut_repo.as_repo_ref(), mut_repo.as_repo_ref(),
&workspace_command.workspace_id(), &workspace_command.workspace_id(),
&new_commit, &new_commit,
ui.settings(), command.settings(),
)?; )?;
ui.write("\n")?; ui.write("\n")?;
workspace_command.finish_transaction(ui, tx)?; workspace_command.finish_transaction(ui, tx)?;
@ -2533,7 +2532,7 @@ don't make any changes, then the operation will be aborted.",
.start_transaction(&format!("edit commit {}", target_commit.id().hex())); .start_transaction(&format!("edit commit {}", target_commit.id().hex()));
let mut_repo = tx.mut_repo(); let mut_repo = tx.mut_repo();
let new_commit = mut_repo let new_commit = mut_repo
.rewrite_commit(ui.settings(), &target_commit) .rewrite_commit(command.settings(), &target_commit)
.set_tree(tree_id) .set_tree(tree_id)
.write()?; .write()?;
ui.write("Created ")?; ui.write("Created ")?;
@ -2542,7 +2541,7 @@ don't make any changes, then the operation will be aborted.",
mut_repo.as_repo_ref(), mut_repo.as_repo_ref(),
&workspace_command.workspace_id(), &workspace_command.workspace_id(),
&new_commit, &new_commit,
ui.settings(), command.settings(),
)?; )?;
ui.write("\n")?; ui.write("\n")?;
workspace_command.finish_transaction(ui, tx)?; workspace_command.finish_transaction(ui, tx)?;
@ -2643,10 +2642,11 @@ don't make any changes, then the operation will be aborted.
&base_tree, &base_tree,
&middle_tree, &middle_tree,
)?; )?;
let first_description = edit_description(tx.base_repo(), &first_template, ui.settings())?; let first_description =
edit_description(tx.base_repo(), &first_template, command.settings())?;
let first_commit = tx let first_commit = tx
.mut_repo() .mut_repo()
.rewrite_commit(ui.settings(), &commit) .rewrite_commit(command.settings(), &commit)
.set_tree(tree_id) .set_tree(tree_id)
.set_description(first_description) .set_description(first_description)
.write()?; .write()?;
@ -2657,17 +2657,18 @@ don't make any changes, then the operation will be aborted.
&middle_tree, &middle_tree,
&commit.tree(), &commit.tree(),
)?; )?;
let second_description = edit_description(tx.base_repo(), &second_template, ui.settings())?; let second_description =
edit_description(tx.base_repo(), &second_template, command.settings())?;
let second_commit = tx let second_commit = tx
.mut_repo() .mut_repo()
.rewrite_commit(ui.settings(), &commit) .rewrite_commit(command.settings(), &commit)
.set_parents(vec![first_commit.id().clone()]) .set_parents(vec![first_commit.id().clone()])
.set_tree(commit.tree_id().clone()) .set_tree(commit.tree_id().clone())
.generate_new_change_id() .generate_new_change_id()
.set_description(second_description) .set_description(second_description)
.write()?; .write()?;
let mut rebaser = DescendantRebaser::new( let mut rebaser = DescendantRebaser::new(
ui.settings(), command.settings(),
tx.mut_repo(), tx.mut_repo(),
hashmap! { commit.id().clone() => hashset!{second_commit.id().clone()} }, hashmap! { commit.id().clone() => hashset!{second_commit.id().clone()} },
hashset! {}, hashset! {},
@ -2683,7 +2684,7 @@ don't make any changes, then the operation will be aborted.
tx.repo().as_repo_ref(), tx.repo().as_repo_ref(),
&workspace_command.workspace_id(), &workspace_command.workspace_id(),
&first_commit, &first_commit,
ui.settings(), command.settings(),
)?; )?;
ui.write("\nSecond part: ")?; ui.write("\nSecond part: ")?;
write_commit_summary( write_commit_summary(
@ -2691,7 +2692,7 @@ don't make any changes, then the operation will be aborted.
tx.repo().as_repo_ref(), tx.repo().as_repo_ref(),
&workspace_command.workspace_id(), &workspace_command.workspace_id(),
&second_commit, &second_commit,
ui.settings(), command.settings(),
)?; )?;
ui.write("\n")?; ui.write("\n")?;
workspace_command.finish_transaction(ui, tx)?; workspace_command.finish_transaction(ui, tx)?;
@ -2736,7 +2737,7 @@ fn cmd_rebase(ui: &mut Ui, command: &CommandHelper, args: &RebaseArgs) -> Result
fn rebase_branch( fn rebase_branch(
ui: &mut Ui, ui: &mut Ui,
_command: &CommandHelper, command: &CommandHelper,
workspace_command: &mut WorkspaceCommandHelper, workspace_command: &mut WorkspaceCommandHelper,
new_parents: &[Commit], new_parents: &[Commit],
branch_str: &str, branch_str: &str,
@ -2763,10 +2764,10 @@ fn rebase_branch(
{ {
let root_commit = root_result?; let root_commit = root_result?;
workspace_command.check_rewriteable(&root_commit)?; workspace_command.check_rewriteable(&root_commit)?;
rebase_commit(ui.settings(), tx.mut_repo(), &root_commit, new_parents)?; rebase_commit(command.settings(), tx.mut_repo(), &root_commit, new_parents)?;
num_rebased += 1; num_rebased += 1;
} }
num_rebased += tx.mut_repo().rebase_descendants(ui.settings())?; num_rebased += tx.mut_repo().rebase_descendants(command.settings())?;
writeln!(ui, "Rebased {num_rebased} commits")?; writeln!(ui, "Rebased {num_rebased} commits")?;
workspace_command.finish_transaction(ui, tx)?; workspace_command.finish_transaction(ui, tx)?;
Ok(()) Ok(())
@ -2774,7 +2775,7 @@ fn rebase_branch(
fn rebase_descendants( fn rebase_descendants(
ui: &mut Ui, ui: &mut Ui,
_command: &CommandHelper, command: &CommandHelper,
workspace_command: &mut WorkspaceCommandHelper, workspace_command: &mut WorkspaceCommandHelper,
new_parents: &[Commit], new_parents: &[Commit],
source_str: &str, source_str: &str,
@ -2786,8 +2787,8 @@ fn rebase_descendants(
"rebase commit {} and descendants", "rebase commit {} and descendants",
old_commit.id().hex() old_commit.id().hex()
)); ));
rebase_commit(ui.settings(), tx.mut_repo(), &old_commit, new_parents)?; rebase_commit(command.settings(), tx.mut_repo(), &old_commit, new_parents)?;
let num_rebased = tx.mut_repo().rebase_descendants(ui.settings())? + 1; let num_rebased = tx.mut_repo().rebase_descendants(command.settings())? + 1;
writeln!(ui, "Rebased {num_rebased} commits")?; writeln!(ui, "Rebased {num_rebased} commits")?;
workspace_command.finish_transaction(ui, tx)?; workspace_command.finish_transaction(ui, tx)?;
Ok(()) Ok(())
@ -2795,7 +2796,7 @@ fn rebase_descendants(
fn rebase_revision( fn rebase_revision(
ui: &mut Ui, ui: &mut Ui,
_command: &CommandHelper, command: &CommandHelper,
workspace_command: &mut WorkspaceCommandHelper, workspace_command: &mut WorkspaceCommandHelper,
new_parents: &[Commit], new_parents: &[Commit],
rev_str: &str, rev_str: &str,
@ -2805,7 +2806,7 @@ fn rebase_revision(
check_rebase_destinations(workspace_command, new_parents, &old_commit)?; check_rebase_destinations(workspace_command, new_parents, &old_commit)?;
let mut tx = let mut tx =
workspace_command.start_transaction(&format!("rebase commit {}", old_commit.id().hex())); workspace_command.start_transaction(&format!("rebase commit {}", old_commit.id().hex()));
rebase_commit(ui.settings(), tx.mut_repo(), &old_commit, new_parents)?; rebase_commit(command.settings(), tx.mut_repo(), &old_commit, new_parents)?;
// Manually rebase children because we don't want to rebase them onto the // Manually rebase children because we don't want to rebase them onto the
// rewritten commit. (But we still want to record the commit as rewritten so // rewritten commit. (But we still want to record the commit as rewritten so
// branches and the working copy get updated to the rewritten commit.) // branches and the working copy get updated to the rewritten commit.)
@ -2852,14 +2853,14 @@ fn rebase_revision(
.try_collect()?; .try_collect()?;
rebase_commit( rebase_commit(
ui.settings(), command.settings(),
tx.mut_repo(), tx.mut_repo(),
&child_commit, &child_commit,
&new_child_parents, &new_child_parents,
)?; )?;
num_rebased_descendants += 1; num_rebased_descendants += 1;
} }
num_rebased_descendants += tx.mut_repo().rebase_descendants(ui.settings())?; num_rebased_descendants += tx.mut_repo().rebase_descendants(command.settings())?;
if num_rebased_descendants > 0 { if num_rebased_descendants > 0 {
writeln!( writeln!(
ui, ui,
@ -2908,7 +2909,12 @@ fn cmd_backout(
"back out commit {}", "back out commit {}",
commit_to_back_out.id().hex() commit_to_back_out.id().hex()
)); ));
back_out_commit(ui.settings(), tx.mut_repo(), &commit_to_back_out, &parents)?; back_out_commit(
command.settings(),
tx.mut_repo(),
&commit_to_back_out,
&parents,
)?;
workspace_command.finish_transaction(ui, tx)?; workspace_command.finish_transaction(ui, tx)?;
Ok(()) Ok(())
@ -3081,7 +3087,7 @@ fn cmd_branch(
fn list_branches( fn list_branches(
ui: &mut Ui, ui: &mut Ui,
_command: &CommandHelper, command: &CommandHelper,
workspace_command: &WorkspaceCommandHelper, workspace_command: &WorkspaceCommandHelper,
) -> Result<(), CommandError> { ) -> Result<(), CommandError> {
let repo = workspace_command.repo(); let repo = workspace_command.repo();
@ -3099,7 +3105,7 @@ fn list_branches(
repo.as_repo_ref(), repo.as_repo_ref(),
&workspace_id, &workspace_id,
&commit, &commit,
ui.settings(), command.settings(),
)?; )?;
writeln!(formatter)?; writeln!(formatter)?;
} }
@ -3115,7 +3121,7 @@ fn list_branches(
repo.as_repo_ref(), repo.as_repo_ref(),
&workspace_id, &workspace_id,
&commit, &commit,
ui.settings(), command.settings(),
)?; )?;
writeln!(formatter)?; writeln!(formatter)?;
} }
@ -3127,7 +3133,7 @@ fn list_branches(
repo.as_repo_ref(), repo.as_repo_ref(),
&workspace_id, &workspace_id,
&commit, &commit,
ui.settings(), command.settings(),
)?; )?;
writeln!(formatter)?; writeln!(formatter)?;
} }
@ -3470,7 +3476,7 @@ fn cmd_workspace_add(
))); )));
} }
let (new_workspace, repo) = Workspace::init_workspace_with_existing_repo( let (new_workspace, repo) = Workspace::init_workspace_with_existing_repo(
ui.settings(), command.settings(),
&destination_path, &destination_path,
repo, repo,
workspace_id, workspace_id,
@ -3488,6 +3494,7 @@ fn cmd_workspace_add(
command.cwd().to_owned(), command.cwd().to_owned(),
command.string_args().clone(), command.string_args().clone(),
command.global_args(), command.global_args(),
command.settings().clone(),
repo, repo,
)?; )?;
let mut tx = new_workspace_command.start_transaction(&format!( let mut tx = new_workspace_command.start_transaction(&format!(
@ -3512,7 +3519,7 @@ fn cmd_workspace_add(
}; };
tx.mut_repo().check_out( tx.mut_repo().check_out(
new_workspace_command.workspace_id(), new_workspace_command.workspace_id(),
ui.settings(), command.settings(),
&new_wc_commit, &new_wc_commit,
)?; )?;
new_workspace_command.finish_transaction(ui, tx)?; new_workspace_command.finish_transaction(ui, tx)?;
@ -3562,7 +3569,7 @@ fn cmd_workspace_list(
repo.as_repo_ref(), repo.as_repo_ref(),
workspace_id, workspace_id,
&commit, &commit,
ui.settings(), command.settings(),
)?; )?;
writeln!(ui)?; writeln!(ui)?;
} }
@ -3574,7 +3581,7 @@ fn cmd_workspace_update_stale(
command: &CommandHelper, command: &CommandHelper,
_args: &WorkspaceUpdateStaleArgs, _args: &WorkspaceUpdateStaleArgs,
) -> Result<(), CommandError> { ) -> Result<(), CommandError> {
let workspace = command.load_workspace(ui)?; let workspace = command.load_workspace()?;
let mut workspace_command = command.resolve_operation(ui, workspace)?; let mut workspace_command = command.resolve_operation(ui, workspace)?;
let repo = workspace_command.repo().clone(); let repo = workspace_command.repo().clone();
let workspace_id = workspace_command.workspace_id(); let workspace_id = workspace_command.workspace_id();
@ -3603,7 +3610,7 @@ fn cmd_workspace_update_stale(
repo.as_repo_ref(), repo.as_repo_ref(),
&workspace_id, &workspace_id,
&desired_wc_commit, &desired_wc_commit,
ui.settings(), command.settings(),
)?; )?;
ui.write("\n")?; ui.write("\n")?;
print_checkout_stats(ui, stats)?; print_checkout_stats(ui, stats)?;
@ -3861,7 +3868,7 @@ fn cmd_git_clone(
if let Ok(commit) = workspace_command.repo().store().get_commit(&commit_id) { if let Ok(commit) = workspace_command.repo().store().get_commit(&commit_id) {
checkout_tx.mut_repo().check_out( checkout_tx.mut_repo().check_out(
workspace_command.workspace_id(), workspace_command.workspace_id(),
ui.settings(), command.settings(),
&commit, &commit,
)?; )?;
} }
@ -3877,7 +3884,7 @@ fn do_git_clone(
source: &str, source: &str,
wc_path: &Path, wc_path: &Path,
) -> Result<(WorkspaceCommandHelper, Option<String>), CommandError> { ) -> Result<(WorkspaceCommandHelper, Option<String>), CommandError> {
let (workspace, repo) = Workspace::init_internal_git(ui.settings(), wc_path)?; let (workspace, repo) = Workspace::init_internal_git(command.settings(), wc_path)?;
let git_repo = get_git_repo(repo.store())?; let git_repo = get_git_repo(repo.store())?;
writeln!(ui, r#"Fetching into new repo in "{}""#, wc_path.display())?; writeln!(ui, r#"Fetching into new repo in "{}""#, wc_path.display())?;
let mut workspace_command = command.for_loaded_repo(ui, workspace, repo)?; let mut workspace_command = command.for_loaded_repo(ui, workspace, repo)?;
@ -4079,7 +4086,7 @@ fn cmd_git_push(
for (change_str, commit) in std::iter::zip(args.change.iter(), commits) { for (change_str, commit) in std::iter::zip(args.change.iter(), commits) {
let branch_name = format!( let branch_name = format!(
"{}{}", "{}{}",
ui.settings().push_branch_prefix(), command.settings().push_branch_prefix(),
commit.change_id().hex() commit.change_id().hex()
); );
if !seen_branches.insert(branch_name.clone()) { if !seen_branches.insert(branch_name.clone()) {

View file

@ -30,7 +30,6 @@ pub struct Ui {
progress_indicator: bool, progress_indicator: bool,
formatter_factory: FormatterFactory, formatter_factory: FormatterFactory,
output: UiOutput, output: UiOutput,
settings: UserSettings,
} }
fn progress_indicator_setting(settings: &UserSettings) -> bool { fn progress_indicator_setting(settings: &UserSettings) -> bool {
@ -132,17 +131,14 @@ impl Ui {
paginate: PaginationChoice::Auto, paginate: PaginationChoice::Auto,
progress_indicator, progress_indicator,
output: UiOutput::new_terminal(), output: UiOutput::new_terminal(),
settings,
} }
} }
pub fn reset(&mut self, settings: UserSettings) { pub fn reset(&mut self, settings: &UserSettings) {
// TODO: maybe Ui shouldn't take ownership of UserSettings self.color = use_color(color_setting(settings));
self.color = use_color(color_setting(&settings)); self.pager_cmd = pager_setting(settings);
self.pager_cmd = pager_setting(&settings); self.progress_indicator = progress_indicator_setting(settings);
self.progress_indicator = progress_indicator_setting(&settings); self.formatter_factory = FormatterFactory::prepare(settings, self.color);
self.formatter_factory = FormatterFactory::prepare(&settings, self.color);
self.settings = settings;
} }
/// Sets the pagination value. /// Sets the pagination value.
@ -179,10 +175,6 @@ impl Ui {
self.color self.color
} }
pub fn settings(&self) -> &UserSettings {
&self.settings
}
pub fn new_formatter<'output, W: Write + 'output>( pub fn new_formatter<'output, W: Write + 'output>(
&self, &self,
output: W, output: W,