cli: teach jj checkout a -m flag, to match jj new

The two commands are very similar and we should probably make one an
alias of the other (or just delete one), but for now let's at least
make them more similar by supporting `-m` for both.

I currently think `jj new` is more natural when starting a new change
on top of the current one and `jj checkout` is more natural when
starting a new change on top of another one, as well as when you just
want to look around or run tests. `jj checkout` doesn't currently
default to the working copy like `jj new` does. Perhaps we should make
it do that. Will people eventually feel that it's natural to run `jj
checkout` to create a new change on top of the working copy, or will
they feel that it's natural to run `jj new` on an unrelated commit
even to just look around, or will we want them as synonyms forever?
This commit is contained in:
Martin von Zweigbergk 2022-08-26 22:03:51 -07:00 committed by Martin von Zweigbergk
parent 22e9997563
commit cd458ec96b
3 changed files with 37 additions and 11 deletions

View File

@ -128,6 +128,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Color setting can now be overridden by `--color=always|never|auto` option.
* `jj checkout` now lets you specify a description with `--message/-m`.
### Fixed bugs
* When rebasing a conflict where one side modified a file and the other side

View File

@ -1166,6 +1166,9 @@ struct InitArgs {
struct CheckoutArgs {
/// The revision to update to
revision: String,
/// The change description to use
#[clap(long, short, default_value = "")]
message: String,
}
/// Stop tracking specified paths in the working copy
@ -2099,27 +2102,39 @@ fn cmd_checkout(
args: &CheckoutArgs,
) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let new_commit = workspace_command.resolve_single_rev(&args.revision)?;
let target = workspace_command.resolve_single_rev(&args.revision)?;
let workspace_id = workspace_command.workspace_id();
if ui.settings().enable_open_commits() {
if workspace_command.repo().view().get_checkout(&workspace_id) == Some(new_commit.id()) {
if workspace_command.repo().view().get_checkout(&workspace_id) == Some(target.id()) {
ui.write("Already on that commit\n")?;
} else {
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);
.start_transaction(&format!("check out commit {}", target.id().hex()));
if target.is_open() {
tx.mut_repo().edit(workspace_id, &target);
} else {
tx.mut_repo()
.check_out(workspace_id, ui.settings(), &new_commit);
let commit_builder = CommitBuilder::for_open_commit(
ui.settings(),
target.id().clone(),
target.tree_id().clone(),
)
.set_description(args.message.clone());
let new_commit = commit_builder.write_to_repo(tx.mut_repo());
tx.mut_repo().edit(workspace_id, &new_commit);
}
workspace_command.finish_transaction(ui, tx)?;
}
} else {
let mut tx = workspace_command
.start_transaction(&format!("check out commit {}", new_commit.id().hex()));
tx.mut_repo()
.check_out(workspace_id, ui.settings(), &new_commit);
let mut tx =
workspace_command.start_transaction(&format!("check out commit {}", target.id().hex()));
let commit_builder = CommitBuilder::for_open_commit(
ui.settings(),
target.id().clone(),
target.tree_id().clone(),
)
.set_description(args.message.clone());
let new_commit = commit_builder.write_to_repo(tx.mut_repo());
tx.mut_repo().edit(workspace_id, &new_commit);
workspace_command.finish_transaction(ui, tx)?;
}
Ok(())

View File

@ -71,6 +71,15 @@ fn test_checkout() {
o b4c967d9c9a9e8b523b0a9b52879b3337a3e67a9 closed
o 0000000000000000000000000000000000000000 (no description set)
"###);
// Can provide a description
test_env.jj_cmd_success(&repo_path, &["checkout", "@-", "-m", "my message"]);
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ 14a7f0fd8f8a8235efdf4b20635567ebcf5c9776 my message
o 169fa76981bcf302d1a96952bdf32a8da79ab084 open
o b4c967d9c9a9e8b523b0a9b52879b3337a3e67a9 closed
o 0000000000000000000000000000000000000000 (no description set)
"###);
}
fn get_log_output(test_env: &TestEnvironment, cwd: &Path) -> String {