From c854ba3422c03252c35ac2ab310454b47f11f5ed Mon Sep 17 00:00:00 2001 From: Martin von Zweigbergk Date: Sun, 20 Mar 2022 21:05:21 -0700 Subject: [PATCH] cli: let the user know if there's been a concurrent modification (#111) --- src/commands.rs | 15 ++++++-- tests/test_concurrent_operations.rs | 56 +++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 tests/test_concurrent_operations.rs diff --git a/src/commands.rs b/src/commands.rs index e075a47b65a..2fc58fb8ee6 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -47,7 +47,7 @@ use jujutsu_lib::op_heads_store::OpHeadsStore; use jujutsu_lib::op_store::{OpStore, OpStoreError, OperationId, RefTarget, WorkspaceId}; use jujutsu_lib::operation::Operation; use jujutsu_lib::refs::{classify_branch_push_action, BranchPushAction}; -use jujutsu_lib::repo::{MutableRepo, ReadonlyRepo, RepoRef}; +use jujutsu_lib::repo::{MutableRepo, ReadonlyRepo, RepoAtHead, RepoRef}; use jujutsu_lib::repo_path::RepoPath; use jujutsu_lib::revset::{RevsetError, RevsetExpression, RevsetParseError}; use jujutsu_lib::revset_graph_iterator::RevsetGraphEdgeType; @@ -184,7 +184,7 @@ impl<'help> CommandHelper<'help> { &self.args } - fn workspace_helper(&self, ui: &Ui) -> Result { + fn workspace_helper(&self, ui: &mut Ui) -> Result { let wc_path_str = self.args.repository.as_deref().unwrap_or("."); let wc_path = ui.cwd().join(wc_path_str); let workspace = match Workspace::load(ui.settings(), wc_path) { @@ -211,7 +211,16 @@ jj init --git-repo=."; let repo_loader = workspace.repo_loader(); let op_str = &self.args.at_operation; let repo = if op_str == "@" { - repo_loader.load_at_head().resolve() + match repo_loader.load_at_head() { + RepoAtHead::Single(repo) => repo, + RepoAtHead::Unresolved(unresolved) => { + writeln!( + ui, + "Concurrent modification detected, resolving automatically.", + )?; + unresolved.resolve() + } + } } else { let op = resolve_single_op_from_store( repo_loader.op_store(), diff --git a/tests/test_concurrent_operations.rs b/tests/test_concurrent_operations.rs new file mode 100644 index 00000000000..96241491a09 --- /dev/null +++ b/tests/test_concurrent_operations.rs @@ -0,0 +1,56 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use jujutsu::testutils::{get_stdout_string, TestEnvironment}; + +#[test] +fn test_concurrent_operations() { + let test_env = TestEnvironment::default(); + test_env + .jj_cmd(test_env.env_root(), &["init", "repo", "--git"]) + .assert() + .success(); + let repo_path = test_env.env_root().join("repo"); + + let assert = test_env + .jj_cmd(&repo_path, &["op", "log"]) + .assert() + .success(); + let op_id_hex = get_stdout_string(&assert)[2..14].to_string(); + + test_env + .jj_cmd(&repo_path, &["describe", "-m", "message 1"]) + .assert() + .success(); + test_env + .jj_cmd( + &repo_path, + &["describe", "-m", "message 2", "--at-op", &op_id_hex], + ) + .assert() + .success(); + + // We should be informed about the concurrent modification + let assert = test_env + .jj_cmd(&repo_path, &["log", "-T", "description"]) + .assert() + .success(); + insta::assert_snapshot!(get_stdout_string(&assert), @r###" + Concurrent modification detected, resolving automatically. + o message 2 + | @ message 1 + |/ + o + "###); +}