From 418ab22be08c819b8e6f786ebae312f6c0706423 Mon Sep 17 00:00:00 2001 From: Martin von Zweigbergk Date: Tue, 28 Jun 2022 16:07:21 -0700 Subject: [PATCH] cli: add config for using only new UX for open commits By adding `ui.open-commits=false` in your config, you can now make `jj checkout` always create a new working-copy commit on top of the specified commit. If the config is set, open commits will also appear in the same color as closed commits in `jj log` etc. This will let some of us experiment with the new UX before we decide if it's a good idea or not. I left `jj close` in place because it's useful for setting a description and creating a new commit in one step. I didn't mention the new config in the release notes because I hope we can reach a decision and remove the config before the next release. --- lib/src/settings.rs | 6 +++++ src/commands.rs | 53 +++++++++++++++++++++++++++++------------- tests/test_checkout.rs | 15 ++++++++++++ 3 files changed, 58 insertions(+), 16 deletions(-) diff --git a/lib/src/settings.rs b/lib/src/settings.rs index cd2d0f83b..3781a913f 100644 --- a/lib/src/settings.rs +++ b/lib/src/settings.rs @@ -88,6 +88,12 @@ impl UserSettings { } } + pub fn enable_open_commits(&self) -> bool { + self.config + .get_bool("ui.enable-open-commits") + .unwrap_or(true) + } + pub fn config(&self) -> &config::Config { &self.config } diff --git a/src/commands.rs b/src/commands.rs index 37e0de738..59b291ad8 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -2122,18 +2122,27 @@ fn cmd_checkout( let mut workspace_command = command.workspace_helper(ui)?; let new_commit = workspace_command.resolve_single_rev(ui, &args.revision)?; let workspace_id = workspace_command.workspace_id(); - if workspace_command.repo().view().get_checkout(&workspace_id) == Some(new_commit.id()) { - ui.write("Already on that commit\n")?; + if ui.settings().enable_open_commits() { + if workspace_command.repo().view().get_checkout(&workspace_id) == Some(new_commit.id()) { + ui.write("Already on that commit\n")?; + } else { + workspace_command.commit_working_copy(ui)?; + let mut tx = workspace_command + .start_transaction(&format!("check out commit {}", new_commit.id().hex())); + if new_commit.is_open() { + tx.mut_repo().edit(workspace_id, &new_commit); + } else { + tx.mut_repo() + .check_out(workspace_id, ui.settings(), &new_commit); + } + workspace_command.finish_transaction(ui, tx)?; + } } else { workspace_command.commit_working_copy(ui)?; let mut tx = workspace_command .start_transaction(&format!("check out commit {}", new_commit.id().hex())); - if new_commit.is_open() { - tx.mut_repo().edit(workspace_id, &new_commit); - } else { - tx.mut_repo() - .check_out(workspace_id, ui.settings(), &new_commit); - } + tx.mut_repo() + .check_out(workspace_id, ui.settings(), &new_commit); workspace_command.finish_transaction(ui, tx)?; } Ok(()) @@ -2376,19 +2385,25 @@ fn cmd_show(ui: &mut Ui, command: &CommandHelper, args: &ShowArgs) -> Result<(), // TODO: Add branches, tags, etc // TODO: Indent the description like Git does let template_string = r#" - label(if(open, "open"), "Commit ID: " commit_id "\n" "Change ID: " change_id "\n" "Author: " author " <" author.email() "> (" author.timestamp() ")\n" "Committer: " committer " <" committer.email() "> (" committer.timestamp() ")\n" "\n" description - "\n" - )"#; + "\n""#; + let template_string = if ui.settings().enable_open_commits() { + format!( + r#" + label(if(open, "open"), {template_string})"# + ) + } else { + String::from(template_string) + }; let template = crate::template_parser::parse_commit_template( workspace_command.repo().as_repo_ref(), &workspace_command.workspace_id(), - template_string, + &template_string, ); let mut formatter = ui.stdout_formatter(); let formatter = formatter.as_mut(); @@ -2995,7 +3010,6 @@ fn log_template(settings: &UserSettings) -> String { // TODO: define a method on boolean values, so we can get auto-coloring // with e.g. `conflict.then("conflict")` let default_template = r#" - label(if(open, "open"), commit_id.short() " " change_id.short() " " author.email() @@ -3008,12 +3022,19 @@ fn log_template(settings: &UserSettings) -> String { if(conflict, label("conflict", " conflict")) "\n" description.first_line() - "\n" - )"#; + "\n""#; + let default_template = if settings.enable_open_commits() { + format!( + r#" + label(if(open, "open"), {default_template})"# + ) + } else { + String::from(default_template) + }; settings .config() .get_string("template.log.graph") - .unwrap_or_else(|_| String::from(default_template)) + .unwrap_or(default_template) } fn cmd_log(ui: &mut Ui, command: &CommandHelper, args: &LogArgs) -> Result<(), CommandError> { diff --git a/tests/test_checkout.rs b/tests/test_checkout.rs index 7c58c376f..a60d5a377 100644 --- a/tests/test_checkout.rs +++ b/tests/test_checkout.rs @@ -56,6 +56,21 @@ fn test_checkout() { o b4c967d9c9a9e8b523b0a9b52879b3337a3e67a9 closed o 0000000000000000000000000000000000000000 (no description set) "###); + + // With ui.enable-open-commits=false, checking out an open commit also results + // in a commit on top + test_env.add_config( + br#"[ui] + enable-open-commits = false + "#, + ); + test_env.jj_cmd_success(&repo_path, &["checkout", "open"]); + insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" + @ 37b7bc83cf288eef68564044a9ac0ec6c5df34f0 (no description set) + o 169fa76981bcf302d1a96952bdf32a8da79ab084 open + o b4c967d9c9a9e8b523b0a9b52879b3337a3e67a9 closed + o 0000000000000000000000000000000000000000 (no description set) + "###); } fn get_log_output(test_env: &TestEnvironment, cwd: &Path) -> String {