working_copy: make old_checkout argument be MergedTreeId

I think this was the last piece for making the working copy handle
tree-level conflicts.
This commit is contained in:
Martin von Zweigbergk 2023-08-26 07:05:10 -07:00 committed by Martin von Zweigbergk
parent abf3853717
commit 1895a55157
3 changed files with 14 additions and 36 deletions

View file

@ -1914,8 +1914,8 @@ pub fn update_working_copy(
old_commit: Option<&Commit>,
new_commit: &Commit,
) -> Result<Option<CheckoutStats>, CommandError> {
let old_tree_id = old_commit.map(|commit| commit.tree_id().clone());
let stats = if Some(new_commit.tree_id()) != old_tree_id.as_ref() {
let old_tree_id = old_commit.map(|commit| commit.merged_tree_id().clone());
let stats = if Some(new_commit.merged_tree_id()) != old_tree_id.as_ref() {
// TODO: CheckoutError::ConcurrentCheckout should probably just result in a
// warning for most commands (but be an error for the checkout command)
let new_tree = new_commit.merged_tree()?;

View file

@ -1524,7 +1524,7 @@ impl WorkingCopy {
pub fn check_out(
&mut self,
operation_id: OperationId,
old_tree_id: Option<&TreeId>,
old_tree_id: Option<&MergedTreeId>,
new_tree: &MergedTree,
) -> Result<CheckoutStats, CheckoutError> {
let mut locked_wc = self.start_mutation()?;
@ -1533,7 +1533,7 @@ impl WorkingCopy {
// regardless, but it's probably not what the caller wanted, so we let
// them know.
if let Some(old_tree_id) = old_tree_id {
if *old_tree_id != locked_wc.old_tree_id.to_legacy_tree_id() {
if *old_tree_id != locked_wc.old_tree_id {
locked_wc.discard();
return Err(CheckoutError::ConcurrentCheckout);
}

View file

@ -33,27 +33,17 @@ fn test_concurrent_checkout() {
let repo1 = test_workspace1.repo.clone();
let workspace1_root = test_workspace1.workspace.workspace_root().clone();
let tree_id1 = testutils::create_random_tree(&repo1);
let tree_id2 = testutils::create_random_tree(&repo1);
let tree_id3 = testutils::create_random_tree(&repo1);
let tree1 = repo1
.store()
.get_tree(&RepoPath::root(), &tree_id1)
.unwrap();
let tree2 = repo1
.store()
.get_tree(&RepoPath::root(), &tree_id2)
.unwrap();
let tree3 = repo1
.store()
.get_tree(&RepoPath::root(), &tree_id3)
.unwrap();
let tree_id1 = MergedTreeId::Legacy(testutils::create_random_tree(&repo1));
let tree_id2 = MergedTreeId::Legacy(testutils::create_random_tree(&repo1));
let tree_id3 = MergedTreeId::Legacy(testutils::create_random_tree(&repo1));
let tree1 = repo1.store().get_root_tree(&tree_id1).unwrap();
let tree2 = repo1.store().get_root_tree(&tree_id2).unwrap();
let tree3 = repo1.store().get_root_tree(&tree_id3).unwrap();
// Check out tree1
let wc1 = test_workspace1.workspace.working_copy_mut();
// The operation ID is not correct, but that doesn't matter for this test
wc1.check_out(repo1.op_id().clone(), None, &MergedTree::legacy(tree1))
.unwrap();
wc1.check_out(repo1.op_id().clone(), None, &tree1).unwrap();
// Check out tree2 from another process (simulated by another workspace
// instance)
@ -61,20 +51,12 @@ fn test_concurrent_checkout() {
Workspace::load(&settings, &workspace1_root, &StoreFactories::default()).unwrap();
workspace2
.working_copy_mut()
.check_out(
repo1.op_id().clone(),
Some(&tree_id1),
&MergedTree::legacy(tree2),
)
.check_out(repo1.op_id().clone(), Some(&tree_id1), &tree2)
.unwrap();
// Checking out another tree (via the first repo instance) should now fail.
assert_matches!(
wc1.check_out(
repo1.op_id().clone(),
Some(&tree_id1),
&MergedTree::legacy(tree3)
),
wc1.check_out(repo1.op_id().clone(), Some(&tree_id1), &tree3),
Err(CheckoutError::ConcurrentCheckout)
);
@ -82,11 +64,7 @@ fn test_concurrent_checkout() {
let workspace3 =
Workspace::load(&settings, &workspace1_root, &StoreFactories::default()).unwrap();
assert_eq!(
workspace3
.working_copy()
.current_tree_id()
.unwrap()
.to_legacy_tree_id(),
*workspace3.working_copy().current_tree_id().unwrap(),
tree_id2
);
}