ok/jj
1
0
Fork 0
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:
Martin von Zweigbergk 2021-04-11 09:23:16 -07:00
parent e3ca27bf77
commit ce855bccfa
13 changed files with 250 additions and 343 deletions

View file

@ -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)
}
}

View file

@ -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)
}
}

View file

@ -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

View file

@ -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,

View file

@ -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);

View file

@ -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,

View file

@ -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]);
}

View file

@ -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);

View file

@ -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()));
}

View file

@ -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()],

View file

@ -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()

View file

@ -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);

View file

@ -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)