forked from mirrors/jj
repo: make reload() and reload_at() return a new ReadonlyRepo
After this patch `ReadonlyRepo` is even closer to readonly. That makes it easier to reason about. It will allow some further cleanups too.
This commit is contained in:
parent
e3ca27bf77
commit
ce855bccfa
13 changed files with 250 additions and 343 deletions
|
@ -352,23 +352,12 @@ impl ReadonlyRepo {
|
|||
Transaction::new(mut_repo, description)
|
||||
}
|
||||
|
||||
pub fn reload(&mut self) {
|
||||
let repo_loader = self.loader();
|
||||
let operation = self
|
||||
.op_heads_store
|
||||
.get_single_op_head(&repo_loader)
|
||||
.unwrap();
|
||||
self.op_id = operation.id().clone();
|
||||
self.view = ReadonlyView::new(operation.view().take_store_view());
|
||||
self.index.lock().unwrap().take();
|
||||
self.evolution.lock().unwrap().take();
|
||||
pub fn reload(&self) -> Result<Arc<ReadonlyRepo>, RepoLoadError> {
|
||||
self.loader().load_at_head()
|
||||
}
|
||||
|
||||
pub fn reload_at(&mut self, operation: &Operation) {
|
||||
self.op_id = operation.id().clone();
|
||||
self.view = ReadonlyView::new(operation.view().take_store_view());
|
||||
self.index.lock().unwrap().take();
|
||||
self.evolution.lock().unwrap().take();
|
||||
pub fn reload_at(&self, operation: &Operation) -> Result<Arc<ReadonlyRepo>, RepoLoadError> {
|
||||
self.loader().load_at(operation)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -718,7 +718,11 @@ impl WorkingCopy {
|
|||
Ok(stats)
|
||||
}
|
||||
|
||||
pub fn commit(&self, settings: &UserSettings, repo: &mut ReadonlyRepo) -> Commit {
|
||||
pub fn commit(
|
||||
&self,
|
||||
settings: &UserSettings,
|
||||
mut repo: Arc<ReadonlyRepo>,
|
||||
) -> (Arc<ReadonlyRepo>, Commit) {
|
||||
let lock_path = self.state_path.join("working_copy.lock");
|
||||
let _lock = FileLock::lock(lock_path);
|
||||
|
||||
|
@ -735,7 +739,7 @@ impl WorkingCopy {
|
|||
// Reload the repo so the new commit is visible in the index and view
|
||||
// TODO: This is not enough. The new commit is not necessarily still in the
|
||||
// view when we reload.
|
||||
repo.reload();
|
||||
repo = repo.reload().unwrap();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -750,12 +754,13 @@ impl WorkingCopy {
|
|||
.write_to_repo(mut_repo);
|
||||
mut_repo.set_checkout(commit.id().clone());
|
||||
let operation = tx.commit();
|
||||
repo.reload_at(&operation);
|
||||
repo = repo.reload_at(&operation).unwrap();
|
||||
|
||||
self.commit_id.replace(Some(commit.id().clone()));
|
||||
self.commit.replace(Some(commit));
|
||||
self.save();
|
||||
}
|
||||
self.commit.borrow().as_ref().unwrap().clone()
|
||||
let commit = self.commit.borrow().as_ref().unwrap().clone();
|
||||
(repo, commit)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
// limitations under the License.
|
||||
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use jujube_lib::repo::ReadonlyRepo;
|
||||
use jujube_lib::testutils;
|
||||
|
@ -141,12 +140,12 @@ fn test_bad_locking_interrupted(use_git: bool) {
|
|||
// that's a descendant of the other is resolved without creating a new
|
||||
// operation.
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let initial = testutils::create_random_commit(&settings, &repo)
|
||||
.set_parents(vec![repo.store().root_commit_id().clone()])
|
||||
.write_to_new_transaction(&repo, "test");
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
|
||||
// Simulate a crash that resulted in the old op-head left in place. We simulate
|
||||
// it somewhat hackily by copying the .jj/op_heads/ directory before the
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use jujube_lib::commit_builder::CommitBuilder;
|
||||
use jujube_lib::repo_path::FileRepoPath;
|
||||
use jujube_lib::settings::UserSettings;
|
||||
|
@ -64,7 +62,7 @@ fn test_initial(use_git: bool) {
|
|||
#[test_case(true ; "git store")]
|
||||
fn test_rewrite(use_git: bool) {
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
let store = repo.store().clone();
|
||||
|
||||
let root_file_path = FileRepoPath::from("file");
|
||||
|
@ -81,7 +79,7 @@ fn test_rewrite(use_git: bool) {
|
|||
CommitBuilder::for_new_commit(&settings, &store, initial_tree.id().clone())
|
||||
.set_parents(vec![store.root_commit_id().clone()])
|
||||
.write_to_new_transaction(&repo, "test");
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
|
||||
let rewritten_tree = testutils::create_tree(
|
||||
&repo,
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
|
||||
use jujube_lib::repo::ReadonlyRepo;
|
||||
|
@ -44,7 +43,7 @@ fn test_commit_parallel(use_git: bool) {
|
|||
// transactions from it. It then reloads the repo. That should merge all the
|
||||
// operations and all commits should be visible.
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let mut threads = vec![];
|
||||
for _ in 0..100 {
|
||||
|
@ -59,7 +58,7 @@ fn test_commit_parallel(use_git: bool) {
|
|||
for thread in threads {
|
||||
thread.join().ok().unwrap();
|
||||
}
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
// One commit per thread plus the commit from the initial checkout on top of the
|
||||
// root commit
|
||||
assert_eq!(repo.view().heads().len(), 101);
|
||||
|
|
|
@ -126,7 +126,7 @@ fn test_import_refs_reimport() {
|
|||
delete_git_ref(&git_repo, "refs/heads/feature2");
|
||||
let commit5 = empty_git_commit(&git_repo, "refs/heads/feature2", &[&commit2]);
|
||||
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
repo = repo.reload().unwrap();
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let mut_repo = tx.mut_repo();
|
||||
jujube_lib::git::import_refs(mut_repo, &git_repo).unwrap_or_default();
|
||||
|
@ -203,7 +203,7 @@ fn test_import_refs_merge() {
|
|||
let mut tx = repo.start_transaction("initial import");
|
||||
jujube_lib::git::import_refs(tx.mut_repo(), &git_repo).unwrap_or_default();
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
repo = repo.reload().unwrap();
|
||||
|
||||
// One of the concurrent operations:
|
||||
git_ref(&git_repo, "refs/heads/sideways-unchanged", commit4.id());
|
||||
|
@ -230,7 +230,7 @@ fn test_import_refs_merge() {
|
|||
tx2.commit();
|
||||
|
||||
// Reload the repo, causing the operations to be merged.
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
repo = repo.reload().unwrap();
|
||||
|
||||
let view = repo.view();
|
||||
let git_refs = view.git_refs();
|
||||
|
@ -367,11 +367,11 @@ fn set_up_push_repos(settings: &UserSettings, temp_dir: &TempDir) -> PushTestSet
|
|||
let initial_commit_id = commit_id(&initial_git_commit);
|
||||
git2::Repository::clone(&source_repo_dir.to_str().unwrap(), &clone_repo_dir).unwrap();
|
||||
std::fs::create_dir(&jj_repo_dir).unwrap();
|
||||
let mut jj_repo = ReadonlyRepo::init_external_git(&settings, jj_repo_dir, clone_repo_dir);
|
||||
let jj_repo = ReadonlyRepo::init_external_git(&settings, jj_repo_dir, clone_repo_dir);
|
||||
let new_commit = testutils::create_random_commit(&settings, &jj_repo)
|
||||
.set_parents(vec![initial_commit_id])
|
||||
.write_to_new_transaction(&jj_repo, "test");
|
||||
Arc::get_mut(&mut jj_repo).unwrap().reload();
|
||||
let jj_repo = jj_repo.reload().unwrap();
|
||||
PushTestSetup {
|
||||
source_repo_dir,
|
||||
jj_repo,
|
||||
|
@ -414,7 +414,7 @@ fn test_push_commit_not_fast_forward() {
|
|||
let mut setup = set_up_push_repos(&settings, &temp_dir);
|
||||
let new_commit = testutils::create_random_commit(&settings, &setup.jj_repo)
|
||||
.write_to_new_transaction(&setup.jj_repo, "test");
|
||||
Arc::get_mut(&mut setup.jj_repo).unwrap().reload();
|
||||
setup.jj_repo = setup.jj_repo.reload().unwrap();
|
||||
let result = git::push_commit(
|
||||
&setup.jj_repo.store().git_repo().unwrap(),
|
||||
&new_commit,
|
||||
|
|
|
@ -93,7 +93,7 @@ fn test_index_commits_standard_cases(use_git: bool) {
|
|||
let commit_g = child_commit(&settings, &repo, &commit_f).write_to_repo(tx.mut_repo());
|
||||
let commit_h = child_commit(&settings, &repo, &commit_e).write_to_repo(tx.mut_repo());
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
repo = repo.reload().unwrap();
|
||||
|
||||
let index = repo.index();
|
||||
// There should be the root commit and the working copy commit, plus
|
||||
|
@ -165,7 +165,7 @@ fn test_index_commits_criss_cross(use_git: bool) {
|
|||
right_commits.push(new_right);
|
||||
}
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
repo = repo.reload().unwrap();
|
||||
|
||||
let index = repo.index();
|
||||
// There should the root commit and the working copy commit, plus 2 for each
|
||||
|
@ -263,12 +263,12 @@ fn test_index_commits_previous_operations(use_git: bool) {
|
|||
let commit_b = child_commit(&settings, &repo, &commit_a).write_to_repo(tx.mut_repo());
|
||||
let commit_c = child_commit(&settings, &repo, &commit_b).write_to_repo(tx.mut_repo());
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
repo = repo.reload().unwrap();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
tx.mut_repo().remove_head(&commit_c);
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
repo = repo.reload().unwrap();
|
||||
|
||||
// Delete index from disk
|
||||
let index_operations_dir = repo
|
||||
|
@ -314,7 +314,7 @@ fn test_index_commits_incremental(use_git: bool) {
|
|||
let root_commit = repo.store().root_commit();
|
||||
let commit_a =
|
||||
child_commit(&settings, &repo, &root_commit).write_to_new_transaction(&repo, "test");
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
repo = repo.reload().unwrap();
|
||||
|
||||
let index = repo.index();
|
||||
// There should be the root commit and the working copy commit, plus
|
||||
|
@ -361,7 +361,7 @@ fn test_index_commits_incremental_empty_transaction(use_git: bool) {
|
|||
let root_commit = repo.store().root_commit();
|
||||
let commit_a =
|
||||
child_commit(&settings, &repo, &root_commit).write_to_new_transaction(&repo, "test");
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
repo = repo.reload().unwrap();
|
||||
|
||||
let index = repo.index();
|
||||
// There should be the root commit and the working copy commit, plus
|
||||
|
@ -405,7 +405,7 @@ fn test_index_commits_incremental_already_indexed(use_git: bool) {
|
|||
let root_commit = repo.store().root_commit();
|
||||
let commit_a =
|
||||
child_commit(&settings, &repo, &root_commit).write_to_new_transaction(&repo, "test");
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
repo = repo.reload().unwrap();
|
||||
|
||||
assert!(repo.index().has_id(commit_a.id()));
|
||||
assert_eq!(repo.index().num_commits(), 2 + 1);
|
||||
|
@ -416,13 +416,18 @@ fn test_index_commits_incremental_already_indexed(use_git: bool) {
|
|||
tx.discard();
|
||||
}
|
||||
|
||||
fn create_n_commits(settings: &UserSettings, repo: &mut Arc<ReadonlyRepo>, num_commits: i32) {
|
||||
#[must_use]
|
||||
fn create_n_commits(
|
||||
settings: &UserSettings,
|
||||
repo: &Arc<ReadonlyRepo>,
|
||||
num_commits: i32,
|
||||
) -> Arc<ReadonlyRepo> {
|
||||
let mut tx = repo.start_transaction("test");
|
||||
for _ in 0..num_commits {
|
||||
create_random_commit(settings, repo).write_to_repo(tx.mut_repo());
|
||||
}
|
||||
tx.commit();
|
||||
Arc::get_mut(repo).unwrap().reload();
|
||||
repo.reload().unwrap()
|
||||
}
|
||||
|
||||
fn commits_by_level(repo: &ReadonlyRepo) -> Vec<u32> {
|
||||
|
@ -440,44 +445,44 @@ fn test_index_commits_incremental_squashed(use_git: bool) {
|
|||
let settings = testutils::user_settings();
|
||||
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
create_n_commits(&settings, &mut repo, 1);
|
||||
repo = create_n_commits(&settings, &repo, 1);
|
||||
assert_eq!(commits_by_level(&repo), vec![2, 1]);
|
||||
create_n_commits(&settings, &mut repo, 1);
|
||||
repo = create_n_commits(&settings, &repo, 1);
|
||||
assert_eq!(commits_by_level(&repo), vec![4]);
|
||||
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
create_n_commits(&settings, &mut repo, 2);
|
||||
repo = create_n_commits(&settings, &repo, 2);
|
||||
assert_eq!(commits_by_level(&repo), vec![4]);
|
||||
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
create_n_commits(&settings, &mut repo, 100);
|
||||
repo = create_n_commits(&settings, &repo, 100);
|
||||
assert_eq!(commits_by_level(&repo), vec![102]);
|
||||
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
create_n_commits(&settings, &mut repo, 2);
|
||||
create_n_commits(&settings, &mut repo, 4);
|
||||
create_n_commits(&settings, &mut repo, 8);
|
||||
create_n_commits(&settings, &mut repo, 16);
|
||||
create_n_commits(&settings, &mut repo, 32);
|
||||
repo = create_n_commits(&settings, &repo, 2);
|
||||
repo = create_n_commits(&settings, &repo, 4);
|
||||
repo = create_n_commits(&settings, &repo, 8);
|
||||
repo = create_n_commits(&settings, &repo, 16);
|
||||
repo = create_n_commits(&settings, &repo, 32);
|
||||
assert_eq!(commits_by_level(&repo), vec![64]);
|
||||
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
create_n_commits(&settings, &mut repo, 32);
|
||||
create_n_commits(&settings, &mut repo, 16);
|
||||
create_n_commits(&settings, &mut repo, 8);
|
||||
create_n_commits(&settings, &mut repo, 4);
|
||||
create_n_commits(&settings, &mut repo, 2);
|
||||
repo = create_n_commits(&settings, &repo, 32);
|
||||
repo = create_n_commits(&settings, &repo, 16);
|
||||
repo = create_n_commits(&settings, &repo, 8);
|
||||
repo = create_n_commits(&settings, &repo, 4);
|
||||
repo = create_n_commits(&settings, &repo, 2);
|
||||
assert_eq!(commits_by_level(&repo), vec![34, 16, 8, 4, 2]);
|
||||
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
create_n_commits(&settings, &mut repo, 10);
|
||||
create_n_commits(&settings, &mut repo, 10);
|
||||
create_n_commits(&settings, &mut repo, 10);
|
||||
create_n_commits(&settings, &mut repo, 10);
|
||||
create_n_commits(&settings, &mut repo, 10);
|
||||
create_n_commits(&settings, &mut repo, 10);
|
||||
create_n_commits(&settings, &mut repo, 10);
|
||||
create_n_commits(&settings, &mut repo, 10);
|
||||
create_n_commits(&settings, &mut repo, 10);
|
||||
repo = create_n_commits(&settings, &repo, 10);
|
||||
repo = create_n_commits(&settings, &repo, 10);
|
||||
repo = create_n_commits(&settings, &repo, 10);
|
||||
repo = create_n_commits(&settings, &repo, 10);
|
||||
repo = create_n_commits(&settings, &repo, 10);
|
||||
repo = create_n_commits(&settings, &repo, 10);
|
||||
repo = create_n_commits(&settings, &repo, 10);
|
||||
repo = create_n_commits(&settings, &repo, 10);
|
||||
repo = create_n_commits(&settings, &repo, 10);
|
||||
assert_eq!(commits_by_level(&repo), vec![72, 20]);
|
||||
}
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use jujube_lib::repo::{ReadonlyRepo, RepoLoadError, RepoLoader};
|
||||
use jujube_lib::testutils;
|
||||
use test_case::test_case;
|
||||
|
@ -37,7 +35,7 @@ fn test_load_at_operation(use_git: bool) {
|
|||
let mut tx = repo.start_transaction("add commit");
|
||||
let commit = testutils::create_random_commit(&settings, &repo).write_to_repo(tx.mut_repo());
|
||||
let op = tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
repo = repo.reload().unwrap();
|
||||
|
||||
let mut tx = repo.start_transaction("remove commit");
|
||||
tx.mut_repo().remove_head(&commit);
|
||||
|
|
|
@ -29,20 +29,20 @@ use test_case::test_case;
|
|||
fn test_checkout_open(use_git: bool) {
|
||||
// Test that MutableRepo::check_out() uses the requested commit if it's open
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let requested_checkout = testutils::create_random_commit(&settings, &repo)
|
||||
.set_open(true)
|
||||
.write_to_repo(tx.mut_repo());
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let actual_checkout = tx.mut_repo().check_out(&settings, &requested_checkout);
|
||||
assert_eq!(actual_checkout.id(), requested_checkout.id());
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
assert_eq!(repo.view().checkout(), actual_checkout.id());
|
||||
}
|
||||
|
||||
|
@ -52,14 +52,14 @@ fn test_checkout_closed(use_git: bool) {
|
|||
// Test that MutableRepo::check_out() creates a child if the requested commit is
|
||||
// closed
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let requested_checkout = testutils::create_random_commit(&settings, &repo)
|
||||
.set_open(false)
|
||||
.write_to_repo(tx.mut_repo());
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let actual_checkout = tx.mut_repo().check_out(&settings, &requested_checkout);
|
||||
|
@ -67,7 +67,7 @@ fn test_checkout_closed(use_git: bool) {
|
|||
assert_eq!(actual_checkout.parents().len(), 1);
|
||||
assert_eq!(actual_checkout.parents()[0].id(), requested_checkout.id());
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
assert_eq!(repo.view().checkout(), actual_checkout.id());
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ fn test_checkout_open_with_conflict(use_git: bool) {
|
|||
// Test that MutableRepo::check_out() creates a child if the requested
|
||||
// commit is open and has conflicts
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
let store = repo.store();
|
||||
|
||||
let file_path = FileRepoPath::from("file");
|
||||
|
@ -93,7 +93,7 @@ fn test_checkout_open_with_conflict(use_git: bool) {
|
|||
.set_open(true)
|
||||
.write_to_repo(tx.mut_repo());
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let actual_checkout = tx.mut_repo().check_out(&settings, &requested_checkout);
|
||||
|
@ -108,7 +108,7 @@ fn test_checkout_open_with_conflict(use_git: bool) {
|
|||
assert_eq!(actual_checkout.parents().len(), 1);
|
||||
assert_eq!(actual_checkout.parents()[0].id(), requested_checkout.id());
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
assert_eq!(repo.view().checkout(), actual_checkout.id());
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ fn test_checkout_closed_with_conflict(use_git: bool) {
|
|||
// Test that MutableRepo::check_out() creates a child if the requested commit is
|
||||
// closed and has conflicts
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
let store = repo.store();
|
||||
|
||||
let file_path = FileRepoPath::from("file");
|
||||
|
@ -134,7 +134,7 @@ fn test_checkout_closed_with_conflict(use_git: bool) {
|
|||
.set_open(false)
|
||||
.write_to_repo(tx.mut_repo());
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let actual_checkout = tx.mut_repo().check_out(&settings, &requested_checkout);
|
||||
|
@ -149,7 +149,7 @@ fn test_checkout_closed_with_conflict(use_git: bool) {
|
|||
assert_eq!(actual_checkout.parents().len(), 1);
|
||||
assert_eq!(actual_checkout.parents()[0].id(), requested_checkout.id());
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
assert_eq!(repo.view().checkout(), actual_checkout.id());
|
||||
}
|
||||
|
||||
|
@ -188,7 +188,7 @@ fn test_checkout_previous_not_empty(use_git: bool) {
|
|||
// Test that MutableRepo::check_out() does not usually prune the previous
|
||||
// commit.
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let mut_repo = tx.mut_repo();
|
||||
|
@ -197,7 +197,7 @@ fn test_checkout_previous_not_empty(use_git: bool) {
|
|||
.write_to_repo(mut_repo);
|
||||
mut_repo.check_out(&settings, &old_checkout);
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let mut_repo = tx.mut_repo();
|
||||
|
@ -215,7 +215,7 @@ fn test_checkout_previous_empty(use_git: bool) {
|
|||
// Test that MutableRepo::check_out() prunes the previous commit if it was
|
||||
// empty.
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let mut_repo = tx.mut_repo();
|
||||
|
@ -228,7 +228,7 @@ fn test_checkout_previous_empty(use_git: bool) {
|
|||
.write_to_repo(mut_repo);
|
||||
mut_repo.check_out(&settings, &old_checkout);
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let mut_repo = tx.mut_repo();
|
||||
|
@ -246,7 +246,7 @@ fn test_checkout_previous_empty_and_obsolete(use_git: bool) {
|
|||
// Test that MutableRepo::check_out() does not unnecessarily prune the previous
|
||||
// commit if it was empty but already obsolete.
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let mut_repo = tx.mut_repo();
|
||||
|
@ -261,7 +261,7 @@ fn test_checkout_previous_empty_and_obsolete(use_git: bool) {
|
|||
.write_to_repo(mut_repo);
|
||||
mut_repo.check_out(&settings, &old_checkout);
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let mut_repo = tx.mut_repo();
|
||||
|
@ -281,7 +281,7 @@ fn test_checkout_previous_empty_and_pruned(use_git: bool) {
|
|||
// Test that MutableRepo::check_out() does not unnecessarily prune the previous
|
||||
// commit if it was empty but already obsolete.
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let mut_repo = tx.mut_repo();
|
||||
|
@ -291,7 +291,7 @@ fn test_checkout_previous_empty_and_pruned(use_git: bool) {
|
|||
.write_to_repo(mut_repo);
|
||||
mut_repo.check_out(&settings, &old_checkout);
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let mut_repo = tx.mut_repo();
|
||||
|
@ -312,7 +312,7 @@ fn test_add_head_success(use_git: bool) {
|
|||
// Test that MutableRepo::add_head() adds the head, and that it's still there
|
||||
// after commit. It should also be indexed.
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
// Create a commit outside of the repo by using a temporary transaction. Then
|
||||
// add that as a head.
|
||||
|
@ -332,7 +332,7 @@ fn test_add_head_success(use_git: bool) {
|
|||
assert!(mut_repo.view().heads().contains(new_commit.id()));
|
||||
assert!(mut_repo.index().has_id(new_commit.id()));
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
assert!(repo.view().heads().contains(new_commit.id()));
|
||||
assert!(repo.index().has_id(new_commit.id()));
|
||||
let index_stats = repo.index().stats();
|
||||
|
@ -347,7 +347,7 @@ fn test_add_head_ancestor(use_git: bool) {
|
|||
// Test that MutableRepo::add_head() does not add a head if it's an ancestor of
|
||||
// an existing head.
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let commit1 = testutils::create_random_commit(&settings, &repo).write_to_repo(tx.mut_repo());
|
||||
|
@ -358,7 +358,7 @@ fn test_add_head_ancestor(use_git: bool) {
|
|||
.set_parents(vec![commit2.id().clone()])
|
||||
.write_to_repo(tx.mut_repo());
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
|
||||
let index_stats = repo.index().stats();
|
||||
assert_eq!(index_stats.num_heads, 2);
|
||||
|
@ -381,12 +381,12 @@ fn test_add_head_not_immediate_child(use_git: bool) {
|
|||
// Test that MutableRepo::add_head() can be used for adding a head that is not
|
||||
// an immediate child of a current head.
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let initial = testutils::create_random_commit(&settings, &repo).write_to_repo(tx.mut_repo());
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
|
||||
// Create some commit outside of the repo by using a temporary transaction. Then
|
||||
// add one of them as a head.
|
||||
|
@ -432,7 +432,7 @@ fn test_remove_head(use_git: bool) {
|
|||
// for commits no longer visible in that case so we don't have to reindex e.g.
|
||||
// when the user does `jj op undo`.
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let commit1 = testutils::create_random_commit(&settings, &repo).write_to_repo(tx.mut_repo());
|
||||
|
@ -443,7 +443,7 @@ fn test_remove_head(use_git: bool) {
|
|||
.set_parents(vec![commit2.id().clone()])
|
||||
.write_to_repo(tx.mut_repo());
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let mut_repo = tx.mut_repo();
|
||||
|
@ -458,7 +458,7 @@ fn test_remove_head(use_git: bool) {
|
|||
assert!(mut_repo.index().has_id(commit3.id()));
|
||||
tx.commit();
|
||||
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
let heads = repo.view().heads().clone();
|
||||
assert!(!heads.contains(commit3.id()));
|
||||
assert!(!heads.contains(commit2.id()));
|
||||
|
@ -474,7 +474,7 @@ fn test_remove_head_ancestor_git_ref(use_git: bool) {
|
|||
// Test that MutableRepo::remove_head() does not leave the view with a git ref
|
||||
// pointing to a commit that's not reachable by any head.
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let mut_repo = tx.mut_repo();
|
||||
|
@ -487,7 +487,7 @@ fn test_remove_head_ancestor_git_ref(use_git: bool) {
|
|||
.write_to_repo(mut_repo);
|
||||
mut_repo.insert_git_ref("refs/heads/main".to_string(), commit1.id().clone());
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let mut_repo = tx.mut_repo();
|
||||
|
@ -500,7 +500,7 @@ fn test_remove_head_ancestor_git_ref(use_git: bool) {
|
|||
assert!(heads.contains(commit1.id()));
|
||||
tx.commit();
|
||||
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
let heads = repo.view().heads().clone();
|
||||
assert!(!heads.contains(commit3.id()));
|
||||
assert!(!heads.contains(commit2.id()));
|
||||
|
@ -513,12 +513,12 @@ fn test_add_public_head(use_git: bool) {
|
|||
// Test that MutableRepo::add_public_head() adds the head, and that it's still
|
||||
// there after commit.
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let commit1 = testutils::create_random_commit(&settings, &repo).write_to_repo(tx.mut_repo());
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let mut_repo = tx.mut_repo();
|
||||
|
@ -526,7 +526,7 @@ fn test_add_public_head(use_git: bool) {
|
|||
mut_repo.add_public_head(&commit1);
|
||||
assert!(mut_repo.view().public_heads().contains(commit1.id()));
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
assert!(repo.view().public_heads().contains(commit1.id()));
|
||||
}
|
||||
|
||||
|
@ -536,7 +536,7 @@ fn test_add_public_head_ancestor(use_git: bool) {
|
|||
// Test that MutableRepo::add_public_head() does not add a public head if it's
|
||||
// an ancestor of an existing public head.
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let mut_repo = tx.mut_repo();
|
||||
|
@ -546,7 +546,7 @@ fn test_add_public_head_ancestor(use_git: bool) {
|
|||
.write_to_repo(mut_repo);
|
||||
mut_repo.add_public_head(&commit2);
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let mut_repo = tx.mut_repo();
|
||||
|
@ -554,7 +554,7 @@ fn test_add_public_head_ancestor(use_git: bool) {
|
|||
mut_repo.add_public_head(&commit1);
|
||||
assert!(!mut_repo.view().public_heads().contains(commit1.id()));
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
assert!(!repo.view().public_heads().contains(commit1.id()));
|
||||
}
|
||||
|
||||
|
@ -564,14 +564,14 @@ fn test_remove_public_head(use_git: bool) {
|
|||
// Test that MutableRepo::remove_public_head() removes the head, and that it's
|
||||
// still removed after commit.
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let mut_repo = tx.mut_repo();
|
||||
let commit1 = testutils::create_random_commit(&settings, &repo).write_to_repo(mut_repo);
|
||||
mut_repo.add_public_head(&commit1);
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let mut_repo = tx.mut_repo();
|
||||
|
@ -579,6 +579,6 @@ fn test_remove_public_head(use_git: bool) {
|
|||
mut_repo.remove_public_head(&commit1);
|
||||
assert!(!mut_repo.view().public_heads().contains(commit1.id()));
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
assert!(!repo.view().public_heads().contains(commit1.id()));
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
// limitations under the License.
|
||||
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use jujube_lib::commit_builder::CommitBuilder;
|
||||
use jujube_lib::repo::RepoRef;
|
||||
|
@ -55,7 +54,7 @@ fn test_consecutive_operations(use_git: bool) {
|
|||
// Test that consecutive operations result in a single op-head on disk after
|
||||
// each operation
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let op_heads_dir = repo.repo_path().join("op_heads");
|
||||
let op_id0 = repo.op_id().clone();
|
||||
|
@ -67,7 +66,7 @@ fn test_consecutive_operations(use_git: bool) {
|
|||
assert_ne!(op_id1, op_id0);
|
||||
assert_eq!(list_dir(&op_heads_dir), vec![op_id1.hex()]);
|
||||
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
let mut tx2 = repo.start_transaction("transaction 2");
|
||||
testutils::create_random_commit(&settings, &repo).write_to_repo(tx2.mut_repo());
|
||||
let op_id2 = tx2.commit().id().clone();
|
||||
|
@ -77,7 +76,7 @@ fn test_consecutive_operations(use_git: bool) {
|
|||
|
||||
// Reloading the repo makes no difference (there are no conflicting operations
|
||||
// to resolve).
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let _repo = repo.reload().unwrap();
|
||||
assert_eq!(list_dir(&op_heads_dir), vec![op_id2.hex()]);
|
||||
}
|
||||
|
||||
|
@ -87,7 +86,7 @@ fn test_concurrent_operations(use_git: bool) {
|
|||
// Test that consecutive operations result in multiple op-heads on disk until
|
||||
// the repo has been reloaded (which currently happens right away).
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let op_heads_dir = repo.repo_path().join("op_heads");
|
||||
let op_id0 = repo.op_id().clone();
|
||||
|
@ -113,7 +112,7 @@ fn test_concurrent_operations(use_git: bool) {
|
|||
assert_eq!(actual_heads_on_disk, expected_heads_on_disk);
|
||||
|
||||
// Reloading the repo causes the operations to be merged
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
let merged_op_id = repo.op_id().clone();
|
||||
assert_ne!(merged_op_id, op_id0);
|
||||
assert_ne!(merged_op_id, op_id1);
|
||||
|
@ -131,13 +130,13 @@ fn assert_heads(repo: RepoRef, expected: Vec<&CommitId>) {
|
|||
fn test_isolation(use_git: bool) {
|
||||
// Test that two concurrent transactions don't see each other's changes.
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let wc_id = repo.working_copy_locked().current_commit_id();
|
||||
let initial = testutils::create_random_commit(&settings, &repo)
|
||||
.set_parents(vec![repo.store().root_commit_id().clone()])
|
||||
.write_to_new_transaction(&repo, "test");
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
|
||||
let mut tx1 = repo.start_transaction("transaction 1");
|
||||
let mut_repo1 = tx1.mut_repo();
|
||||
|
@ -185,7 +184,7 @@ fn test_isolation(use_git: bool) {
|
|||
tx2.commit();
|
||||
assert_heads(repo.as_repo_ref(), vec![&wc_id, initial.id()]);
|
||||
// After reload, the base repo sees both rewrites.
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
let repo = repo.reload().unwrap();
|
||||
assert_heads(
|
||||
repo.as_repo_ref(),
|
||||
vec![&wc_id, initial.id(), rewrite1.id(), rewrite2.id()],
|
||||
|
|
|
@ -16,7 +16,6 @@ use std::fs::OpenOptions;
|
|||
use std::io::Write;
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
use std::sync::Arc;
|
||||
|
||||
use jujube_lib::commit_builder::CommitBuilder;
|
||||
use jujube_lib::repo::ReadonlyRepo;
|
||||
|
@ -31,13 +30,13 @@ use test_case::test_case;
|
|||
#[test_case(true ; "git store")]
|
||||
fn test_root(use_git: bool) {
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let wc = owned_wc.lock().unwrap();
|
||||
assert_eq!(&wc.current_commit_id(), repo.view().checkout());
|
||||
assert_ne!(&wc.current_commit_id(), repo.store().root_commit_id());
|
||||
let wc_commit = wc.commit(&settings, Arc::get_mut(&mut repo).unwrap());
|
||||
let (repo, wc_commit) = wc.commit(&settings, repo);
|
||||
assert_eq!(wc_commit.id(), repo.view().checkout());
|
||||
assert_eq!(wc_commit.tree().id(), repo.store().empty_tree_id());
|
||||
assert_eq!(wc_commit.store_commit().parents, vec![]);
|
||||
|
@ -175,11 +174,12 @@ fn test_checkout_file_transitions(use_git: bool) {
|
|||
let owned_wc = repo.working_copy().clone();
|
||||
let wc = owned_wc.lock().unwrap();
|
||||
wc.check_out(left_commit).unwrap();
|
||||
wc.commit(&settings, Arc::get_mut(&mut repo).unwrap());
|
||||
repo = wc.commit(&settings, repo).0;
|
||||
wc.check_out(right_commit.clone()).unwrap();
|
||||
|
||||
// Check that the working copy is clean.
|
||||
let after_commit = wc.commit(&settings, Arc::get_mut(&mut repo).unwrap());
|
||||
let (reloaded_repo, after_commit) = wc.commit(&settings, repo);
|
||||
repo = reloaded_repo;
|
||||
let diff_summary = right_commit.tree().diff_summary(&after_commit.tree());
|
||||
assert_eq!(diff_summary.modified, vec![]);
|
||||
assert_eq!(diff_summary.added, vec![]);
|
||||
|
@ -262,7 +262,8 @@ fn test_commit_racy_timestamps(use_git: bool) {
|
|||
file.write_all(format!("contents {}", i).as_bytes())
|
||||
.unwrap();
|
||||
}
|
||||
let commit = wc.commit(&settings, Arc::get_mut(&mut repo).unwrap());
|
||||
let (reloaded_repo, commit) = wc.commit(&settings, repo);
|
||||
repo = reloaded_repo;
|
||||
let new_tree_id = commit.tree().id().clone();
|
||||
assert_ne!(new_tree_id, previous_tree_id);
|
||||
previous_tree_id = new_tree_id;
|
||||
|
@ -276,7 +277,7 @@ fn test_gitignores(use_git: bool) {
|
|||
|
||||
let _home_dir = testutils::new_user_home();
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let gitignore_path = FileRepoPath::from(".gitignore");
|
||||
let added_path = FileRepoPath::from("added");
|
||||
|
@ -293,10 +294,7 @@ fn test_gitignores(use_git: bool) {
|
|||
testutils::write_working_copy_file(&repo, &subdir_modified_path, "1");
|
||||
|
||||
let wc = repo.working_copy().clone();
|
||||
let commit1 = wc
|
||||
.lock()
|
||||
.unwrap()
|
||||
.commit(&settings, Arc::get_mut(&mut repo).unwrap());
|
||||
let (repo, commit1) = wc.lock().unwrap().commit(&settings, repo);
|
||||
let files1: Vec<_> = commit1
|
||||
.tree()
|
||||
.entries()
|
||||
|
@ -325,10 +323,7 @@ fn test_gitignores(use_git: bool) {
|
|||
testutils::write_working_copy_file(&repo, &subdir_ignored_path, "2");
|
||||
|
||||
let wc = repo.working_copy().clone();
|
||||
let commit2 = wc
|
||||
.lock()
|
||||
.unwrap()
|
||||
.commit(&settings, Arc::get_mut(&mut repo).unwrap());
|
||||
let (_repo, commit2) = wc.lock().unwrap().commit(&settings, repo);
|
||||
let files2: Vec<_> = commit2
|
||||
.tree()
|
||||
.entries()
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
// limitations under the License.
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
|
||||
use jujube_lib::commit_builder::CommitBuilder;
|
||||
|
@ -74,25 +73,25 @@ fn test_concurrent_commit(use_git: bool) {
|
|||
// instead of divergence.
|
||||
let _home_dir = testutils::new_user_home();
|
||||
let settings = testutils::user_settings();
|
||||
let (_temp_dir, mut repo1) = testutils::init_repo(&settings, use_git);
|
||||
let (_temp_dir, repo1) = testutils::init_repo(&settings, use_git);
|
||||
|
||||
let owned_wc1 = repo1.working_copy().clone();
|
||||
let wc1 = owned_wc1.lock().unwrap();
|
||||
let commit1 = wc1.current_commit();
|
||||
|
||||
// Commit from another process (simulated by another repo instance)
|
||||
let mut repo2 = ReadonlyRepo::load(&settings, repo1.working_copy_path().clone()).unwrap();
|
||||
let repo2 = ReadonlyRepo::load(&settings, repo1.working_copy_path().clone()).unwrap();
|
||||
testutils::write_working_copy_file(&repo2, &FileRepoPath::from("file2"), "contents2");
|
||||
let owned_wc2 = repo2.working_copy().clone();
|
||||
let wc2 = owned_wc2.lock().unwrap();
|
||||
let commit2 = wc2.commit(&settings, Arc::get_mut(&mut repo2).unwrap());
|
||||
let commit2 = wc2.commit(&settings, repo2).1;
|
||||
|
||||
assert_eq!(commit2.predecessors(), vec![commit1]);
|
||||
|
||||
// Creating another commit (via the first repo instance) should result in a
|
||||
// successor of the commit created from the other process.
|
||||
testutils::write_working_copy_file(&repo1, &FileRepoPath::from("file3"), "contents3");
|
||||
let commit3 = wc1.commit(&settings, Arc::get_mut(&mut repo1).unwrap());
|
||||
let commit3 = wc1.commit(&settings, repo1).1;
|
||||
assert_eq!(commit3.predecessors(), vec![commit2]);
|
||||
}
|
||||
|
||||
|
@ -133,7 +132,7 @@ fn test_checkout_parallel(use_git: bool) {
|
|||
let settings = settings.clone();
|
||||
let working_copy_path = repo.working_copy_path().clone();
|
||||
let handle = thread::spawn(move || {
|
||||
let mut repo = ReadonlyRepo::load(&settings, working_copy_path).unwrap();
|
||||
let repo = ReadonlyRepo::load(&settings, working_copy_path).unwrap();
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let wc = owned_wc.lock().unwrap();
|
||||
let commit = repo.store().get_commit(&commit_id).unwrap();
|
||||
|
@ -145,7 +144,7 @@ fn test_checkout_parallel(use_git: bool) {
|
|||
// different commit than the one we just checked out, but since
|
||||
// commit() should take the same lock as check_out(), commit()
|
||||
// should never produce a different tree (resulting in a different commit).
|
||||
let commit_after = wc.commit(&settings, Arc::get_mut(&mut repo).unwrap());
|
||||
let commit_after = wc.commit(&settings, repo).1;
|
||||
assert!(commit_ids_set.contains(commit_after.id()));
|
||||
});
|
||||
threads.push(handle);
|
||||
|
|
323
src/commands.rs
323
src/commands.rs
|
@ -114,34 +114,35 @@ fn get_repo(ui: &Ui, matches: &ArgMatches) -> Result<Arc<ReadonlyRepo>, CommandE
|
|||
|
||||
fn resolve_revision_arg(
|
||||
ui: &Ui,
|
||||
repo: &mut ReadonlyRepo,
|
||||
repo: Arc<ReadonlyRepo>,
|
||||
matches: &ArgMatches,
|
||||
) -> Result<Commit, CommandError> {
|
||||
) -> Result<(Arc<ReadonlyRepo>, Commit), CommandError> {
|
||||
resolve_single_rev(ui, repo, matches.value_of("revision").unwrap())
|
||||
}
|
||||
|
||||
fn resolve_single_rev(
|
||||
ui: &Ui,
|
||||
repo: &mut ReadonlyRepo,
|
||||
mut repo: Arc<ReadonlyRepo>,
|
||||
revision_str: &str,
|
||||
) -> Result<Commit, CommandError> {
|
||||
) -> Result<(Arc<ReadonlyRepo>, Commit), CommandError> {
|
||||
// If we're looking up the working copy commit ("@"), make sure that it is up to
|
||||
// date (the lib crate only looks at the checkout in the view).
|
||||
if revision_str == "@" {
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
// TODO: Avoid committing every time this function is called.
|
||||
owned_wc.lock().unwrap().commit(ui.settings(), repo);
|
||||
let (reloaded_repo, _) = owned_wc.lock().unwrap().commit(ui.settings(), repo.clone());
|
||||
repo = reloaded_repo;
|
||||
}
|
||||
|
||||
if revision_str == "@^" {
|
||||
let commit = repo.store().get_commit(repo.view().checkout()).unwrap();
|
||||
assert!(commit.is_open());
|
||||
let parents = commit.parents();
|
||||
Ok(parents[0].clone())
|
||||
Ok((repo, parents[0].clone()))
|
||||
} else if revision_str.starts_with("desc(") && revision_str.ends_with(')') {
|
||||
let needle = revision_str[5..revision_str.len() - 1].to_string();
|
||||
let mut matches = vec![];
|
||||
let head_ids = skip_uninteresting_heads(repo, &repo.view().heads());
|
||||
let head_ids = skip_uninteresting_heads(repo.as_ref(), &repo.view().heads());
|
||||
let heads: Vec<_> = head_ids
|
||||
.iter()
|
||||
.map(|id| repo.store().get_commit(&id).unwrap())
|
||||
|
@ -151,11 +152,15 @@ fn resolve_single_rev(
|
|||
matches.push(commit);
|
||||
}
|
||||
}
|
||||
matches
|
||||
.pop()
|
||||
.ok_or_else(|| CommandError::UserError(String::from("No matching commit")))
|
||||
match matches.pop() {
|
||||
None => Err(CommandError::UserError(String::from("No matching commit"))),
|
||||
Some(commit) => Ok((repo, commit)),
|
||||
}
|
||||
} else {
|
||||
Ok(revset::resolve_symbol(repo.as_repo_ref(), revision_str)?)
|
||||
Ok((
|
||||
repo.clone(),
|
||||
revset::resolve_symbol(repo.as_repo_ref(), revision_str)?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,10 +223,10 @@ fn resolve_single_op_from_store(
|
|||
|
||||
fn update_working_copy(
|
||||
ui: &mut Ui,
|
||||
repo: &mut ReadonlyRepo,
|
||||
repo: &Arc<ReadonlyRepo>,
|
||||
wc: &WorkingCopy,
|
||||
) -> Result<Option<CheckoutStats>, CommandError> {
|
||||
repo.reload();
|
||||
let repo = repo.reload()?;
|
||||
let old_commit = wc.current_commit();
|
||||
let new_commit = repo.store().get_commit(repo.view().checkout()).unwrap();
|
||||
if old_commit == new_commit {
|
||||
|
@ -627,16 +632,15 @@ fn cmd_checkout(
|
|||
matches: &ArgMatches,
|
||||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let new_commit = resolve_revision_arg(ui, mut_repo, sub_matches)?;
|
||||
let (repo, new_commit) = resolve_revision_arg(ui, repo, sub_matches)?;
|
||||
let wc = owned_wc.lock().unwrap();
|
||||
wc.commit(ui.settings(), mut_repo);
|
||||
let (repo, _) = wc.commit(ui.settings(), repo);
|
||||
let mut tx = repo.start_transaction(&format!("check out commit {}", new_commit.id().hex()));
|
||||
tx.mut_repo().check_out(ui.settings(), &new_commit);
|
||||
tx.commit();
|
||||
let stats = update_working_copy(ui, Arc::get_mut(&mut repo).unwrap(), &wc)?;
|
||||
let stats = update_working_copy(ui, &repo, &wc)?;
|
||||
match stats {
|
||||
None => ui.write("already on that commit\n")?,
|
||||
Some(stats) => writeln!(
|
||||
|
@ -653,9 +657,8 @@ fn cmd_files(
|
|||
matches: &ArgMatches,
|
||||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let commit = resolve_revision_arg(ui, mut_repo, sub_matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let (_repo, commit) = resolve_revision_arg(ui, repo, sub_matches)?;
|
||||
for (name, _value) in commit.tree().entries() {
|
||||
writeln!(ui, "{}", name.to_internal_string())?;
|
||||
}
|
||||
|
@ -760,20 +763,20 @@ fn cmd_diff(
|
|||
)));
|
||||
}
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let from_tree;
|
||||
let to_tree;
|
||||
if sub_matches.is_present("from") || sub_matches.is_present("to") {
|
||||
from_tree =
|
||||
resolve_single_rev(ui, mut_repo, sub_matches.value_of("from").unwrap_or("@"))?.tree();
|
||||
to_tree =
|
||||
resolve_single_rev(ui, mut_repo, sub_matches.value_of("to").unwrap_or("@"))?.tree();
|
||||
let (reoaded_repo, from) =
|
||||
resolve_single_rev(ui, repo, sub_matches.value_of("from").unwrap_or("@"))?;
|
||||
from_tree = from.tree();
|
||||
let (reloaded_repo, to) =
|
||||
resolve_single_rev(ui, reoaded_repo, sub_matches.value_of("to").unwrap_or("@"))?;
|
||||
repo = reloaded_repo;
|
||||
to_tree = to.tree();
|
||||
} else {
|
||||
let commit = resolve_single_rev(
|
||||
ui,
|
||||
mut_repo,
|
||||
sub_matches.value_of("revision").unwrap_or("@"),
|
||||
)?;
|
||||
let (reloaded_repo, commit) =
|
||||
resolve_single_rev(ui, repo, sub_matches.value_of("revision").unwrap_or("@"))?;
|
||||
repo = reloaded_repo;
|
||||
let parents = commit.parents();
|
||||
from_tree = merge_commit_trees(repo.as_repo_ref(), &parents);
|
||||
to_tree = commit.tree()
|
||||
|
@ -939,11 +942,10 @@ fn cmd_status(
|
|||
matches: &ArgMatches,
|
||||
_sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let wc = owned_wc.lock().unwrap();
|
||||
let commit = wc.commit(ui.settings(), mut_repo);
|
||||
let (repo, commit) = wc.commit(ui.settings(), repo);
|
||||
ui.write("Working copy : ")?;
|
||||
ui.write_commit_summary(repo.as_repo_ref(), &commit)?;
|
||||
ui.write("\n")?;
|
||||
|
@ -1038,12 +1040,13 @@ fn cmd_log(
|
|||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
|
||||
let use_graph = !sub_matches.is_present("no-graph");
|
||||
if use_graph {
|
||||
// Commit so the latest working copy is reflected in the visible heads
|
||||
owned_wc.lock().unwrap().commit(ui.settings(), mut_repo);
|
||||
// Commit so the latest working copy is reflected in the view's checkout and
|
||||
// visible heads
|
||||
let (reloaded_repo, _wc_commit) = owned_wc.lock().unwrap().commit(ui.settings(), repo);
|
||||
repo = reloaded_repo;
|
||||
}
|
||||
|
||||
let template_string = match sub_matches.value_of("template") {
|
||||
|
@ -1107,11 +1110,10 @@ fn cmd_obslog(
|
|||
matches: &ArgMatches,
|
||||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
|
||||
let use_graph = !sub_matches.is_present("no-graph");
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let start_commit = resolve_revision_arg(ui, mut_repo, sub_matches)?;
|
||||
let (repo, start_commit) = resolve_revision_arg(ui, repo, sub_matches)?;
|
||||
|
||||
let template_string = match sub_matches.value_of("template") {
|
||||
Some(value) => value.to_string(),
|
||||
|
@ -1204,10 +1206,9 @@ fn cmd_describe(
|
|||
matches: &ArgMatches,
|
||||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let commit = resolve_revision_arg(ui, mut_repo, sub_matches)?;
|
||||
let (repo, commit) = resolve_revision_arg(ui, repo, sub_matches)?;
|
||||
let description;
|
||||
if sub_matches.is_present("stdin") {
|
||||
let mut buffer = String::new();
|
||||
|
@ -1224,11 +1225,7 @@ fn cmd_describe(
|
|||
.write_to_repo(tx.mut_repo());
|
||||
update_checkout_after_rewrite(ui, tx.mut_repo())?;
|
||||
tx.commit();
|
||||
update_working_copy(
|
||||
ui,
|
||||
Arc::get_mut(&mut repo).unwrap(),
|
||||
&owned_wc.lock().unwrap(),
|
||||
)?;
|
||||
update_working_copy(ui, &repo, &owned_wc.lock().unwrap())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1237,21 +1234,16 @@ fn cmd_open(
|
|||
matches: &ArgMatches,
|
||||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let commit = resolve_revision_arg(ui, mut_repo, sub_matches)?;
|
||||
let (repo, commit) = resolve_revision_arg(ui, repo, sub_matches)?;
|
||||
let mut tx = repo.start_transaction(&format!("open commit {}", commit.id().hex()));
|
||||
CommitBuilder::for_rewrite_from(ui.settings(), repo.store(), &commit)
|
||||
.set_open(true)
|
||||
.write_to_repo(tx.mut_repo());
|
||||
update_checkout_after_rewrite(ui, tx.mut_repo())?;
|
||||
tx.commit();
|
||||
update_working_copy(
|
||||
ui,
|
||||
Arc::get_mut(&mut repo).unwrap(),
|
||||
&owned_wc.lock().unwrap(),
|
||||
)?;
|
||||
update_working_copy(ui, &repo, &owned_wc.lock().unwrap())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1260,10 +1252,9 @@ fn cmd_close(
|
|||
matches: &ArgMatches,
|
||||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let commit = resolve_revision_arg(ui, mut_repo, sub_matches)?;
|
||||
let (repo, commit) = resolve_revision_arg(ui, repo, sub_matches)?;
|
||||
let mut commit_builder =
|
||||
CommitBuilder::for_rewrite_from(ui.settings(), repo.store(), &commit).set_open(false);
|
||||
let description;
|
||||
|
@ -1279,11 +1270,7 @@ fn cmd_close(
|
|||
commit_builder.write_to_repo(tx.mut_repo());
|
||||
update_checkout_after_rewrite(ui, tx.mut_repo())?;
|
||||
tx.commit();
|
||||
update_working_copy(
|
||||
ui,
|
||||
Arc::get_mut(&mut repo).unwrap(),
|
||||
&owned_wc.lock().unwrap(),
|
||||
)?;
|
||||
update_working_copy(ui, &repo, &owned_wc.lock().unwrap())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1292,9 +1279,8 @@ fn cmd_duplicate(
|
|||
matches: &ArgMatches,
|
||||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let predecessor = resolve_revision_arg(ui, mut_repo, sub_matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let (repo, predecessor) = resolve_revision_arg(ui, repo, sub_matches)?;
|
||||
let mut tx = repo.start_transaction(&format!("duplicate commit {}", predecessor.id().hex()));
|
||||
let mut_repo = tx.mut_repo();
|
||||
let new_commit = CommitBuilder::for_rewrite_from(ui.settings(), repo.store(), &predecessor)
|
||||
|
@ -1312,10 +1298,9 @@ fn cmd_prune(
|
|||
matches: &ArgMatches,
|
||||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let predecessor = resolve_revision_arg(ui, mut_repo, sub_matches)?;
|
||||
let (repo, predecessor) = resolve_revision_arg(ui, repo, sub_matches)?;
|
||||
if predecessor.id() == repo.store().root_commit_id() {
|
||||
return Err(CommandError::UserError(String::from(
|
||||
"Cannot prune the root commit",
|
||||
|
@ -1327,11 +1312,7 @@ fn cmd_prune(
|
|||
.write_to_repo(tx.mut_repo());
|
||||
update_checkout_after_rewrite(ui, tx.mut_repo())?;
|
||||
tx.commit();
|
||||
update_working_copy(
|
||||
ui,
|
||||
Arc::get_mut(&mut repo).unwrap(),
|
||||
&owned_wc.lock().unwrap(),
|
||||
)?;
|
||||
update_working_copy(ui, &repo, &owned_wc.lock().unwrap())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1340,10 +1321,9 @@ fn cmd_new(
|
|||
matches: &ArgMatches,
|
||||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let parent = resolve_revision_arg(ui, mut_repo, sub_matches)?;
|
||||
let (repo, parent) = resolve_revision_arg(ui, repo, sub_matches)?;
|
||||
let commit_builder = CommitBuilder::for_open_commit(
|
||||
ui.settings(),
|
||||
repo.store(),
|
||||
|
@ -1357,11 +1337,7 @@ fn cmd_new(
|
|||
mut_repo.check_out(ui.settings(), &new_commit);
|
||||
}
|
||||
tx.commit();
|
||||
update_working_copy(
|
||||
ui,
|
||||
Arc::get_mut(&mut repo).unwrap(),
|
||||
&owned_wc.lock().unwrap(),
|
||||
)?;
|
||||
update_working_copy(ui, &repo, &owned_wc.lock().unwrap())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1370,10 +1346,9 @@ fn cmd_squash(
|
|||
matches: &ArgMatches,
|
||||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let commit = resolve_revision_arg(ui, mut_repo, sub_matches)?;
|
||||
let (repo, commit) = resolve_revision_arg(ui, repo, sub_matches)?;
|
||||
let parents = commit.parents();
|
||||
if parents.len() != 1 {
|
||||
return Err(CommandError::UserError(String::from(
|
||||
|
@ -1411,11 +1386,7 @@ fn cmd_squash(
|
|||
.write_to_repo(mut_repo);
|
||||
update_checkout_after_rewrite(ui, mut_repo)?;
|
||||
tx.commit();
|
||||
update_working_copy(
|
||||
ui,
|
||||
Arc::get_mut(&mut repo).unwrap(),
|
||||
&owned_wc.lock().unwrap(),
|
||||
)?;
|
||||
update_working_copy(ui, &repo, &owned_wc.lock().unwrap())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1424,10 +1395,9 @@ fn cmd_unsquash(
|
|||
matches: &ArgMatches,
|
||||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let commit = resolve_revision_arg(ui, mut_repo, sub_matches)?;
|
||||
let (repo, commit) = resolve_revision_arg(ui, repo, sub_matches)?;
|
||||
let parents = commit.parents();
|
||||
if parents.len() != 1 {
|
||||
return Err(CommandError::UserError(String::from(
|
||||
|
@ -1466,11 +1436,7 @@ fn cmd_unsquash(
|
|||
.write_to_repo(mut_repo);
|
||||
update_checkout_after_rewrite(ui, mut_repo)?;
|
||||
tx.commit();
|
||||
update_working_copy(
|
||||
ui,
|
||||
Arc::get_mut(&mut repo).unwrap(),
|
||||
&owned_wc.lock().unwrap(),
|
||||
)?;
|
||||
update_working_copy(ui, &repo, &owned_wc.lock().unwrap())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1479,9 +1445,8 @@ fn cmd_discard(
|
|||
matches: &ArgMatches,
|
||||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let commit = resolve_revision_arg(ui, mut_repo, sub_matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let (repo, commit) = resolve_revision_arg(ui, repo, sub_matches)?;
|
||||
let mut tx = repo.start_transaction(&format!("discard commit {}", commit.id().hex()));
|
||||
let mut_repo = tx.mut_repo();
|
||||
mut_repo.remove_head(&commit);
|
||||
|
@ -1499,12 +1464,12 @@ fn cmd_restore(
|
|||
matches: &ArgMatches,
|
||||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let source_commit = resolve_single_rev(ui, mut_repo, sub_matches.value_of("source").unwrap())?;
|
||||
let destination_commit =
|
||||
resolve_single_rev(ui, mut_repo, sub_matches.value_of("destination").unwrap())?;
|
||||
let (repo, source_commit) =
|
||||
resolve_single_rev(ui, repo, sub_matches.value_of("source").unwrap())?;
|
||||
let (repo, destination_commit) =
|
||||
resolve_single_rev(ui, repo, sub_matches.value_of("destination").unwrap())?;
|
||||
let tree_id;
|
||||
if sub_matches.is_present("interactive") {
|
||||
if sub_matches.is_present("paths") {
|
||||
|
@ -1550,11 +1515,7 @@ fn cmd_restore(
|
|||
ui.write("\n")?;
|
||||
update_checkout_after_rewrite(ui, mut_repo)?;
|
||||
tx.commit();
|
||||
update_working_copy(
|
||||
ui,
|
||||
Arc::get_mut(&mut repo).unwrap(),
|
||||
&owned_wc.lock().unwrap(),
|
||||
)?;
|
||||
update_working_copy(ui, &repo, &owned_wc.lock().unwrap())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1564,10 +1525,9 @@ fn cmd_edit(
|
|||
matches: &ArgMatches,
|
||||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let commit = resolve_revision_arg(ui, mut_repo, sub_matches)?;
|
||||
let (repo, commit) = resolve_revision_arg(ui, repo, sub_matches)?;
|
||||
let base_tree = merge_commit_trees(repo.as_repo_ref(), &commit.parents());
|
||||
let tree_id = crate::diff_edit::edit_diff(&base_tree, &commit.tree())?;
|
||||
if &tree_id == commit.tree().id() {
|
||||
|
@ -1583,11 +1543,7 @@ fn cmd_edit(
|
|||
ui.write("\n")?;
|
||||
update_checkout_after_rewrite(ui, mut_repo)?;
|
||||
tx.commit();
|
||||
update_working_copy(
|
||||
ui,
|
||||
Arc::get_mut(&mut repo).unwrap(),
|
||||
&owned_wc.lock().unwrap(),
|
||||
)?;
|
||||
update_working_copy(ui, &repo, &owned_wc.lock().unwrap())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1597,10 +1553,9 @@ fn cmd_split(
|
|||
matches: &ArgMatches,
|
||||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let commit = resolve_revision_arg(ui, mut_repo, sub_matches)?;
|
||||
let (repo, commit) = resolve_revision_arg(ui, repo, sub_matches)?;
|
||||
let base_tree = merge_commit_trees(repo.as_repo_ref(), &commit.parents());
|
||||
let tree_id = crate::diff_edit::edit_diff(&base_tree, &commit.tree())?;
|
||||
if &tree_id == commit.tree().id() {
|
||||
|
@ -1629,11 +1584,7 @@ fn cmd_split(
|
|||
ui.write("\n")?;
|
||||
update_checkout_after_rewrite(ui, mut_repo)?;
|
||||
tx.commit();
|
||||
update_working_copy(
|
||||
ui,
|
||||
Arc::get_mut(&mut repo).unwrap(),
|
||||
&owned_wc.lock().unwrap(),
|
||||
)?;
|
||||
update_working_copy(ui, &repo, &owned_wc.lock().unwrap())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1645,7 +1596,6 @@ fn cmd_merge(
|
|||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let revision_args = sub_matches.values_of("revisions").unwrap();
|
||||
if revision_args.len() < 2 {
|
||||
return Err(CommandError::UserError(String::from(
|
||||
|
@ -1655,7 +1605,8 @@ fn cmd_merge(
|
|||
let mut commits = vec![];
|
||||
let mut parent_ids = vec![];
|
||||
for revision_arg in revision_args {
|
||||
let commit = resolve_single_rev(ui, mut_repo, revision_arg)?;
|
||||
let (reloaded_repo, commit) = resolve_single_rev(ui, repo, revision_arg)?;
|
||||
repo = reloaded_repo;
|
||||
parent_ids.push(commit.id().clone());
|
||||
commits.push(commit);
|
||||
}
|
||||
|
@ -1674,11 +1625,7 @@ fn cmd_merge(
|
|||
.write_to_repo(tx.mut_repo());
|
||||
update_checkout_after_rewrite(ui, tx.mut_repo())?;
|
||||
tx.commit();
|
||||
update_working_copy(
|
||||
ui,
|
||||
Arc::get_mut(&mut repo).unwrap(),
|
||||
&owned_wc.lock().unwrap(),
|
||||
)?;
|
||||
update_working_copy(ui, &repo, &owned_wc.lock().unwrap())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1688,23 +1635,20 @@ fn cmd_rebase(
|
|||
matches: &ArgMatches,
|
||||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let commit_to_rebase = resolve_revision_arg(ui, mut_repo, sub_matches)?;
|
||||
let (mut repo, commit_to_rebase) = resolve_revision_arg(ui, repo, sub_matches)?;
|
||||
let mut parents = vec![];
|
||||
for revision_str in sub_matches.values_of("destination").unwrap() {
|
||||
parents.push(resolve_single_rev(ui, mut_repo, revision_str)?);
|
||||
let (reloaded_repo, destination) = resolve_single_rev(ui, repo, revision_str)?;
|
||||
repo = reloaded_repo;
|
||||
parents.push(destination);
|
||||
}
|
||||
let mut tx = repo.start_transaction(&format!("rebase commit {}", commit_to_rebase.id().hex()));
|
||||
rebase_commit(ui.settings(), tx.mut_repo(), &commit_to_rebase, &parents);
|
||||
update_checkout_after_rewrite(ui, tx.mut_repo())?;
|
||||
tx.commit();
|
||||
update_working_copy(
|
||||
ui,
|
||||
Arc::get_mut(&mut repo).unwrap(),
|
||||
&owned_wc.lock().unwrap(),
|
||||
)?;
|
||||
update_working_copy(ui, &repo, &owned_wc.lock().unwrap())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1714,13 +1658,14 @@ fn cmd_backout(
|
|||
matches: &ArgMatches,
|
||||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let commit_to_back_out = resolve_revision_arg(ui, mut_repo, sub_matches)?;
|
||||
let (mut repo, commit_to_back_out) = resolve_revision_arg(ui, repo, sub_matches)?;
|
||||
let mut parents = vec![];
|
||||
for revision_str in sub_matches.values_of("destination").unwrap() {
|
||||
parents.push(resolve_single_rev(ui, mut_repo, revision_str)?);
|
||||
let (reloaded_repo, destination) = resolve_single_rev(ui, repo, revision_str)?;
|
||||
repo = reloaded_repo;
|
||||
parents.push(destination);
|
||||
}
|
||||
let mut tx = repo.start_transaction(&format!(
|
||||
"back out commit {}",
|
||||
|
@ -1729,11 +1674,7 @@ fn cmd_backout(
|
|||
back_out_commit(ui.settings(), tx.mut_repo(), &commit_to_back_out, &parents);
|
||||
update_checkout_after_rewrite(ui, tx.mut_repo())?;
|
||||
tx.commit();
|
||||
update_working_copy(
|
||||
ui,
|
||||
Arc::get_mut(&mut repo).unwrap(),
|
||||
&owned_wc.lock().unwrap(),
|
||||
)?;
|
||||
update_working_copy(ui, &repo, &owned_wc.lock().unwrap())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1743,7 +1684,7 @@ fn cmd_evolve<'s>(
|
|||
matches: &ArgMatches,
|
||||
_sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
|
||||
struct Listener<'a, 's> {
|
||||
|
@ -1834,11 +1775,7 @@ fn cmd_evolve<'s>(
|
|||
evolve(&user_settings, tx.mut_repo(), &mut listener);
|
||||
update_checkout_after_rewrite(ui, tx.mut_repo())?;
|
||||
tx.commit();
|
||||
update_working_copy(
|
||||
ui,
|
||||
Arc::get_mut(&mut repo).unwrap(),
|
||||
&owned_wc.lock().unwrap(),
|
||||
)?;
|
||||
update_working_copy(ui, &repo, &owned_wc.lock().unwrap())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1849,9 +1786,8 @@ fn cmd_debug(
|
|||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
if let Some(resolve_matches) = sub_matches.subcommand_matches("resolverev") {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let commit = resolve_revision_arg(ui, mut_repo, resolve_matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let (_repo, commit) = resolve_revision_arg(ui, repo, resolve_matches)?;
|
||||
writeln!(ui, "{}", commit.id().hex())?;
|
||||
} else if let Some(_wc_matches) = sub_matches.subcommand_matches("workingcopy") {
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
|
@ -1866,12 +1802,12 @@ fn cmd_debug(
|
|||
)?;
|
||||
}
|
||||
} else if let Some(_wc_matches) = sub_matches.subcommand_matches("writeworkingcopy") {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let wc = owned_wc.lock().unwrap();
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let old_commit_id = wc.current_commit_id();
|
||||
let new_commit_id = wc.commit(ui.settings(), mut_repo).id().clone();
|
||||
let (_repo, new_commit) = wc.commit(ui.settings(), repo);
|
||||
let new_commit_id = new_commit.id().clone();
|
||||
writeln!(ui, "old commit {:?}", old_commit_id)?;
|
||||
writeln!(ui, "new commit {:?}", new_commit_id)?;
|
||||
} else if let Some(template_matches) = sub_matches.subcommand_matches("template") {
|
||||
|
@ -1933,37 +1869,31 @@ fn cmd_bench(
|
|||
sub_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
if let Some(command_matches) = sub_matches.subcommand_matches("commonancestors") {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let commit1 =
|
||||
resolve_single_rev(ui, mut_repo, command_matches.value_of("revision1").unwrap())?;
|
||||
let commit2 =
|
||||
resolve_single_rev(ui, mut_repo, command_matches.value_of("revision2").unwrap())?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let (repo, commit1) =
|
||||
resolve_single_rev(ui, repo, command_matches.value_of("revision1").unwrap())?;
|
||||
let (repo, commit2) =
|
||||
resolve_single_rev(ui, repo, command_matches.value_of("revision2").unwrap())?;
|
||||
let routine = || {
|
||||
repo.index()
|
||||
.common_ancestors(&[commit1.id().clone()], &[commit2.id().clone()])
|
||||
};
|
||||
run_bench(ui, "commonancestors", routine)?;
|
||||
} else if let Some(command_matches) = sub_matches.subcommand_matches("isancestor") {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let ancestor_commit =
|
||||
resolve_single_rev(ui, mut_repo, command_matches.value_of("ancestor").unwrap())?;
|
||||
let descendant_commit = resolve_single_rev(
|
||||
ui,
|
||||
mut_repo,
|
||||
command_matches.value_of("descendant").unwrap(),
|
||||
)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let (repo, ancestor_commit) =
|
||||
resolve_single_rev(ui, repo, command_matches.value_of("ancestor").unwrap())?;
|
||||
let (repo, descendant_commit) =
|
||||
resolve_single_rev(ui, repo, command_matches.value_of("descendant").unwrap())?;
|
||||
let index = repo.index();
|
||||
let routine = || index.is_ancestor(ancestor_commit.id(), descendant_commit.id());
|
||||
run_bench(ui, "isancestor", routine)?;
|
||||
} else if let Some(command_matches) = sub_matches.subcommand_matches("walkrevs") {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let unwanted_commit =
|
||||
resolve_single_rev(ui, mut_repo, command_matches.value_of("unwanted").unwrap())?;
|
||||
let wanted_commit =
|
||||
resolve_single_rev(ui, mut_repo, command_matches.value_of("wanted").unwrap())?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let (repo, unwanted_commit) =
|
||||
resolve_single_rev(ui, repo, command_matches.value_of("unwanted").unwrap())?;
|
||||
let (repo, wanted_commit) =
|
||||
resolve_single_rev(ui, repo, command_matches.value_of("wanted").unwrap())?;
|
||||
let index = repo.index();
|
||||
let routine = || {
|
||||
index
|
||||
|
@ -2075,7 +2005,7 @@ fn cmd_op_undo(
|
|||
_op_matches: &ArgMatches,
|
||||
_cmd_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let bad_op = resolve_single_op(&repo, _cmd_matches.value_of("operation").unwrap())?;
|
||||
let parent_ops = bad_op.parents();
|
||||
|
@ -2095,11 +2025,7 @@ fn cmd_op_undo(
|
|||
let parent_repo = repo.loader().load_at(&parent_ops[0])?;
|
||||
tx.mut_repo().merge(&bad_repo, &parent_repo);
|
||||
tx.commit();
|
||||
update_working_copy(
|
||||
ui,
|
||||
Arc::get_mut(&mut repo).unwrap(),
|
||||
&owned_wc.lock().unwrap(),
|
||||
)?;
|
||||
update_working_copy(ui, &repo, &owned_wc.lock().unwrap())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -2109,17 +2035,13 @@ fn cmd_op_restore(
|
|||
_op_matches: &ArgMatches,
|
||||
_cmd_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let owned_wc = repo.working_copy().clone();
|
||||
let target_op = resolve_single_op(&repo, _cmd_matches.value_of("operation").unwrap())?;
|
||||
let mut tx = repo.start_transaction(&format!("restore to operation {}", target_op.id().hex()));
|
||||
tx.mut_repo().set_view(target_op.view().take_store_view());
|
||||
tx.commit();
|
||||
update_working_copy(
|
||||
ui,
|
||||
Arc::get_mut(&mut repo).unwrap(),
|
||||
&owned_wc.lock().unwrap(),
|
||||
)?;
|
||||
update_working_copy(ui, &repo, &owned_wc.lock().unwrap())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -2210,10 +2132,9 @@ fn cmd_git_push(
|
|||
_git_matches: &ArgMatches,
|
||||
cmd_matches: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut repo = get_repo(ui, &matches)?;
|
||||
let repo = get_repo(ui, &matches)?;
|
||||
let git_repo = get_git_repo(repo.store())?;
|
||||
let mut_repo = Arc::get_mut(&mut repo).unwrap();
|
||||
let commit = resolve_revision_arg(ui, mut_repo, cmd_matches)?;
|
||||
let (repo, commit) = resolve_revision_arg(ui, repo, cmd_matches)?;
|
||||
let remote_name = cmd_matches.value_of("remote").unwrap();
|
||||
let branch_name = cmd_matches.value_of("branch").unwrap();
|
||||
git::push_commit(&git_repo, &commit, remote_name, branch_name)
|
||||
|
|
Loading…
Reference in a new issue