forked from mirrors/jj
working_copy: move logic of check_out()
onto LockedWorkingCopy
Having the checkout functionality in `LockedWorkingCopy` makes it a little more flexible (one could imagine using it for udating working copy files and then discarding the state changes, for example). It also lets us reuse a few lines of code for locking. I left `WorkingCopy::check_out()` for convenience because that's what all current users want.
This commit is contained in:
parent
9e1869dcef
commit
fabaf8b608
1 changed files with 46 additions and 37 deletions
|
@ -816,43 +816,6 @@ impl WorkingCopy {
|
|||
self.write_proto(proto);
|
||||
}
|
||||
|
||||
pub fn check_out(
|
||||
&mut self,
|
||||
old_commit_id: Option<&CommitId>,
|
||||
new_commit: Commit,
|
||||
) -> Result<CheckoutStats, CheckoutError> {
|
||||
assert!(new_commit.is_open());
|
||||
let lock_path = self.state_path.join("working_copy.lock");
|
||||
let _lock = FileLock::lock(lock_path);
|
||||
|
||||
// TODO: Write a "pending_checkout" file with the old and new TreeIds so we can
|
||||
// continue an interrupted checkout if we find such a file. Write
|
||||
// access to that file can also serve as lock so only one process
|
||||
// at once can do a checkout.
|
||||
|
||||
// Check if the current checkout has changed on disk compared to what the caller
|
||||
// expected. It's safe to check out another commit regardless, but it's
|
||||
// probably not what the caller wanted, so we let them know.
|
||||
let current_proto = self.read_proto();
|
||||
if let Some(old_commit_id) = old_commit_id {
|
||||
if current_proto.commit_id != old_commit_id.as_bytes() {
|
||||
return Err(CheckoutError::ConcurrentCheckout);
|
||||
}
|
||||
}
|
||||
|
||||
let stats = self
|
||||
.tree_state()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.check_out(new_commit.tree().id().clone())?;
|
||||
|
||||
self.commit_id.replace(Some(new_commit.id().clone()));
|
||||
|
||||
self.save();
|
||||
// TODO: Clear the "pending_checkout" file here.
|
||||
Ok(stats)
|
||||
}
|
||||
|
||||
pub fn start_mutation(&mut self) -> LockedWorkingCopy {
|
||||
let lock_path = self.state_path.join("working_copy.lock");
|
||||
let lock = FileLock::lock(lock_path);
|
||||
|
@ -868,6 +831,24 @@ impl WorkingCopy {
|
|||
closed: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_out(
|
||||
&mut self,
|
||||
old_commit_id: Option<&CommitId>,
|
||||
new_commit: Commit,
|
||||
) -> Result<CheckoutStats, CheckoutError> {
|
||||
let mut locked_wc = self.start_mutation();
|
||||
let new_commit_id = new_commit.id().clone();
|
||||
let stats = match locked_wc.check_out(old_commit_id, new_commit) {
|
||||
Err(CheckoutError::ConcurrentCheckout) => {
|
||||
locked_wc.discard();
|
||||
return Err(CheckoutError::ConcurrentCheckout);
|
||||
}
|
||||
other => other,
|
||||
}?;
|
||||
locked_wc.finish(new_commit_id);
|
||||
Ok(stats)
|
||||
}
|
||||
}
|
||||
|
||||
// A working copy that's locked on disk. The tree state has already been
|
||||
|
@ -890,6 +871,33 @@ impl LockedWorkingCopy<'_> {
|
|||
self.wc.tree_state().as_mut().unwrap().write_tree()
|
||||
}
|
||||
|
||||
pub fn check_out(
|
||||
&mut self,
|
||||
old_commit_id: Option<&CommitId>,
|
||||
new_commit: Commit,
|
||||
) -> Result<CheckoutStats, CheckoutError> {
|
||||
assert!(new_commit.is_open());
|
||||
// TODO: Write a "pending_checkout" file with the old and new TreeIds so we can
|
||||
// continue an interrupted checkout if we find such a file.
|
||||
|
||||
// Check if the current checkout has changed on disk compared to what the caller
|
||||
// expected. It's safe to check out another commit regardless, but it's
|
||||
// probably not what the caller wanted, so we let them know.
|
||||
if let Some(old_commit_id) = old_commit_id {
|
||||
if *old_commit_id != self.old_commit_id {
|
||||
return Err(CheckoutError::ConcurrentCheckout);
|
||||
}
|
||||
}
|
||||
|
||||
let stats = self
|
||||
.wc
|
||||
.tree_state()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.check_out(new_commit.tree().id().clone())?;
|
||||
Ok(stats)
|
||||
}
|
||||
|
||||
pub fn reset(&mut self, new_tree: &Tree) -> Result<(), ResetError> {
|
||||
self.wc.tree_state().as_mut().unwrap().reset(new_tree)
|
||||
}
|
||||
|
@ -898,6 +906,7 @@ impl LockedWorkingCopy<'_> {
|
|||
self.wc.tree_state().as_mut().unwrap().save();
|
||||
self.wc.commit_id.replace(Some(commit_id));
|
||||
self.wc.save();
|
||||
// TODO: Clear the "pending_checkout" file here.
|
||||
self.closed = true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue