mirror of
https://github.com/martinvonz/jj.git
synced 2024-12-27 06:27:43 +00:00
repo: replace Repo trait by enum with readonly and mutable variants
I want to keep the index updated within the transaction. I tried doing that by adding a `trait Index`, implemented by `ReadonlyIndex` and `MutableIndex`. However, `ReadonlyRepo::index` is of type `Mutex<Option<Arc<IndexFile>>>` (because it is lazily initialized), and we cannot get a `&dyn Index` that lives long enough to be returned from a `Repo::index()` from that. It seems the best solution is to instead create an `Index` enum (instead of a trait), with one readonly and one mutable variant. This commit starts the migration to that design by replacing the `Repo` trait by an enum. I never intended for there there to be more implementations of `Repo` than `ReadonlyRepo` and `MutableRepo` anyway.
This commit is contained in:
parent
a1983ebe96
commit
f1666375bd
17 changed files with 238 additions and 164 deletions
|
@ -18,7 +18,7 @@ use std::sync::{Arc, Mutex};
|
|||
use crate::commit::Commit;
|
||||
use crate::commit_builder::CommitBuilder;
|
||||
use crate::dag_walk::{bfs, closest_common_node, leaves, walk_ancestors};
|
||||
use crate::repo::{MutableRepo, ReadonlyRepo, Repo};
|
||||
use crate::repo::{MutableRepo, ReadonlyRepo};
|
||||
use crate::repo_path::DirRepoPath;
|
||||
use crate::rewrite::{merge_commit_trees, rebase_commit};
|
||||
use crate::settings::UserSettings;
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
// limitations under the License.
|
||||
|
||||
use crate::commit::Commit;
|
||||
use crate::repo::Repo;
|
||||
use crate::store::CommitId;
|
||||
use crate::transaction::Transaction;
|
||||
use thiserror::Error;
|
||||
|
@ -31,7 +30,7 @@ pub fn import_refs(
|
|||
) -> Result<(), GitImportError> {
|
||||
let store = tx.store().clone();
|
||||
let git_refs = git_repo.references()?;
|
||||
let existing_git_refs: Vec<_> = tx.as_repo().view().git_refs().keys().cloned().collect();
|
||||
let existing_git_refs: Vec<_> = tx.as_repo_ref().view().git_refs().keys().cloned().collect();
|
||||
// TODO: Store the id of the previous import and read it back here, so we can
|
||||
// merge the views instead of overwriting.
|
||||
for existing_git_ref in existing_git_refs {
|
||||
|
|
|
@ -30,9 +30,10 @@ use crate::commit::Commit;
|
|||
use crate::dag_walk;
|
||||
use crate::op_store::OperationId;
|
||||
use crate::operation::Operation;
|
||||
use crate::repo::{ReadonlyRepo, Repo};
|
||||
use crate::repo::ReadonlyRepo;
|
||||
use crate::store::CommitId;
|
||||
use crate::store_wrapper::StoreWrapper;
|
||||
use crate::view::View;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::ops::Bound;
|
||||
|
||||
|
|
|
@ -54,10 +54,35 @@ impl From<StoreError> for RepoError {
|
|||
|
||||
pub type RepoResult<T> = Result<T, RepoError>;
|
||||
|
||||
pub trait Repo: Sync {
|
||||
fn store(&self) -> &Arc<StoreWrapper>;
|
||||
fn view(&self) -> &dyn View;
|
||||
fn evolution(&self) -> &dyn Evolution;
|
||||
// TODO: Should we implement From<&ReadonlyRepo> and From<&MutableRepo> for
|
||||
// RepoRef?
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum RepoRef<'a, 'r: 'a> {
|
||||
Readonly(&'a ReadonlyRepo),
|
||||
Mutable(&'a MutableRepo<'r>),
|
||||
}
|
||||
|
||||
impl<'a, 'r> RepoRef<'a, 'r> {
|
||||
pub fn store(&self) -> &'a Arc<StoreWrapper> {
|
||||
match self {
|
||||
RepoRef::Readonly(repo) => repo.store(),
|
||||
RepoRef::Mutable(repo) => repo.store(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn view(&self) -> &'a dyn View {
|
||||
match self {
|
||||
RepoRef::Readonly(repo) => repo.view(),
|
||||
RepoRef::Mutable(repo) => repo.view(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn evolution(&self) -> &'a dyn Evolution {
|
||||
match self {
|
||||
RepoRef::Readonly(repo) => repo.evolution(),
|
||||
RepoRef::Mutable(repo) => repo.evolution(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ReadonlyRepo {
|
||||
|
@ -241,6 +266,10 @@ impl ReadonlyRepo {
|
|||
Ok(repo)
|
||||
}
|
||||
|
||||
pub fn as_repo_ref(&self) -> RepoRef {
|
||||
RepoRef::Readonly(&self)
|
||||
}
|
||||
|
||||
pub fn repo_path(&self) -> &PathBuf {
|
||||
&self.repo_path
|
||||
}
|
||||
|
@ -249,6 +278,16 @@ impl ReadonlyRepo {
|
|||
&self.wc_path
|
||||
}
|
||||
|
||||
pub fn view(&self) -> &ReadonlyView {
|
||||
&self.view
|
||||
}
|
||||
|
||||
pub fn evolution<'a>(&'a self) -> &ReadonlyEvolution<'a> {
|
||||
let evolution: &ReadonlyEvolution<'static> = self.evolution.as_ref().unwrap();
|
||||
let evolution: &ReadonlyEvolution<'a> = unsafe { std::mem::transmute(evolution) };
|
||||
evolution
|
||||
}
|
||||
|
||||
pub fn index(&self) -> Arc<ReadonlyIndex> {
|
||||
let mut locked_index = self.index.lock().unwrap();
|
||||
if locked_index.is_none() {
|
||||
|
@ -315,40 +354,12 @@ impl ReadonlyRepo {
|
|||
}
|
||||
}
|
||||
|
||||
impl Repo for ReadonlyRepo {
|
||||
fn store(&self) -> &Arc<StoreWrapper> {
|
||||
&self.store
|
||||
}
|
||||
|
||||
fn view(&self) -> &dyn View {
|
||||
&self.view
|
||||
}
|
||||
|
||||
fn evolution(&self) -> &dyn Evolution {
|
||||
self.evolution.as_ref().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MutableRepo<'r> {
|
||||
repo: &'r ReadonlyRepo,
|
||||
view: Option<MutableView>,
|
||||
evolution: Option<MutableEvolution<'static, 'static>>,
|
||||
}
|
||||
|
||||
impl<'r> Repo for MutableRepo<'r> {
|
||||
fn store(&self) -> &Arc<StoreWrapper> {
|
||||
self.repo.store()
|
||||
}
|
||||
|
||||
fn view(&self) -> &dyn View {
|
||||
self.view.as_ref().unwrap()
|
||||
}
|
||||
|
||||
fn evolution(&self) -> &dyn Evolution {
|
||||
self.evolution.as_ref().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r> MutableRepo<'r> {
|
||||
pub fn new(
|
||||
repo: &'r ReadonlyRepo,
|
||||
|
@ -371,10 +382,22 @@ impl<'r> MutableRepo<'r> {
|
|||
mut_repo
|
||||
}
|
||||
|
||||
pub fn as_repo_ref(&self) -> RepoRef {
|
||||
RepoRef::Mutable(&self)
|
||||
}
|
||||
|
||||
pub fn store(&self) -> &Arc<StoreWrapper> {
|
||||
self.repo.store()
|
||||
}
|
||||
|
||||
pub fn base_repo(&self) -> &'r ReadonlyRepo {
|
||||
self.repo
|
||||
}
|
||||
|
||||
pub fn view(&self) -> &dyn View {
|
||||
self.view.as_ref().unwrap()
|
||||
}
|
||||
|
||||
pub fn view_mut(&mut self) -> &mut MutableView {
|
||||
self.view.as_mut().unwrap()
|
||||
}
|
||||
|
@ -383,6 +406,10 @@ impl<'r> MutableRepo<'r> {
|
|||
self.view.take().unwrap()
|
||||
}
|
||||
|
||||
pub fn evolution(&self) -> &dyn Evolution {
|
||||
self.evolution.as_ref().unwrap()
|
||||
}
|
||||
|
||||
pub fn evolution_mut<'m>(&'m mut self) -> &'m mut MutableEvolution<'r, 'm> {
|
||||
let evolution: &mut MutableEvolution<'static, 'static> = self.evolution.as_mut().unwrap();
|
||||
let evolution: &mut MutableEvolution<'r, 'm> = unsafe { std::mem::transmute(evolution) };
|
||||
|
|
|
@ -17,12 +17,11 @@ use crate::commit_builder::CommitBuilder;
|
|||
use crate::conflicts;
|
||||
use crate::op_store;
|
||||
use crate::operation::Operation;
|
||||
use crate::repo::{MutableRepo, ReadonlyRepo, Repo};
|
||||
use crate::repo::{MutableRepo, ReadonlyRepo, RepoRef};
|
||||
use crate::settings::UserSettings;
|
||||
use crate::store;
|
||||
use crate::store::{CommitId, Timestamp};
|
||||
use crate::store_wrapper::StoreWrapper;
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct Transaction<'r> {
|
||||
|
@ -50,8 +49,8 @@ impl<'r> Transaction<'r> {
|
|||
self.repo.as_ref().unwrap().store()
|
||||
}
|
||||
|
||||
pub fn as_repo<'a: 'r>(&'a self) -> &(impl Repo + 'a) {
|
||||
self.repo.as_ref().unwrap().deref()
|
||||
pub fn as_repo_ref(&self) -> RepoRef {
|
||||
self.repo.as_ref().unwrap().as_repo_ref()
|
||||
}
|
||||
|
||||
pub fn as_repo_mut(&mut self) -> &mut MutableRepo<'r> {
|
||||
|
@ -65,12 +64,15 @@ impl<'r> Transaction<'r> {
|
|||
}
|
||||
|
||||
pub fn check_out(&mut self, settings: &UserSettings, commit: &Commit) -> Commit {
|
||||
let current_checkout_id = self.as_repo().view().checkout().clone();
|
||||
let current_checkout_id = self.as_repo_ref().view().checkout().clone();
|
||||
let current_checkout = self.store().get_commit(¤t_checkout_id).unwrap();
|
||||
assert!(current_checkout.is_open(), "current checkout is closed");
|
||||
if current_checkout.is_empty()
|
||||
&& !(current_checkout.is_pruned()
|
||||
|| self.as_repo().evolution().is_obsolete(¤t_checkout_id))
|
||||
|| self
|
||||
.as_repo_ref()
|
||||
.evolution()
|
||||
.is_obsolete(¤t_checkout_id))
|
||||
{
|
||||
// Prune the checkout we're leaving if it's empty.
|
||||
// TODO: Also prune it if the only changes are conflicts that got materialized.
|
||||
|
|
|
@ -16,8 +16,9 @@ use std::path::PathBuf;
|
|||
|
||||
use tempfile::TempDir;
|
||||
|
||||
use jujube_lib::repo::{ReadonlyRepo, Repo};
|
||||
use jujube_lib::repo::ReadonlyRepo;
|
||||
use jujube_lib::testutils;
|
||||
use jujube_lib::view::View;
|
||||
use std::sync::Arc;
|
||||
use test_case::test_case;
|
||||
|
||||
|
|
|
@ -15,8 +15,9 @@
|
|||
use std::thread;
|
||||
|
||||
use jujube_lib::dag_walk;
|
||||
use jujube_lib::repo::{ReadonlyRepo, Repo};
|
||||
use jujube_lib::repo::ReadonlyRepo;
|
||||
use jujube_lib::testutils;
|
||||
use jujube_lib::view::View;
|
||||
use std::sync::Arc;
|
||||
use test_case::test_case;
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ use jujube_lib::commit::Commit;
|
|||
use jujube_lib::commit_builder::CommitBuilder;
|
||||
use jujube_lib::evolution::evolve;
|
||||
use jujube_lib::evolution::EvolveListener;
|
||||
use jujube_lib::repo::{ReadonlyRepo, Repo};
|
||||
use jujube_lib::repo::ReadonlyRepo;
|
||||
use jujube_lib::repo_path::FileRepoPath;
|
||||
use jujube_lib::settings::UserSettings;
|
||||
use jujube_lib::testutils;
|
||||
|
@ -37,8 +37,8 @@ fn test_obsolete_and_orphan(use_git: bool) {
|
|||
|
||||
// A commit without successors should not be obsolete and not an orphan.
|
||||
let original = child_commit(&settings, &repo, &root_commit).write_to_transaction(&mut tx);
|
||||
assert!(!tx.as_repo().evolution().is_obsolete(original.id()));
|
||||
assert!(!tx.as_repo().evolution().is_orphan(original.id()));
|
||||
assert!(!tx.as_repo_ref().evolution().is_obsolete(original.id()));
|
||||
assert!(!tx.as_repo_ref().evolution().is_orphan(original.id()));
|
||||
|
||||
// A commit with a successor with a different change_id should not be obsolete.
|
||||
let child = child_commit(&settings, &repo, &original).write_to_transaction(&mut tx);
|
||||
|
@ -46,30 +46,30 @@ fn test_obsolete_and_orphan(use_git: bool) {
|
|||
let cherry_picked = child_commit(&settings, &repo, &root_commit)
|
||||
.set_predecessors(vec![original.id().clone()])
|
||||
.write_to_transaction(&mut tx);
|
||||
assert!(!tx.as_repo().evolution().is_obsolete(original.id()));
|
||||
assert!(!tx.as_repo().evolution().is_orphan(original.id()));
|
||||
assert!(!tx.as_repo().evolution().is_obsolete(child.id()));
|
||||
assert!(!tx.as_repo().evolution().is_orphan(child.id()));
|
||||
assert!(!tx.as_repo_ref().evolution().is_obsolete(original.id()));
|
||||
assert!(!tx.as_repo_ref().evolution().is_orphan(original.id()));
|
||||
assert!(!tx.as_repo_ref().evolution().is_obsolete(child.id()));
|
||||
assert!(!tx.as_repo_ref().evolution().is_orphan(child.id()));
|
||||
|
||||
// A commit with a successor with the same change_id should be obsolete.
|
||||
let rewritten = child_commit(&settings, &repo, &root_commit)
|
||||
.set_predecessors(vec![original.id().clone()])
|
||||
.set_change_id(original.change_id().clone())
|
||||
.write_to_transaction(&mut tx);
|
||||
assert!(tx.as_repo().evolution().is_obsolete(original.id()));
|
||||
assert!(!tx.as_repo().evolution().is_obsolete(child.id()));
|
||||
assert!(tx.as_repo().evolution().is_orphan(child.id()));
|
||||
assert!(tx.as_repo().evolution().is_orphan(grandchild.id()));
|
||||
assert!(!tx.as_repo().evolution().is_obsolete(cherry_picked.id()));
|
||||
assert!(!tx.as_repo().evolution().is_orphan(cherry_picked.id()));
|
||||
assert!(!tx.as_repo().evolution().is_obsolete(rewritten.id()));
|
||||
assert!(!tx.as_repo().evolution().is_orphan(rewritten.id()));
|
||||
assert!(tx.as_repo_ref().evolution().is_obsolete(original.id()));
|
||||
assert!(!tx.as_repo_ref().evolution().is_obsolete(child.id()));
|
||||
assert!(tx.as_repo_ref().evolution().is_orphan(child.id()));
|
||||
assert!(tx.as_repo_ref().evolution().is_orphan(grandchild.id()));
|
||||
assert!(!tx.as_repo_ref().evolution().is_obsolete(cherry_picked.id()));
|
||||
assert!(!tx.as_repo_ref().evolution().is_orphan(cherry_picked.id()));
|
||||
assert!(!tx.as_repo_ref().evolution().is_obsolete(rewritten.id()));
|
||||
assert!(!tx.as_repo_ref().evolution().is_orphan(rewritten.id()));
|
||||
|
||||
// It should no longer be obsolete if we remove the successor.
|
||||
tx.remove_head(&rewritten);
|
||||
assert!(!tx.as_repo().evolution().is_obsolete(original.id()));
|
||||
assert!(!tx.as_repo().evolution().is_orphan(child.id()));
|
||||
assert!(!tx.as_repo().evolution().is_orphan(grandchild.id()));
|
||||
assert!(!tx.as_repo_ref().evolution().is_obsolete(original.id()));
|
||||
assert!(!tx.as_repo_ref().evolution().is_orphan(child.id()));
|
||||
assert!(!tx.as_repo_ref().evolution().is_orphan(grandchild.id()));
|
||||
tx.discard();
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,10 @@ fn test_divergent(use_git: bool) {
|
|||
|
||||
// A single commit should not be divergent
|
||||
let original = child_commit(&settings, &repo, &root_commit).write_to_transaction(&mut tx);
|
||||
assert!(!tx.as_repo().evolution().is_divergent(original.change_id()));
|
||||
assert!(!tx
|
||||
.as_repo_ref()
|
||||
.evolution()
|
||||
.is_divergent(original.change_id()));
|
||||
|
||||
// Commits with the same change id are divergent, including the original commit
|
||||
// (it's the change that's divergent)
|
||||
|
@ -95,7 +98,10 @@ fn test_divergent(use_git: bool) {
|
|||
.set_predecessors(vec![original.id().clone()])
|
||||
.set_change_id(original.change_id().clone())
|
||||
.write_to_transaction(&mut tx);
|
||||
assert!(tx.as_repo().evolution().is_divergent(original.change_id()));
|
||||
assert!(tx
|
||||
.as_repo_ref()
|
||||
.evolution()
|
||||
.is_divergent(original.change_id()));
|
||||
tx.discard();
|
||||
}
|
||||
|
||||
|
@ -121,7 +127,10 @@ fn test_divergent_pruned(use_git: bool) {
|
|||
.set_change_id(original.change_id().clone())
|
||||
.set_pruned(true)
|
||||
.write_to_transaction(&mut tx);
|
||||
assert!(tx.as_repo().evolution().is_divergent(original.change_id()));
|
||||
assert!(tx
|
||||
.as_repo_ref()
|
||||
.evolution()
|
||||
.is_divergent(original.change_id()));
|
||||
tx.discard();
|
||||
}
|
||||
|
||||
|
@ -141,13 +150,16 @@ fn test_divergent_duplicate(use_git: bool) {
|
|||
let cherry_picked2 = child_commit(&settings, &repo, &root_commit)
|
||||
.set_predecessors(vec![original.id().clone()])
|
||||
.write_to_transaction(&mut tx);
|
||||
assert!(!tx.as_repo().evolution().is_divergent(original.change_id()));
|
||||
assert!(!tx
|
||||
.as_repo()
|
||||
.as_repo_ref()
|
||||
.evolution()
|
||||
.is_divergent(original.change_id()));
|
||||
assert!(!tx
|
||||
.as_repo_ref()
|
||||
.evolution()
|
||||
.is_divergent(cherry_picked1.change_id()));
|
||||
assert!(!tx
|
||||
.as_repo()
|
||||
.as_repo_ref()
|
||||
.evolution()
|
||||
.is_divergent(cherry_picked2.change_id()));
|
||||
tx.discard();
|
||||
|
@ -170,7 +182,7 @@ fn test_new_parent_rewritten(use_git: bool) {
|
|||
.set_change_id(original.change_id().clone())
|
||||
.write_to_transaction(&mut tx);
|
||||
assert_eq!(
|
||||
tx.as_repo().evolution().new_parent(original.id()),
|
||||
tx.as_repo_ref().evolution().new_parent(original.id()),
|
||||
vec![rewritten.id().clone()].into_iter().collect()
|
||||
);
|
||||
tx.discard();
|
||||
|
@ -190,7 +202,7 @@ fn test_new_parent_cherry_picked(use_git: bool) {
|
|||
.set_predecessors(vec![original.id().clone()])
|
||||
.write_to_transaction(&mut tx);
|
||||
assert_eq!(
|
||||
tx.as_repo().evolution().new_parent(original.id()),
|
||||
tx.as_repo_ref().evolution().new_parent(original.id()),
|
||||
vec![original.id().clone()].into_iter().collect()
|
||||
);
|
||||
tx.discard();
|
||||
|
@ -214,7 +226,7 @@ fn test_new_parent_is_pruned(use_git: bool) {
|
|||
.set_change_id(original.change_id().clone())
|
||||
.write_to_transaction(&mut tx);
|
||||
assert_eq!(
|
||||
tx.as_repo().evolution().new_parent(original.id()),
|
||||
tx.as_repo_ref().evolution().new_parent(original.id()),
|
||||
vec![new_parent.id().clone()].into_iter().collect()
|
||||
);
|
||||
tx.discard();
|
||||
|
@ -243,7 +255,7 @@ fn test_new_parent_divergent(use_git: bool) {
|
|||
.set_change_id(original.change_id().clone())
|
||||
.write_to_transaction(&mut tx);
|
||||
assert_eq!(
|
||||
tx.as_repo().evolution().new_parent(original.id()),
|
||||
tx.as_repo_ref().evolution().new_parent(original.id()),
|
||||
vec![
|
||||
rewritten1.id().clone(),
|
||||
rewritten2.id().clone(),
|
||||
|
@ -284,7 +296,7 @@ fn test_new_parent_divergent_one_not_pruned(use_git: bool) {
|
|||
.set_pruned(true)
|
||||
.write_to_transaction(&mut tx);
|
||||
assert_eq!(
|
||||
tx.as_repo().evolution().new_parent(original.id()),
|
||||
tx.as_repo_ref().evolution().new_parent(original.id()),
|
||||
vec![
|
||||
rewritten1.id().clone(),
|
||||
parent2.id().clone(),
|
||||
|
@ -327,7 +339,7 @@ fn test_new_parent_divergent_all_pruned(use_git: bool) {
|
|||
.set_pruned(true)
|
||||
.write_to_transaction(&mut tx);
|
||||
assert_eq!(
|
||||
tx.as_repo().evolution().new_parent(original.id()),
|
||||
tx.as_repo_ref().evolution().new_parent(original.id()),
|
||||
vec![
|
||||
parent1.id().clone(),
|
||||
parent2.id().clone(),
|
||||
|
@ -363,7 +375,7 @@ fn test_new_parent_split(use_git: bool) {
|
|||
.set_predecessors(vec![original.id().clone()])
|
||||
.write_to_transaction(&mut tx);
|
||||
assert_eq!(
|
||||
tx.as_repo().evolution().new_parent(original.id()),
|
||||
tx.as_repo_ref().evolution().new_parent(original.id()),
|
||||
vec![rewritten3.id().clone()].into_iter().collect()
|
||||
);
|
||||
tx.discard();
|
||||
|
@ -397,7 +409,7 @@ fn test_new_parent_split_pruned_descendant(use_git: bool) {
|
|||
.set_predecessors(vec![original.id().clone()])
|
||||
.write_to_transaction(&mut tx);
|
||||
assert_eq!(
|
||||
tx.as_repo().evolution().new_parent(original.id()),
|
||||
tx.as_repo_ref().evolution().new_parent(original.id()),
|
||||
vec![rewritten2.id().clone()].into_iter().collect()
|
||||
);
|
||||
tx.discard();
|
||||
|
@ -431,7 +443,7 @@ fn test_new_parent_split_forked(use_git: bool) {
|
|||
.set_predecessors(vec![original.id().clone()])
|
||||
.write_to_transaction(&mut tx);
|
||||
assert_eq!(
|
||||
tx.as_repo().evolution().new_parent(original.id()),
|
||||
tx.as_repo_ref().evolution().new_parent(original.id()),
|
||||
vec![rewritten2.id().clone(), rewritten3.id().clone()]
|
||||
.into_iter()
|
||||
.collect()
|
||||
|
@ -467,7 +479,7 @@ fn test_new_parent_split_forked_pruned(use_git: bool) {
|
|||
.set_predecessors(vec![original.id().clone()])
|
||||
.write_to_transaction(&mut tx);
|
||||
assert_eq!(
|
||||
tx.as_repo().evolution().new_parent(original.id()),
|
||||
tx.as_repo_ref().evolution().new_parent(original.id()),
|
||||
vec![rewritten3.id().clone()].into_iter().collect()
|
||||
);
|
||||
tx.discard();
|
||||
|
|
|
@ -16,10 +16,11 @@ use git2::Oid;
|
|||
use jujube_lib::commit::Commit;
|
||||
use jujube_lib::git;
|
||||
use jujube_lib::git::{GitFetchError, GitPushError};
|
||||
use jujube_lib::repo::{ReadonlyRepo, Repo};
|
||||
use jujube_lib::repo::ReadonlyRepo;
|
||||
use jujube_lib::settings::UserSettings;
|
||||
use jujube_lib::store::CommitId;
|
||||
use jujube_lib::testutils;
|
||||
use jujube_lib::view::View;
|
||||
use maplit::hashset;
|
||||
use std::collections::HashSet;
|
||||
use std::path::PathBuf;
|
||||
|
@ -69,7 +70,7 @@ fn test_import_refs() {
|
|||
let mut tx = repo.start_transaction("test");
|
||||
let heads_before: HashSet<_> = repo.view().heads().clone();
|
||||
jujube_lib::git::import_refs(&mut tx, &git_repo).unwrap_or_default();
|
||||
let view = tx.as_repo().view();
|
||||
let view = tx.as_repo_ref().view();
|
||||
let expected_heads: HashSet<_> = heads_before
|
||||
.union(&hashset!(
|
||||
commit_id(&commit3),
|
||||
|
@ -125,7 +126,7 @@ fn test_import_refs_reimport() {
|
|||
let mut tx = repo.start_transaction("test");
|
||||
jujube_lib::git::import_refs(&mut tx, &git_repo).unwrap_or_default();
|
||||
|
||||
let view = tx.as_repo().view();
|
||||
let view = tx.as_repo_ref().view();
|
||||
// TODO: commit3 and commit4 should probably be removed
|
||||
let expected_heads: HashSet<_> = heads_before
|
||||
.union(&hashset!(
|
||||
|
@ -277,7 +278,7 @@ fn test_import_refs_empty_git_repo() {
|
|||
let heads_before = repo.view().heads().clone();
|
||||
let mut tx = repo.start_transaction("test");
|
||||
jujube_lib::git::import_refs(&mut tx, &git_repo).unwrap_or_default();
|
||||
let view = tx.as_repo().view();
|
||||
let view = tx.as_repo_ref().view();
|
||||
assert_eq!(*view.heads(), heads_before);
|
||||
assert_eq!(view.git_refs().len(), 0);
|
||||
tx.discard();
|
||||
|
@ -324,7 +325,7 @@ fn test_fetch_success() {
|
|||
let mut tx = jj_repo.start_transaction("test");
|
||||
git::fetch(&mut tx, &clone_git_repo, "origin").unwrap();
|
||||
assert!(tx
|
||||
.as_repo()
|
||||
.as_repo_ref()
|
||||
.view()
|
||||
.heads()
|
||||
.contains(&commit_id(&new_git_commit)));
|
||||
|
|
|
@ -13,9 +13,11 @@
|
|||
// limitations under the License.
|
||||
|
||||
use jujube_lib::commit_builder::CommitBuilder;
|
||||
use jujube_lib::repo::Repo;
|
||||
use jujube_lib::evolution::Evolution;
|
||||
use jujube_lib::repo::RepoRef;
|
||||
use jujube_lib::store::CommitId;
|
||||
use jujube_lib::testutils;
|
||||
use jujube_lib::view::View;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use test_case::test_case;
|
||||
|
@ -105,7 +107,7 @@ fn test_concurrent_operations(use_git: bool) {
|
|||
assert_eq!(list_dir(&op_heads_dir), vec![merged_op_head_id.hex()]);
|
||||
}
|
||||
|
||||
fn assert_heads(repo: &impl Repo, expected: Vec<&CommitId>) {
|
||||
fn assert_heads(repo: RepoRef, expected: Vec<&CommitId>) {
|
||||
let expected = expected.iter().cloned().cloned().collect();
|
||||
assert_eq!(*repo.view().heads(), expected);
|
||||
}
|
||||
|
@ -126,12 +128,12 @@ fn test_isolation(use_git: bool) {
|
|||
let mut tx1 = repo.start_transaction("transaction 1");
|
||||
let mut tx2 = repo.start_transaction("transaction 2");
|
||||
|
||||
assert_heads(repo.as_ref(), vec![&wc_id, initial.id()]);
|
||||
assert_heads(tx1.as_repo(), vec![&wc_id, initial.id()]);
|
||||
assert_heads(tx2.as_repo(), vec![&wc_id, initial.id()]);
|
||||
assert_heads(repo.as_repo_ref(), vec![&wc_id, initial.id()]);
|
||||
assert_heads(tx1.as_repo_ref(), vec![&wc_id, initial.id()]);
|
||||
assert_heads(tx2.as_repo_ref(), vec![&wc_id, initial.id()]);
|
||||
assert!(!repo.evolution().is_obsolete(initial.id()));
|
||||
assert!(!tx1.as_repo().evolution().is_obsolete(initial.id()));
|
||||
assert!(!tx2.as_repo().evolution().is_obsolete(initial.id()));
|
||||
assert!(!tx1.as_repo_ref().evolution().is_obsolete(initial.id()));
|
||||
assert!(!tx2.as_repo_ref().evolution().is_obsolete(initial.id()));
|
||||
|
||||
let rewrite1 = CommitBuilder::for_rewrite_from(&settings, repo.store(), &initial)
|
||||
.set_description("rewrite1".to_string())
|
||||
|
@ -142,25 +144,25 @@ fn test_isolation(use_git: bool) {
|
|||
|
||||
// Neither transaction has committed yet, so each transaction sees its own
|
||||
// commit.
|
||||
assert_heads(repo.as_ref(), vec![&wc_id, initial.id()]);
|
||||
assert_heads(tx1.as_repo(), vec![&wc_id, initial.id(), rewrite1.id()]);
|
||||
assert_heads(tx2.as_repo(), vec![&wc_id, initial.id(), rewrite2.id()]);
|
||||
assert_heads(repo.as_repo_ref(), vec![&wc_id, initial.id()]);
|
||||
assert_heads(tx1.as_repo_ref(), vec![&wc_id, initial.id(), rewrite1.id()]);
|
||||
assert_heads(tx2.as_repo_ref(), vec![&wc_id, initial.id(), rewrite2.id()]);
|
||||
assert!(!repo.evolution().is_obsolete(initial.id()));
|
||||
assert!(tx1.as_repo().evolution().is_obsolete(initial.id()));
|
||||
assert!(tx2.as_repo().evolution().is_obsolete(initial.id()));
|
||||
assert!(tx1.as_repo_ref().evolution().is_obsolete(initial.id()));
|
||||
assert!(tx2.as_repo_ref().evolution().is_obsolete(initial.id()));
|
||||
|
||||
// The base repo and tx2 don't see the commits from tx1.
|
||||
tx1.commit();
|
||||
assert_heads(repo.as_ref(), vec![&wc_id, initial.id()]);
|
||||
assert_heads(tx2.as_repo(), vec![&wc_id, initial.id(), rewrite2.id()]);
|
||||
assert_heads(repo.as_repo_ref(), vec![&wc_id, initial.id()]);
|
||||
assert_heads(tx2.as_repo_ref(), vec![&wc_id, initial.id(), rewrite2.id()]);
|
||||
|
||||
// The base repo still doesn't see the commits after both transactions commit.
|
||||
tx2.commit();
|
||||
assert_heads(repo.as_ref(), vec![&wc_id, initial.id()]);
|
||||
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();
|
||||
assert_heads(
|
||||
repo.as_ref(),
|
||||
repo.as_repo_ref(),
|
||||
vec![&wc_id, initial.id(), rewrite1.id(), rewrite2.id()],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
// limitations under the License.
|
||||
|
||||
use jujube_lib::commit_builder::CommitBuilder;
|
||||
use jujube_lib::repo::Repo;
|
||||
use jujube_lib::repo_path::FileRepoPath;
|
||||
use jujube_lib::store::{Conflict, ConflictId, ConflictPart, TreeValue};
|
||||
use jujube_lib::store_wrapper::StoreWrapper;
|
||||
use jujube_lib::testutils;
|
||||
use jujube_lib::view::View;
|
||||
use std::sync::Arc;
|
||||
use test_case::test_case;
|
||||
|
||||
|
@ -203,7 +203,7 @@ fn test_checkout_previous_not_empty(use_git: bool) {
|
|||
.set_open(true)
|
||||
.write_to_transaction(&mut tx);
|
||||
tx.check_out(&settings, &new_checkout);
|
||||
assert!(!tx.as_repo().evolution().is_obsolete(old_checkout.id()));
|
||||
assert!(!tx.as_repo_ref().evolution().is_obsolete(old_checkout.id()));
|
||||
tx.discard();
|
||||
}
|
||||
|
||||
|
@ -232,7 +232,7 @@ fn test_checkout_previous_empty(use_git: bool) {
|
|||
.set_open(true)
|
||||
.write_to_transaction(&mut tx);
|
||||
tx.check_out(&settings, &new_checkout);
|
||||
assert!(tx.as_repo().evolution().is_obsolete(old_checkout.id()));
|
||||
assert!(tx.as_repo_ref().evolution().is_obsolete(old_checkout.id()));
|
||||
tx.discard();
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@ fn test_checkout_previous_empty_and_obsolete(use_git: bool) {
|
|||
.set_open(true)
|
||||
.write_to_transaction(&mut tx);
|
||||
tx.check_out(&settings, &new_checkout);
|
||||
let successors = tx.as_repo().evolution().successors(old_checkout.id());
|
||||
let successors = tx.as_repo_ref().evolution().successors(old_checkout.id());
|
||||
assert_eq!(successors.len(), 1);
|
||||
assert_eq!(successors.iter().next().unwrap(), successor.id());
|
||||
tx.discard();
|
||||
|
@ -292,7 +292,7 @@ fn test_checkout_previous_empty_and_pruned(use_git: bool) {
|
|||
.write_to_transaction(&mut tx);
|
||||
tx.check_out(&settings, &new_checkout);
|
||||
assert!(tx
|
||||
.as_repo()
|
||||
.as_repo_ref()
|
||||
.evolution()
|
||||
.successors(old_checkout.id())
|
||||
.is_empty());
|
||||
|
@ -315,9 +315,9 @@ fn test_add_head_success(use_git: bool) {
|
|||
tx.discard();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
assert!(!tx.as_repo().view().heads().contains(new_commit.id()));
|
||||
assert!(!tx.as_repo_ref().view().heads().contains(new_commit.id()));
|
||||
tx.add_head(&new_commit);
|
||||
assert!(tx.as_repo().view().heads().contains(new_commit.id()));
|
||||
assert!(tx.as_repo_ref().view().heads().contains(new_commit.id()));
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
assert!(repo.view().heads().contains(new_commit.id()));
|
||||
|
@ -344,7 +344,7 @@ fn test_add_head_ancestor(use_git: bool) {
|
|||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
tx.add_head(&commit1);
|
||||
assert!(!tx.as_repo().view().heads().contains(commit1.id()));
|
||||
assert!(!tx.as_repo_ref().view().heads().contains(commit1.id()));
|
||||
tx.discard();
|
||||
}
|
||||
|
||||
|
@ -368,9 +368,9 @@ fn test_remove_head(use_git: bool) {
|
|||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
assert!(tx.as_repo().view().heads().contains(commit3.id()));
|
||||
assert!(tx.as_repo_ref().view().heads().contains(commit3.id()));
|
||||
tx.remove_head(&commit3);
|
||||
let heads = tx.as_repo().view().heads().clone();
|
||||
let heads = tx.as_repo_ref().view().heads().clone();
|
||||
assert!(!heads.contains(commit3.id()));
|
||||
assert!(!heads.contains(commit2.id()));
|
||||
assert!(!heads.contains(commit1.id()));
|
||||
|
@ -404,10 +404,10 @@ fn test_remove_head_ancestor_git_ref(use_git: bool) {
|
|||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
let heads = tx.as_repo().view().heads().clone();
|
||||
let heads = tx.as_repo_ref().view().heads().clone();
|
||||
assert!(heads.contains(commit3.id()));
|
||||
tx.remove_head(&commit3);
|
||||
let heads = tx.as_repo().view().heads().clone();
|
||||
let heads = tx.as_repo_ref().view().heads().clone();
|
||||
assert!(!heads.contains(commit3.id()));
|
||||
assert!(!heads.contains(commit2.id()));
|
||||
assert!(heads.contains(commit1.id()));
|
||||
|
@ -434,9 +434,17 @@ fn test_add_public_head(use_git: bool) {
|
|||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
assert!(!tx.as_repo().view().public_heads().contains(commit1.id()));
|
||||
assert!(!tx
|
||||
.as_repo_ref()
|
||||
.view()
|
||||
.public_heads()
|
||||
.contains(commit1.id()));
|
||||
tx.add_public_head(&commit1);
|
||||
assert!(tx.as_repo().view().public_heads().contains(commit1.id()));
|
||||
assert!(tx
|
||||
.as_repo_ref()
|
||||
.view()
|
||||
.public_heads()
|
||||
.contains(commit1.id()));
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
assert!(repo.view().public_heads().contains(commit1.id()));
|
||||
|
@ -460,9 +468,17 @@ fn test_add_public_head_ancestor(use_git: bool) {
|
|||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
assert!(!tx.as_repo().view().public_heads().contains(commit1.id()));
|
||||
assert!(!tx
|
||||
.as_repo_ref()
|
||||
.view()
|
||||
.public_heads()
|
||||
.contains(commit1.id()));
|
||||
tx.add_public_head(&commit1);
|
||||
assert!(!tx.as_repo().view().public_heads().contains(commit1.id()));
|
||||
assert!(!tx
|
||||
.as_repo_ref()
|
||||
.view()
|
||||
.public_heads()
|
||||
.contains(commit1.id()));
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
assert!(!repo.view().public_heads().contains(commit1.id()));
|
||||
|
@ -483,9 +499,17 @@ fn test_remove_public_head(use_git: bool) {
|
|||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
|
||||
let mut tx = repo.start_transaction("test");
|
||||
assert!(tx.as_repo().view().public_heads().contains(commit1.id()));
|
||||
assert!(tx
|
||||
.as_repo_ref()
|
||||
.view()
|
||||
.public_heads()
|
||||
.contains(commit1.id()));
|
||||
tx.remove_public_head(&commit1);
|
||||
assert!(!tx.as_repo().view().public_heads().contains(commit1.id()));
|
||||
assert!(!tx
|
||||
.as_repo_ref()
|
||||
.view()
|
||||
.public_heads()
|
||||
.contains(commit1.id()));
|
||||
tx.commit();
|
||||
Arc::get_mut(&mut repo).unwrap().reload();
|
||||
assert!(!repo.view().public_heads().contains(commit1.id()));
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use jujube_lib::repo::Repo;
|
||||
use jujube_lib::testutils;
|
||||
use jujube_lib::view::View;
|
||||
use maplit::hashset;
|
||||
use test_case::test_case;
|
||||
|
||||
|
@ -46,7 +46,7 @@ fn test_heads_fork(use_git: bool) {
|
|||
|
||||
let wc = repo.working_copy_locked();
|
||||
assert_eq!(
|
||||
*tx.as_repo().view().heads(),
|
||||
*tx.as_repo_ref().view().heads(),
|
||||
hashset! {
|
||||
wc.current_commit_id(),
|
||||
child1.id().clone(),
|
||||
|
@ -78,7 +78,7 @@ fn test_heads_merge(use_git: bool) {
|
|||
|
||||
let wc = repo.working_copy_locked();
|
||||
assert_eq!(
|
||||
*tx.as_repo().view().heads(),
|
||||
*tx.as_repo_ref().view().heads(),
|
||||
hashset! {wc.current_commit_id(), merge.id().clone()}
|
||||
);
|
||||
tx.discard();
|
||||
|
|
|
@ -16,12 +16,13 @@
|
|||
use std::os::unix::fs::PermissionsExt;
|
||||
|
||||
use jujube_lib::commit_builder::CommitBuilder;
|
||||
use jujube_lib::repo::{ReadonlyRepo, Repo};
|
||||
use jujube_lib::repo::ReadonlyRepo;
|
||||
use jujube_lib::repo_path::{FileRepoPath, RepoPath};
|
||||
use jujube_lib::settings::UserSettings;
|
||||
use jujube_lib::store::TreeValue;
|
||||
use jujube_lib::testutils;
|
||||
use jujube_lib::tree_builder::TreeBuilder;
|
||||
use jujube_lib::view::View;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::Write;
|
||||
use std::sync::Arc;
|
||||
|
|
|
@ -36,12 +36,12 @@ use jujube_lib::commit_builder::CommitBuilder;
|
|||
use jujube_lib::conflicts;
|
||||
use jujube_lib::dag_walk::{common_ancestor, topo_order_reverse, walk_ancestors};
|
||||
use jujube_lib::evolution::evolve;
|
||||
use jujube_lib::evolution::EvolveListener;
|
||||
use jujube_lib::evolution::{Evolution, EvolveListener};
|
||||
use jujube_lib::files;
|
||||
use jujube_lib::files::DiffLine;
|
||||
use jujube_lib::git;
|
||||
use jujube_lib::op_store::{OpStoreError, OperationId};
|
||||
use jujube_lib::repo::{ReadonlyRepo, Repo, RepoLoadError};
|
||||
use jujube_lib::repo::{ReadonlyRepo, RepoLoadError, RepoRef};
|
||||
use jujube_lib::repo_path::RepoPath;
|
||||
use jujube_lib::rewrite::{back_out_commit, merge_commit_trees, rebase_commit};
|
||||
use jujube_lib::settings::UserSettings;
|
||||
|
@ -49,6 +49,7 @@ use jujube_lib::store::{CommitId, Timestamp};
|
|||
use jujube_lib::store::{StoreError, TreeValue};
|
||||
use jujube_lib::tree::Tree;
|
||||
use jujube_lib::trees::TreeValueDiff;
|
||||
use jujube_lib::view::View;
|
||||
use jujube_lib::working_copy::{CheckoutStats, WorkingCopy};
|
||||
|
||||
use self::chrono::{FixedOffset, TimeZone, Utc};
|
||||
|
@ -237,7 +238,7 @@ fn update_working_copy(
|
|||
return Ok(None);
|
||||
}
|
||||
ui.write("leaving: ");
|
||||
ui.write_commit_summary(repo, &old_commit);
|
||||
ui.write_commit_summary(repo.as_repo_ref(), &old_commit);
|
||||
ui.write("\n");
|
||||
// TODO: CheckoutError::ConcurrentCheckout should probably just result in a
|
||||
// warning for most commands (but be an error for the checkout command)
|
||||
|
@ -249,14 +250,14 @@ fn update_working_copy(
|
|||
))
|
||||
})?;
|
||||
ui.write("now at: ");
|
||||
ui.write_commit_summary(repo, &new_commit);
|
||||
ui.write_commit_summary(repo.as_repo_ref(), &new_commit);
|
||||
ui.write("\n");
|
||||
Ok(Some(stats))
|
||||
}
|
||||
|
||||
fn update_checkout_after_rewrite(ui: &mut Ui, tx: &mut Transaction) {
|
||||
// TODO: Perhaps this method should be in Transaction.
|
||||
let repo = tx.as_repo();
|
||||
let repo = tx.as_repo_ref();
|
||||
let new_checkout_candidates = repo.evolution().new_parent(repo.view().checkout());
|
||||
if new_checkout_candidates.is_empty() {
|
||||
return;
|
||||
|
@ -929,10 +930,10 @@ fn cmd_status(
|
|||
let wc = owned_wc.lock().unwrap();
|
||||
let commit = wc.commit(ui.settings(), mut_repo);
|
||||
ui.write("Working copy : ");
|
||||
ui.write_commit_summary(repo.as_ref(), &commit);
|
||||
ui.write_commit_summary(repo.as_repo_ref(), &commit);
|
||||
ui.write("\n");
|
||||
ui.write("Parent commit: ");
|
||||
ui.write_commit_summary(repo.as_ref(), &commit.parents()[0]);
|
||||
ui.write_commit_summary(repo.as_repo_ref(), &commit.parents()[0]);
|
||||
ui.write("\n");
|
||||
ui.write("Diff summary:\n");
|
||||
show_diff_summary(ui, &commit.parents()[0].tree(), &commit.tree());
|
||||
|
@ -1035,7 +1036,8 @@ fn cmd_log(
|
|||
}
|
||||
}
|
||||
};
|
||||
let template = crate::template_parser::parse_commit_template(repo.as_ref(), &template_string);
|
||||
let template =
|
||||
crate::template_parser::parse_commit_template(repo.as_repo_ref(), &template_string);
|
||||
|
||||
let mut styler = ui.styler();
|
||||
let mut styler = styler.as_mut();
|
||||
|
@ -1108,7 +1110,8 @@ fn cmd_obslog(
|
|||
}
|
||||
}
|
||||
};
|
||||
let template = crate::template_parser::parse_commit_template(repo.as_ref(), &template_string);
|
||||
let template =
|
||||
crate::template_parser::parse_commit_template(repo.as_repo_ref(), &template_string);
|
||||
|
||||
let mut styler = ui.styler();
|
||||
let mut styler = styler.as_mut();
|
||||
|
@ -1284,7 +1287,7 @@ fn cmd_duplicate(
|
|||
.generate_new_change_id()
|
||||
.write_to_transaction(&mut tx);
|
||||
ui.write("created: ");
|
||||
ui.write_commit_summary(tx.as_repo(), &new_commit);
|
||||
ui.write_commit_summary(tx.as_repo_ref(), &new_commit);
|
||||
ui.write("\n");
|
||||
tx.commit();
|
||||
Ok(())
|
||||
|
@ -1335,7 +1338,7 @@ fn cmd_new(
|
|||
);
|
||||
let mut tx = repo.start_transaction("new empty commit");
|
||||
let new_commit = commit_builder.write_to_transaction(&mut tx);
|
||||
if tx.as_repo().view().checkout() == parent.id() {
|
||||
if tx.as_repo_ref().view().checkout() == parent.id() {
|
||||
tx.check_out(ui.settings(), &new_commit);
|
||||
}
|
||||
tx.commit();
|
||||
|
@ -1460,7 +1463,7 @@ fn cmd_restore(
|
|||
.set_tree(tree_id)
|
||||
.write_to_transaction(&mut tx);
|
||||
ui.write("Created ");
|
||||
ui.write_commit_summary(tx.as_repo(), &new_commit);
|
||||
ui.write_commit_summary(tx.as_repo_ref(), &new_commit);
|
||||
ui.write("\n");
|
||||
update_checkout_after_rewrite(ui, &mut tx);
|
||||
tx.commit();
|
||||
|
@ -1492,7 +1495,7 @@ fn cmd_edit(
|
|||
.set_tree(tree_id)
|
||||
.write_to_transaction(&mut tx);
|
||||
ui.write("Created ");
|
||||
ui.write_commit_summary(tx.as_repo(), &new_commit);
|
||||
ui.write_commit_summary(tx.as_repo_ref(), &new_commit);
|
||||
ui.write("\n");
|
||||
update_checkout_after_rewrite(ui, &mut tx);
|
||||
tx.commit();
|
||||
|
@ -1535,9 +1538,9 @@ fn cmd_split(
|
|||
.set_description(second_description)
|
||||
.write_to_transaction(&mut tx);
|
||||
ui.write("First part: ");
|
||||
ui.write_commit_summary(tx.as_repo(), &first_commit);
|
||||
ui.write_commit_summary(tx.as_repo_ref(), &first_commit);
|
||||
ui.write("Second part: ");
|
||||
ui.write_commit_summary(tx.as_repo(), &second_commit);
|
||||
ui.write_commit_summary(tx.as_repo_ref(), &second_commit);
|
||||
ui.write("\n");
|
||||
update_checkout_after_rewrite(ui, &mut tx);
|
||||
tx.commit();
|
||||
|
@ -1660,7 +1663,7 @@ fn cmd_evolve<'s>(
|
|||
|
||||
struct Listener<'a, 's, 'r> {
|
||||
ui: &'a mut Ui<'s>,
|
||||
repo: &'r dyn Repo,
|
||||
repo: RepoRef<'a, 'r>,
|
||||
};
|
||||
|
||||
impl<'a, 's, 'r> EvolveListener for Listener<'a, 's, 'r> {
|
||||
|
@ -1710,9 +1713,9 @@ fn cmd_evolve<'s>(
|
|||
let user_settings = ui.settings().clone();
|
||||
let mut listener = Listener {
|
||||
ui,
|
||||
// TODO: This should be using tx.as_repo() so the templater sees the updated state, but
|
||||
// TODO: This should be using tx.as_repo_ref() so the templater sees the updated state, but
|
||||
// we can't do that because we let evolution::evolve() mutably borrow the Transaction.
|
||||
repo: repo.as_ref(),
|
||||
repo: repo.as_repo_ref(),
|
||||
};
|
||||
let mut tx = repo.start_transaction("evolve");
|
||||
evolve(&user_settings, &mut tx, &mut listener);
|
||||
|
|
|
@ -29,7 +29,7 @@ use crate::templater::{
|
|||
LiteralTemplate, ObsoleteProperty, OpenProperty, OrphanProperty, PrunedProperty,
|
||||
StringPropertyTemplate, Template, TemplateFunction, TemplateProperty,
|
||||
};
|
||||
use jujube_lib::repo::Repo;
|
||||
use jujube_lib::repo::RepoRef;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[grammar = "template.pest"]
|
||||
|
@ -216,7 +216,7 @@ impl<'a, I: 'a> Property<'a, I> {
|
|||
}
|
||||
|
||||
fn parse_commit_keyword<'a, 'r: 'a>(
|
||||
repo: &'r dyn Repo,
|
||||
repo: RepoRef<'a, 'r>,
|
||||
pair: Pair<Rule>,
|
||||
) -> (Property<'a, Commit>, String) {
|
||||
assert_eq!(pair.as_rule(), Rule::identifier);
|
||||
|
@ -260,7 +260,7 @@ fn coerce_to_string<'a, I: 'a>(
|
|||
}
|
||||
|
||||
fn parse_boolean_commit_property<'a, 'r: 'a>(
|
||||
repo: &'r dyn Repo,
|
||||
repo: RepoRef<'a, 'r>,
|
||||
pair: Pair<Rule>,
|
||||
) -> Box<dyn TemplateProperty<Commit, bool> + 'a> {
|
||||
let mut inner = pair.into_inner();
|
||||
|
@ -277,7 +277,7 @@ fn parse_boolean_commit_property<'a, 'r: 'a>(
|
|||
}
|
||||
|
||||
fn parse_commit_term<'a, 'r: 'a>(
|
||||
repo: &'r dyn Repo,
|
||||
repo: RepoRef<'a, 'r>,
|
||||
pair: Pair<Rule>,
|
||||
) -> Box<dyn Template<Commit> + 'a> {
|
||||
assert_eq!(pair.as_rule(), Rule::term);
|
||||
|
@ -375,7 +375,7 @@ fn parse_commit_term<'a, 'r: 'a>(
|
|||
}
|
||||
|
||||
fn parse_commit_template_rule<'a, 'r: 'a>(
|
||||
repo: &'r dyn Repo,
|
||||
repo: RepoRef<'a, 'r>,
|
||||
pair: Pair<Rule>,
|
||||
) -> Box<dyn Template<Commit> + 'a> {
|
||||
match pair.as_rule() {
|
||||
|
@ -398,7 +398,7 @@ fn parse_commit_template_rule<'a, 'r: 'a>(
|
|||
}
|
||||
|
||||
pub fn parse_commit_template<'a, 'r: 'a>(
|
||||
repo: &'r dyn Repo,
|
||||
repo: RepoRef<'a, 'r>,
|
||||
template_text: &str,
|
||||
) -> Box<dyn Template<Commit> + 'a> {
|
||||
let mut pairs: Pairs<Rule> = TemplateParser::parse(Rule::template, template_text).unwrap();
|
||||
|
|
|
@ -16,7 +16,7 @@ use std::borrow::BorrowMut;
|
|||
use std::ops::Add;
|
||||
|
||||
use jujube_lib::commit::Commit;
|
||||
use jujube_lib::repo::Repo;
|
||||
use jujube_lib::repo::RepoRef;
|
||||
use jujube_lib::store::{CommitId, Signature};
|
||||
|
||||
use crate::styler::Styler;
|
||||
|
@ -202,21 +202,21 @@ impl TemplateProperty<Commit, bool> for PrunedProperty {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct CurrentCheckoutProperty<'r> {
|
||||
pub repo: &'r dyn Repo,
|
||||
pub struct CurrentCheckoutProperty<'a, 'r> {
|
||||
pub repo: RepoRef<'a, 'r>,
|
||||
}
|
||||
|
||||
impl<'r> TemplateProperty<Commit, bool> for CurrentCheckoutProperty<'r> {
|
||||
impl TemplateProperty<Commit, bool> for CurrentCheckoutProperty<'_, '_> {
|
||||
fn extract(&self, context: &Commit) -> bool {
|
||||
context.id() == self.repo.view().checkout()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GitRefsProperty<'r> {
|
||||
pub repo: &'r dyn Repo,
|
||||
pub struct GitRefsProperty<'a, 'r> {
|
||||
pub repo: RepoRef<'a, 'r>,
|
||||
}
|
||||
|
||||
impl<'r> TemplateProperty<Commit, String> for GitRefsProperty<'r> {
|
||||
impl TemplateProperty<Commit, String> for GitRefsProperty<'_, '_> {
|
||||
fn extract(&self, context: &Commit) -> String {
|
||||
let refs: Vec<_> = self
|
||||
.repo
|
||||
|
@ -230,31 +230,31 @@ impl<'r> TemplateProperty<Commit, String> for GitRefsProperty<'r> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct ObsoleteProperty<'r> {
|
||||
pub repo: &'r dyn Repo,
|
||||
pub struct ObsoleteProperty<'a, 'r> {
|
||||
pub repo: RepoRef<'a, 'r>,
|
||||
}
|
||||
|
||||
impl<'r> TemplateProperty<Commit, bool> for ObsoleteProperty<'r> {
|
||||
impl TemplateProperty<Commit, bool> for ObsoleteProperty<'_, '_> {
|
||||
fn extract(&self, context: &Commit) -> bool {
|
||||
self.repo.evolution().is_obsolete(context.id())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OrphanProperty<'r> {
|
||||
pub repo: &'r dyn Repo,
|
||||
pub struct OrphanProperty<'a, 'r> {
|
||||
pub repo: RepoRef<'a, 'r>,
|
||||
}
|
||||
|
||||
impl<'r> TemplateProperty<Commit, bool> for OrphanProperty<'r> {
|
||||
impl TemplateProperty<Commit, bool> for OrphanProperty<'_, '_> {
|
||||
fn extract(&self, context: &Commit) -> bool {
|
||||
self.repo.evolution().is_orphan(context.id())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DivergentProperty<'r> {
|
||||
pub repo: &'r dyn Repo,
|
||||
pub struct DivergentProperty<'a, 'r> {
|
||||
pub repo: RepoRef<'a, 'r>,
|
||||
}
|
||||
|
||||
impl<'r> TemplateProperty<Commit, bool> for DivergentProperty<'r> {
|
||||
impl TemplateProperty<Commit, bool> for DivergentProperty<'_, '_> {
|
||||
fn extract(&self, context: &Commit) -> bool {
|
||||
self.repo.evolution().is_divergent(context.change_id())
|
||||
}
|
||||
|
@ -262,7 +262,7 @@ impl<'r> TemplateProperty<Commit, bool> for DivergentProperty<'r> {
|
|||
|
||||
pub struct ConflictProperty;
|
||||
|
||||
impl<'r> TemplateProperty<Commit, bool> for ConflictProperty {
|
||||
impl TemplateProperty<Commit, bool> for ConflictProperty {
|
||||
fn extract(&self, context: &Commit) -> bool {
|
||||
context.tree().has_conflict()
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ use jujube_lib::settings::UserSettings;
|
|||
|
||||
use crate::styler::{ColorStyler, PlainTextStyler, Styler};
|
||||
use crate::templater::TemplateFormatter;
|
||||
use jujube_lib::repo::Repo;
|
||||
use jujube_lib::repo::RepoRef;
|
||||
|
||||
pub struct Ui<'a> {
|
||||
cwd: PathBuf,
|
||||
|
@ -84,7 +84,7 @@ impl<'a> Ui<'a> {
|
|||
styler.remove_label();
|
||||
}
|
||||
|
||||
pub fn write_commit_summary<'r>(&mut self, repo: &'r dyn Repo, commit: &Commit) {
|
||||
pub fn write_commit_summary(&mut self, repo: RepoRef, commit: &Commit) {
|
||||
let template_string = self
|
||||
.settings
|
||||
.config()
|
||||
|
|
Loading…
Reference in a new issue