repo: replace RepoRef by Repo trait

This commit is contained in:
Martin von Zweigbergk 2023-02-13 09:52:21 -08:00 committed by Martin von Zweigbergk
parent f6a4cb57da
commit d8997999f2
13 changed files with 246 additions and 404 deletions

View file

@ -75,78 +75,6 @@ pub trait Repo {
fn shortest_unique_change_id_prefix_len(&self, target_id_bytes: &ChangeId) -> usize; fn shortest_unique_change_id_prefix_len(&self, target_id_bytes: &ChangeId) -> usize;
} }
// TODO: Should we implement From<&ReadonlyRepo> and From<&MutableRepo> for
// RepoRef?
#[derive(Clone, Copy)]
pub enum RepoRef<'a> {
Readonly(&'a Arc<ReadonlyRepo>),
Mutable(&'a MutableRepo),
}
impl<'a> RepoRef<'a> {
pub fn base_repo(&self) -> &Arc<ReadonlyRepo> {
match self {
RepoRef::Readonly(repo) => &repo,
RepoRef::Mutable(repo) => &repo.base_repo,
}
}
pub fn store(&self) -> &Arc<Store> {
match self {
RepoRef::Readonly(repo) => repo.store(),
RepoRef::Mutable(repo) => repo.store(),
}
}
pub fn op_store(&self) -> &Arc<dyn OpStore> {
match self {
RepoRef::Readonly(repo) => repo.op_store(),
RepoRef::Mutable(repo) => repo.op_store(),
}
}
pub fn index(&self) -> &'a dyn Index {
match self {
RepoRef::Readonly(repo) => repo.index(),
RepoRef::Mutable(repo) => repo.index(),
}
}
pub fn view(&self) -> &View {
match self {
RepoRef::Readonly(repo) => repo.view(),
RepoRef::Mutable(repo) => repo.view(),
}
}
pub fn resolve_change_id(&self, change_id: &ChangeId) -> Option<Vec<IndexEntry<'a>>> {
// Replace this if we added more efficient lookup method.
let prefix = HexPrefix::from_bytes(change_id.as_bytes());
match self.resolve_change_id_prefix(&prefix) {
PrefixResolution::NoMatch => None,
PrefixResolution::SingleMatch(entries) => Some(entries),
PrefixResolution::AmbiguousMatch => panic!("complete change_id should be unambiguous"),
}
}
pub fn resolve_change_id_prefix(
&self,
prefix: &HexPrefix,
) -> PrefixResolution<Vec<IndexEntry<'a>>> {
match self {
RepoRef::Readonly(repo) => repo.resolve_change_id_prefix(prefix),
RepoRef::Mutable(repo) => repo.resolve_change_id_prefix(prefix),
}
}
pub fn shortest_unique_change_id_prefix_len(&self, target_id: &ChangeId) -> usize {
match self {
RepoRef::Readonly(repo) => repo.shortest_unique_change_id_prefix_len(target_id),
RepoRef::Mutable(repo) => repo.shortest_unique_change_id_prefix_len(target_id),
}
}
}
pub struct ReadonlyRepo { pub struct ReadonlyRepo {
repo_path: PathBuf, repo_path: PathBuf,
store: Arc<Store>, store: Arc<Store>,
@ -271,10 +199,6 @@ impl ReadonlyRepo {
} }
} }
pub fn as_repo_ref<'a>(self: &'a Arc<Self>) -> RepoRef<'a> {
RepoRef::Readonly(self)
}
pub fn repo_path(&self) -> &PathBuf { pub fn repo_path(&self) -> &PathBuf {
&self.repo_path &self.repo_path
} }
@ -654,10 +578,6 @@ impl MutableRepo {
} }
} }
pub fn as_repo_ref(&self) -> RepoRef {
RepoRef::Mutable(self)
}
fn view_mut(&mut self) -> &mut View { fn view_mut(&mut self) -> &mut View {
self.view.get_mut() self.view.get_mut()
} }

View file

@ -36,7 +36,7 @@ use crate::hex_util::to_forward_hex;
use crate::index::{HexPrefix, IndexEntry, PrefixResolution}; use crate::index::{HexPrefix, IndexEntry, PrefixResolution};
use crate::matchers::{EverythingMatcher, Matcher, PrefixMatcher}; use crate::matchers::{EverythingMatcher, Matcher, PrefixMatcher};
use crate::op_store::WorkspaceId; use crate::op_store::WorkspaceId;
use crate::repo::RepoRef; use crate::repo::Repo;
use crate::repo_path::{FsPathParseError, RepoPath}; use crate::repo_path::{FsPathParseError, RepoPath};
use crate::revset_graph_iterator::RevsetGraphIterator; use crate::revset_graph_iterator::RevsetGraphIterator;
use crate::rewrite; use crate::rewrite;
@ -52,7 +52,7 @@ pub enum RevsetError {
StoreError(#[source] BackendError), StoreError(#[source] BackendError),
} }
fn resolve_git_ref(repo: RepoRef, symbol: &str) -> Option<Vec<CommitId>> { fn resolve_git_ref(repo: &dyn Repo, symbol: &str) -> Option<Vec<CommitId>> {
let view = repo.view(); let view = repo.view();
for git_ref_prefix in &["", "refs/", "refs/heads/", "refs/tags/", "refs/remotes/"] { for git_ref_prefix in &["", "refs/", "refs/heads/", "refs/tags/", "refs/remotes/"] {
if let Some(ref_target) = view.git_refs().get(&(git_ref_prefix.to_string() + symbol)) { if let Some(ref_target) = view.git_refs().get(&(git_ref_prefix.to_string() + symbol)) {
@ -62,7 +62,7 @@ fn resolve_git_ref(repo: RepoRef, symbol: &str) -> Option<Vec<CommitId>> {
None None
} }
fn resolve_branch(repo: RepoRef, symbol: &str) -> Option<Vec<CommitId>> { fn resolve_branch(repo: &dyn Repo, symbol: &str) -> Option<Vec<CommitId>> {
if let Some(branch_target) = repo.view().branches().get(symbol) { if let Some(branch_target) = repo.view().branches().get(symbol) {
return Some( return Some(
branch_target branch_target
@ -83,7 +83,7 @@ fn resolve_branch(repo: RepoRef, symbol: &str) -> Option<Vec<CommitId>> {
} }
fn resolve_full_commit_id( fn resolve_full_commit_id(
repo: RepoRef, repo: &dyn Repo,
symbol: &str, symbol: &str,
) -> Result<Option<Vec<CommitId>>, RevsetError> { ) -> Result<Option<Vec<CommitId>>, RevsetError> {
if let Ok(binary_commit_id) = hex::decode(symbol) { if let Ok(binary_commit_id) = hex::decode(symbol) {
@ -103,7 +103,7 @@ fn resolve_full_commit_id(
} }
fn resolve_short_commit_id( fn resolve_short_commit_id(
repo: RepoRef, repo: &dyn Repo,
symbol: &str, symbol: &str,
) -> Result<Option<Vec<CommitId>>, RevsetError> { ) -> Result<Option<Vec<CommitId>>, RevsetError> {
if let Some(prefix) = HexPrefix::new(symbol) { if let Some(prefix) = HexPrefix::new(symbol) {
@ -119,7 +119,7 @@ fn resolve_short_commit_id(
} }
} }
fn resolve_change_id(repo: RepoRef, symbol: &str) -> Result<Option<Vec<CommitId>>, RevsetError> { fn resolve_change_id(repo: &dyn Repo, symbol: &str) -> Result<Option<Vec<CommitId>>, RevsetError> {
if let Some(prefix) = to_forward_hex(symbol).as_deref().and_then(HexPrefix::new) { if let Some(prefix) = to_forward_hex(symbol).as_deref().and_then(HexPrefix::new) {
match repo.resolve_change_id_prefix(&prefix) { match repo.resolve_change_id_prefix(&prefix) {
PrefixResolution::NoMatch => Ok(None), PrefixResolution::NoMatch => Ok(None),
@ -136,7 +136,7 @@ fn resolve_change_id(repo: RepoRef, symbol: &str) -> Result<Option<Vec<CommitId>
} }
pub fn resolve_symbol( pub fn resolve_symbol(
repo: RepoRef, repo: &dyn Repo,
symbol: &str, symbol: &str,
workspace_id: Option<&WorkspaceId>, workspace_id: Option<&WorkspaceId>,
) -> Result<Vec<CommitId>, RevsetError> { ) -> Result<Vec<CommitId>, RevsetError> {
@ -538,7 +538,7 @@ impl RevsetExpression {
pub fn evaluate<'repo>( pub fn evaluate<'repo>(
&self, &self,
repo: RepoRef<'repo>, repo: &'repo dyn Repo,
workspace_ctx: Option<&RevsetWorkspaceContext>, workspace_ctx: Option<&RevsetWorkspaceContext>,
) -> Result<Box<dyn Revset<'repo> + 'repo>, RevsetError> { ) -> Result<Box<dyn Revset<'repo> + 'repo>, RevsetError> {
evaluate_expression(repo, self, workspace_ctx) evaluate_expression(repo, self, workspace_ctx)
@ -1916,7 +1916,7 @@ pub struct RevsetWorkspaceContext<'a> {
} }
pub fn evaluate_expression<'repo>( pub fn evaluate_expression<'repo>(
repo: RepoRef<'repo>, repo: &'repo dyn Repo,
expression: &RevsetExpression, expression: &RevsetExpression,
workspace_ctx: Option<&RevsetWorkspaceContext>, workspace_ctx: Option<&RevsetWorkspaceContext>,
) -> Result<Box<dyn Revset<'repo> + 'repo>, RevsetError> { ) -> Result<Box<dyn Revset<'repo> + 'repo>, RevsetError> {
@ -2127,7 +2127,7 @@ pub fn evaluate_expression<'repo>(
} }
fn revset_for_commit_ids<'revset, 'repo: 'revset>( fn revset_for_commit_ids<'revset, 'repo: 'revset>(
repo: RepoRef<'repo>, repo: &'repo dyn Repo,
commit_ids: &[CommitId], commit_ids: &[CommitId],
) -> Box<dyn Revset<'repo> + 'revset> { ) -> Box<dyn Revset<'repo> + 'revset> {
let index = repo.index(); let index = repo.index();
@ -2141,7 +2141,7 @@ fn revset_for_commit_ids<'revset, 'repo: 'revset>(
} }
pub fn revset_for_commits<'revset, 'repo: 'revset>( pub fn revset_for_commits<'revset, 'repo: 'revset>(
repo: RepoRef<'repo>, repo: &'repo dyn Repo,
commits: &[&Commit], commits: &[&Commit],
) -> Box<dyn Revset<'repo> + 'revset> { ) -> Box<dyn Revset<'repo> + 'revset> {
let index = repo.index(); let index = repo.index();
@ -2162,7 +2162,7 @@ impl<'repo> ToPredicateFn<'repo> for PurePredicateFn<'repo> {
} }
fn build_predicate_fn<'repo>( fn build_predicate_fn<'repo>(
repo: RepoRef<'repo>, repo: &'repo dyn Repo,
predicate: &RevsetFilterPredicate, predicate: &RevsetFilterPredicate,
) -> PurePredicateFn<'repo> { ) -> PurePredicateFn<'repo> {
match predicate { match predicate {
@ -2212,7 +2212,7 @@ fn build_predicate_fn<'repo>(
} }
pub fn filter_by_diff<'revset, 'repo: 'revset>( pub fn filter_by_diff<'revset, 'repo: 'revset>(
repo: RepoRef<'repo>, repo: &'repo dyn Repo,
matcher: impl Borrow<dyn Matcher + 'repo> + 'repo, matcher: impl Borrow<dyn Matcher + 'repo> + 'repo,
candidates: Box<dyn Revset<'repo> + 'revset>, candidates: Box<dyn Revset<'repo> + 'revset>,
) -> Box<dyn Revset<'repo> + 'revset> { ) -> Box<dyn Revset<'repo> + 'revset> {
@ -2222,7 +2222,7 @@ pub fn filter_by_diff<'revset, 'repo: 'revset>(
}) })
} }
fn has_diff_from_parent(repo: RepoRef<'_>, entry: &IndexEntry<'_>, matcher: &dyn Matcher) -> bool { fn has_diff_from_parent(repo: &dyn Repo, entry: &IndexEntry<'_>, matcher: &dyn Matcher) -> bool {
let commit = repo.store().get_commit(&entry.commit_id()).unwrap(); let commit = repo.store().get_commit(&entry.commit_id()).unwrap();
let parents = commit.parents(); let parents = commit.parents();
let from_tree = rewrite::merge_commit_trees(repo, &parents); let from_tree = rewrite::merge_commit_trees(repo, &parents);

View file

@ -20,14 +20,14 @@ use crate::backend::{BackendError, BackendResult, CommitId, ObjectId};
use crate::commit::Commit; use crate::commit::Commit;
use crate::dag_walk; use crate::dag_walk;
use crate::op_store::RefTarget; use crate::op_store::RefTarget;
use crate::repo::{MutableRepo, Repo, RepoRef}; use crate::repo::{MutableRepo, Repo};
use crate::repo_path::RepoPath; use crate::repo_path::RepoPath;
use crate::revset::RevsetExpression; use crate::revset::RevsetExpression;
use crate::settings::UserSettings; use crate::settings::UserSettings;
use crate::tree::{merge_trees, Tree}; use crate::tree::{merge_trees, Tree};
use crate::view::RefName; use crate::view::RefName;
pub fn merge_commit_trees(repo: RepoRef, commits: &[Commit]) -> Tree { pub fn merge_commit_trees(repo: &dyn Repo, commits: &[Commit]) -> Tree {
let store = repo.store(); let store = repo.store();
if commits.is_empty() { if commits.is_empty() {
store store
@ -73,8 +73,8 @@ pub fn rebase_commit(
// Optimization // Optimization
old_commit.tree_id().clone() old_commit.tree_id().clone()
} else { } else {
let old_base_tree = merge_commit_trees(mut_repo.as_repo_ref(), &old_parents); let old_base_tree = merge_commit_trees(mut_repo, &old_parents);
let new_base_tree = merge_commit_trees(mut_repo.as_repo_ref(), new_parents); let new_base_tree = merge_commit_trees(mut_repo, new_parents);
// TODO: pass in labels for the merge parts // TODO: pass in labels for the merge parts
merge_trees(&new_base_tree, &old_base_tree, &old_commit.tree()).unwrap() merge_trees(&new_base_tree, &old_base_tree, &old_commit.tree()).unwrap()
}; };
@ -95,8 +95,8 @@ pub fn back_out_commit(
old_commit: &Commit, old_commit: &Commit,
new_parents: &[Commit], new_parents: &[Commit],
) -> BackendResult<Commit> { ) -> BackendResult<Commit> {
let old_base_tree = merge_commit_trees(mut_repo.as_repo_ref(), &old_commit.parents()); let old_base_tree = merge_commit_trees(mut_repo, &old_commit.parents());
let new_base_tree = merge_commit_trees(mut_repo.as_repo_ref(), new_parents); let new_base_tree = merge_commit_trees(mut_repo, new_parents);
// TODO: pass in labels for the merge parts // TODO: pass in labels for the merge parts
let new_tree_id = merge_trees(&new_base_tree, &old_commit.tree(), &old_base_tree).unwrap(); let new_tree_id = merge_trees(&new_base_tree, &old_commit.tree(), &old_base_tree).unwrap();
let new_parent_ids = new_parents let new_parent_ids = new_parents
@ -157,16 +157,14 @@ impl<'settings, 'repo> DescendantRebaser<'settings, 'repo> {
.parents() .parents()
.minus(&old_commits_expression); .minus(&old_commits_expression);
let heads_to_add = heads_to_add_expression let heads_to_add = heads_to_add_expression
.evaluate(mut_repo.as_repo_ref(), None) .evaluate(mut_repo, None)
.unwrap() .unwrap()
.iter() .iter()
.commit_ids() .commit_ids()
.collect(); .collect();
let to_visit_expression = old_commits_expression.descendants(); let to_visit_expression = old_commits_expression.descendants();
let to_visit_revset = to_visit_expression let to_visit_revset = to_visit_expression.evaluate(mut_repo, None).unwrap();
.evaluate(mut_repo.as_repo_ref(), None)
.unwrap();
let to_visit_entries = to_visit_revset.iter().collect_vec(); let to_visit_entries = to_visit_revset.iter().collect_vec();
drop(to_visit_revset); drop(to_visit_revset);
let index = mut_repo.index(); let index = mut_repo.index();

View file

@ -15,7 +15,7 @@
use std::path::Path; use std::path::Path;
use jujutsu_lib::backend::CommitId; use jujutsu_lib::backend::CommitId;
use jujutsu_lib::repo::{Repo, RepoRef}; use jujutsu_lib::repo::Repo;
use test_case::test_case; use test_case::test_case;
use testutils::{create_random_commit, write_random_commit, TestRepo}; use testutils::{create_random_commit, write_random_commit, TestRepo};
@ -122,7 +122,7 @@ fn test_concurrent_operations(use_git: bool) {
assert_eq!(list_dir(&op_heads_dir), vec![merged_op_id.hex()]); assert_eq!(list_dir(&op_heads_dir), vec![merged_op_id.hex()]);
} }
fn assert_heads(repo: RepoRef, expected: Vec<&CommitId>) { fn assert_heads(repo: &dyn Repo, expected: Vec<&CommitId>) {
let expected = expected.iter().cloned().cloned().collect(); let expected = expected.iter().cloned().cloned().collect();
assert_eq!(*repo.view().heads(), expected); assert_eq!(*repo.view().heads(), expected);
} }
@ -147,9 +147,9 @@ fn test_isolation(use_git: bool) {
let mut tx2 = repo.start_transaction(&settings, "transaction 2"); let mut tx2 = repo.start_transaction(&settings, "transaction 2");
let mut_repo2 = tx2.mut_repo(); let mut_repo2 = tx2.mut_repo();
assert_heads(repo.as_repo_ref(), vec![initial.id()]); assert_heads(&repo, vec![initial.id()]);
assert_heads(mut_repo1.as_repo_ref(), vec![initial.id()]); assert_heads(mut_repo1, vec![initial.id()]);
assert_heads(mut_repo2.as_repo_ref(), vec![initial.id()]); assert_heads(mut_repo2, vec![initial.id()]);
let rewrite1 = mut_repo1 let rewrite1 = mut_repo1
.rewrite_commit(&settings, &initial) .rewrite_commit(&settings, &initial)
@ -166,19 +166,19 @@ fn test_isolation(use_git: bool) {
// Neither transaction has committed yet, so each transaction sees its own // Neither transaction has committed yet, so each transaction sees its own
// commit. // commit.
assert_heads(repo.as_repo_ref(), vec![initial.id()]); assert_heads(&repo, vec![initial.id()]);
assert_heads(mut_repo1.as_repo_ref(), vec![rewrite1.id()]); assert_heads(mut_repo1, vec![rewrite1.id()]);
assert_heads(mut_repo2.as_repo_ref(), vec![rewrite2.id()]); assert_heads(mut_repo2, vec![rewrite2.id()]);
// The base repo and tx2 don't see the commits from tx1. // The base repo and tx2 don't see the commits from tx1.
tx1.commit(); tx1.commit();
assert_heads(repo.as_repo_ref(), vec![initial.id()]); assert_heads(&repo, vec![initial.id()]);
assert_heads(mut_repo2.as_repo_ref(), vec![rewrite2.id()]); assert_heads(mut_repo2, vec![rewrite2.id()]);
// The base repo still doesn't see the commits after both transactions commit. // The base repo still doesn't see the commits after both transactions commit.
tx2.commit(); tx2.commit();
assert_heads(repo.as_repo_ref(), vec![initial.id()]); assert_heads(&repo, vec![initial.id()]);
// After reload, the base repo sees both rewrites. // After reload, the base repo sees both rewrites.
let repo = repo.reload_at_head(&settings).unwrap(); let repo = repo.reload_at_head(&settings).unwrap();
assert_heads(repo.as_repo_ref(), vec![rewrite1.id(), rewrite2.id()]); assert_heads(&repo, vec![rewrite1.id(), rewrite2.id()]);
} }

File diff suppressed because it is too large Load diff

View file

@ -48,7 +48,7 @@ fn test_graph_iterator_linearized(skip_transitive_edges: bool) {
.unwrap(); .unwrap();
let pos_a = repo.index().commit_id_to_pos(commit_a.id()).unwrap(); let pos_a = repo.index().commit_id_to_pos(commit_a.id()).unwrap();
let revset = revset_for_commits(repo.as_repo_ref(), &[&commit_a, &commit_d]); let revset = revset_for_commits(&repo, &[&commit_a, &commit_d]);
let commits = revset let commits = revset
.iter() .iter()
.graph() .graph()
@ -96,10 +96,7 @@ fn test_graph_iterator_virtual_octopus(skip_transitive_edges: bool) {
let pos_b = repo.index().commit_id_to_pos(commit_b.id()).unwrap(); let pos_b = repo.index().commit_id_to_pos(commit_b.id()).unwrap();
let pos_c = repo.index().commit_id_to_pos(commit_c.id()).unwrap(); let pos_c = repo.index().commit_id_to_pos(commit_c.id()).unwrap();
let revset = revset_for_commits( let revset = revset_for_commits(&repo, &[&commit_a, &commit_b, &commit_c, &commit_f]);
repo.as_repo_ref(),
&[&commit_a, &commit_b, &commit_c, &commit_f],
);
let commits = revset let commits = revset
.iter() .iter()
.graph() .graph()
@ -156,7 +153,7 @@ fn test_graph_iterator_simple_fork(skip_transitive_edges: bool) {
.unwrap(); .unwrap();
let pos_a = repo.index().commit_id_to_pos(commit_a.id()).unwrap(); let pos_a = repo.index().commit_id_to_pos(commit_a.id()).unwrap();
let revset = revset_for_commits(repo.as_repo_ref(), &[&commit_a, &commit_c, &commit_e]); let revset = revset_for_commits(&repo, &[&commit_a, &commit_c, &commit_e]);
let commits = revset let commits = revset
.iter() .iter()
.graph() .graph()
@ -205,7 +202,7 @@ fn test_graph_iterator_multiple_missing(skip_transitive_edges: bool) {
let pos_b = repo.index().commit_id_to_pos(commit_b.id()).unwrap(); let pos_b = repo.index().commit_id_to_pos(commit_b.id()).unwrap();
let pos_c = repo.index().commit_id_to_pos(commit_c.id()).unwrap(); let pos_c = repo.index().commit_id_to_pos(commit_c.id()).unwrap();
let revset = revset_for_commits(repo.as_repo_ref(), &[&commit_b, &commit_f]); let revset = revset_for_commits(&repo, &[&commit_b, &commit_f]);
let commits = revset let commits = revset
.iter() .iter()
.graph() .graph()
@ -259,7 +256,7 @@ fn test_graph_iterator_edge_to_ancestor(skip_transitive_edges: bool) {
let pos_c = repo.index().commit_id_to_pos(commit_c.id()).unwrap(); let pos_c = repo.index().commit_id_to_pos(commit_c.id()).unwrap();
let pos_d = repo.index().commit_id_to_pos(commit_d.id()).unwrap(); let pos_d = repo.index().commit_id_to_pos(commit_d.id()).unwrap();
let revset = revset_for_commits(repo.as_repo_ref(), &[&commit_c, &commit_d, &commit_f]); let revset = revset_for_commits(&repo, &[&commit_c, &commit_d, &commit_f]);
let commits = revset let commits = revset
.iter() .iter()
.graph() .graph()
@ -337,7 +334,7 @@ fn test_graph_iterator_edge_escapes_from_(skip_transitive_edges: bool) {
let pos_h = repo.index().commit_id_to_pos(commit_h.id()).unwrap(); let pos_h = repo.index().commit_id_to_pos(commit_h.id()).unwrap();
let revset = revset_for_commits( let revset = revset_for_commits(
repo.as_repo_ref(), &repo,
&[&commit_a, &commit_d, &commit_g, &commit_h, &commit_j], &[&commit_a, &commit_d, &commit_g, &commit_h, &commit_j],
); );
let commits = revset let commits = revset
@ -420,7 +417,7 @@ fn test_reverse_graph_iterator() {
let pos_f = repo.index().commit_id_to_pos(commit_f.id()).unwrap(); let pos_f = repo.index().commit_id_to_pos(commit_f.id()).unwrap();
let revset = revset_for_commits( let revset = revset_for_commits(
repo.as_repo_ref(), &repo,
&[&commit_a, &commit_c, &commit_d, &commit_e, &commit_f], &[&commit_a, &commit_c, &commit_d, &commit_e, &commit_f],
); );
let commits = revset.iter().graph().reversed().collect_vec(); let commits = revset.iter().graph().reversed().collect_vec();

View file

@ -38,7 +38,7 @@ use jujutsu_lib::op_heads_store::{self, OpHeadResolutionError, OpHeadsStore};
use jujutsu_lib::op_store::{OpStore, OpStoreError, OperationId, RefTarget, WorkspaceId}; use jujutsu_lib::op_store::{OpStore, OpStoreError, OperationId, RefTarget, WorkspaceId};
use jujutsu_lib::operation::Operation; use jujutsu_lib::operation::Operation;
use jujutsu_lib::repo::{ use jujutsu_lib::repo::{
CheckOutCommitError, EditCommitError, MutableRepo, ReadonlyRepo, Repo, RepoLoader, RepoRef, CheckOutCommitError, EditCommitError, MutableRepo, ReadonlyRepo, Repo, RepoLoader,
RewriteRootCommit, StoreFactories, RewriteRootCommit, StoreFactories,
}; };
use jujutsu_lib::repo_path::{FsPathParseError, RepoPath}; use jujutsu_lib::repo_path::{FsPathParseError, RepoPath};
@ -487,7 +487,7 @@ impl WorkspaceCommandHelper {
// operation. // operation.
// TODO: Parsed template can be cached if it doesn't capture repo // TODO: Parsed template can be cached if it doesn't capture repo
parse_commit_summary_template( parse_commit_summary_template(
repo.as_repo_ref(), &repo,
workspace.workspace_id(), workspace.workspace_id(),
&template_aliases_map, &template_aliases_map,
&settings, &settings,
@ -799,7 +799,7 @@ impl WorkspaceCommandHelper {
&'repo self, &'repo self,
revset_expression: &RevsetExpression, revset_expression: &RevsetExpression,
) -> Result<Box<dyn Revset<'repo> + 'repo>, RevsetError> { ) -> Result<Box<dyn Revset<'repo> + 'repo>, RevsetError> {
revset_expression.evaluate(self.repo.as_repo_ref(), Some(&self.revset_context())) revset_expression.evaluate(&self.repo, Some(&self.revset_context()))
} }
fn revset_context(&self) -> RevsetWorkspaceContext { fn revset_context(&self) -> RevsetWorkspaceContext {
@ -815,7 +815,7 @@ impl WorkspaceCommandHelper {
template_text: &str, template_text: &str,
) -> Result<Box<dyn Template<Commit> + '_>, TemplateParseError> { ) -> Result<Box<dyn Template<Commit> + '_>, TemplateParseError> {
template_parser::parse_commit_template( template_parser::parse_commit_template(
self.repo.as_repo_ref(), &self.repo,
self.workspace_id(), self.workspace_id(),
template_text, template_text,
&self.template_aliases_map, &self.template_aliases_map,
@ -837,7 +837,7 @@ impl WorkspaceCommandHelper {
commit: &Commit, commit: &Commit,
) -> std::io::Result<()> { ) -> std::io::Result<()> {
let template = parse_commit_summary_template( let template = parse_commit_summary_template(
self.repo.as_repo_ref(), &self.repo,
self.workspace_id(), self.workspace_id(),
&self.template_aliases_map, &self.template_aliases_map,
&self.settings, &self.settings,
@ -971,7 +971,7 @@ impl WorkspaceCommandHelper {
if self.may_update_working_copy { if self.may_update_working_copy {
let workspace_id = self.workspace_id().to_owned(); let workspace_id = self.workspace_id().to_owned();
let summary_template = parse_commit_summary_template( let summary_template = parse_commit_summary_template(
self.repo.as_repo_ref(), &self.repo,
&workspace_id, &workspace_id,
&self.template_aliases_map, &self.template_aliases_map,
&self.settings, &self.settings,
@ -1122,7 +1122,7 @@ impl WorkspaceCommandTransaction<'_> {
commit: &Commit, commit: &Commit,
) -> std::io::Result<()> { ) -> std::io::Result<()> {
let template = parse_commit_summary_template( let template = parse_commit_summary_template(
self.tx.repo().as_repo_ref(), self.tx.repo(),
self.helper.workspace_id(), self.helper.workspace_id(),
&self.helper.template_aliases_map, &self.helper.template_aliases_map,
&self.helper.settings, &self.helper.settings,
@ -1557,7 +1557,7 @@ fn load_template_aliases(
} }
fn parse_commit_summary_template<'a>( fn parse_commit_summary_template<'a>(
repo: RepoRef<'a>, repo: &'a dyn Repo,
workspace_id: &WorkspaceId, workspace_id: &WorkspaceId,
aliases_map: &TemplateAliasesMap, aliases_map: &TemplateAliasesMap,
settings: &UserSettings, settings: &UserSettings,

View file

@ -4,7 +4,7 @@ use clap::builder::NonEmptyStringValueParser;
use itertools::Itertools; use itertools::Itertools;
use jujutsu_lib::backend::{CommitId, ObjectId}; use jujutsu_lib::backend::{CommitId, ObjectId};
use jujutsu_lib::op_store::RefTarget; use jujutsu_lib::op_store::RefTarget;
use jujutsu_lib::repo::{Repo, RepoRef}; use jujutsu_lib::repo::Repo;
use jujutsu_lib::view::View; use jujutsu_lib::view::View;
use crate::cli_util::{user_error, user_error_with_hint, CommandError, CommandHelper, RevisionArg}; use crate::cli_util::{user_error, user_error_with_hint, CommandError, CommandHelper, RevisionArg};
@ -170,11 +170,7 @@ fn cmd_branch_set(
workspace_command.resolve_single_rev(args.revision.as_deref().unwrap_or("@"))?; workspace_command.resolve_single_rev(args.revision.as_deref().unwrap_or("@"))?;
if !args.allow_backwards if !args.allow_backwards
&& !branch_names.iter().all(|branch_name| { && !branch_names.iter().all(|branch_name| {
is_fast_forward( is_fast_forward(workspace_command.repo(), branch_name, target_commit.id())
workspace_command.repo().as_repo_ref(),
branch_name,
target_commit.id(),
)
}) })
{ {
return Err(user_error_with_hint( return Err(user_error_with_hint(
@ -340,7 +336,7 @@ fn validate_branch_names_exist(view: &View, names: &[String]) -> Result<(), Comm
Ok(()) Ok(())
} }
fn is_fast_forward(repo: RepoRef, branch_name: &str, new_target_id: &CommitId) -> bool { fn is_fast_forward(repo: &dyn Repo, branch_name: &str, new_target_id: &CommitId) -> bool {
if let Some(current_target) = repo.view().get_local_branch(branch_name) { if let Some(current_target) = repo.view().get_local_branch(branch_name) {
current_target current_target
.adds() .adds()

View file

@ -12,7 +12,7 @@ use jujutsu_lib::backend::ObjectId;
use jujutsu_lib::git::{self, GitFetchError, GitRefUpdate}; use jujutsu_lib::git::{self, GitFetchError, GitRefUpdate};
use jujutsu_lib::op_store::{BranchTarget, RefTarget}; use jujutsu_lib::op_store::{BranchTarget, RefTarget};
use jujutsu_lib::refs::{classify_branch_push_action, BranchPushAction, BranchPushUpdate}; use jujutsu_lib::refs::{classify_branch_push_action, BranchPushAction, BranchPushUpdate};
use jujutsu_lib::repo::{Repo, RepoRef}; use jujutsu_lib::repo::Repo;
use jujutsu_lib::settings::UserSettings; use jujutsu_lib::settings::UserSettings;
use jujutsu_lib::store::Store; use jujutsu_lib::store::Store;
use jujutsu_lib::view::View; use jujutsu_lib::view::View;
@ -547,11 +547,9 @@ fn cmd_git_push(
if !seen_branches.insert(branch_name.clone()) { if !seen_branches.insert(branch_name.clone()) {
continue; continue;
} }
if let Some(update) = branch_updates_for_push( if let Some(update) =
workspace_command.repo().as_repo_ref(), branch_updates_for_push(workspace_command.repo(), &remote, branch_name)?
&remote, {
branch_name,
)? {
branch_updates.push((branch_name.clone(), update)); branch_updates.push((branch_name.clone(), update));
} else { } else {
writeln!( writeln!(
@ -620,9 +618,7 @@ fn cmd_git_push(
} }
tx.mut_repo() tx.mut_repo()
.set_local_branch(branch_name.clone(), RefTarget::Normal(commit.id().clone())); .set_local_branch(branch_name.clone(), RefTarget::Normal(commit.id().clone()));
if let Some(update) = if let Some(update) = branch_updates_for_push(tx.mut_repo(), &remote, &branch_name)? {
branch_updates_for_push(tx.mut_repo().as_repo_ref(), &remote, &branch_name)?
{
branch_updates.push((branch_name.clone(), update)); branch_updates.push((branch_name.clone(), update));
} else { } else {
writeln!( writeln!(
@ -822,7 +818,7 @@ fn cmd_git_push(
} }
fn branch_updates_for_push( fn branch_updates_for_push(
repo: RepoRef, repo: &dyn Repo,
remote_name: &str, remote_name: &str,
branch_name: &str, branch_name: &str,
) -> Result<Option<BranchPushUpdate>, CommandError> { ) -> Result<Option<BranchPushUpdate>, CommandError> {

View file

@ -1260,7 +1260,7 @@ fn cmd_diff(ui: &mut Ui, command: &CommandHelper, args: &DiffArgs) -> Result<(),
let commit = let commit =
workspace_command.resolve_single_rev(args.revision.as_deref().unwrap_or("@"))?; workspace_command.resolve_single_rev(args.revision.as_deref().unwrap_or("@"))?;
let parents = commit.parents(); let parents = commit.parents();
from_tree = merge_commit_trees(workspace_command.repo().as_repo_ref(), &parents); from_tree = merge_commit_trees(workspace_command.repo(), &parents);
to_tree = commit.tree() to_tree = commit.tree()
} }
let matcher = workspace_command.matcher_from_values(&args.paths)?; let matcher = workspace_command.matcher_from_values(&args.paths)?;
@ -1371,7 +1371,7 @@ fn cmd_status(
} }
if let Some(wc_commit) = &maybe_wc_commit { if let Some(wc_commit) = &maybe_wc_commit {
let parent_tree = merge_commit_trees(repo.as_repo_ref(), &wc_commit.parents()); let parent_tree = merge_commit_trees(repo, &wc_commit.parents());
let tree = wc_commit.tree(); let tree = wc_commit.tree();
if tree.id() == parent_tree.id() { if tree.id() == parent_tree.id() {
formatter.write_str("The working copy is clean\n")?; formatter.write_str("The working copy is clean\n")?;
@ -1409,7 +1409,7 @@ fn cmd_log(ui: &mut Ui, command: &CommandHelper, args: &LogArgs) -> Result<(), C
let matcher = workspace_command.matcher_from_values(&args.paths)?; let matcher = workspace_command.matcher_from_values(&args.paths)?;
let revset = workspace_command.evaluate_revset(&revset_expression)?; let revset = workspace_command.evaluate_revset(&revset_expression)?;
let revset = if !args.paths.is_empty() { let revset = if !args.paths.is_empty() {
revset::filter_by_diff(repo.as_repo_ref(), matcher.as_ref(), revset) revset::filter_by_diff(repo, matcher.as_ref(), revset)
} else { } else {
revset revset
}; };
@ -1667,12 +1667,9 @@ fn rebase_to_dest_parent(
if source.parent_ids() == destination.parent_ids() { if source.parent_ids() == destination.parent_ids() {
Ok(source.tree()) Ok(source.tree())
} else { } else {
let destination_parent_tree = merge_commit_trees( let destination_parent_tree =
workspace_command.repo().as_repo_ref(), merge_commit_trees(workspace_command.repo(), &destination.parents());
&destination.parents(), let source_parent_tree = merge_commit_trees(workspace_command.repo(), &source.parents());
);
let source_parent_tree =
merge_commit_trees(workspace_command.repo().as_repo_ref(), &source.parents());
let rebased_tree_id = merge_trees( let rebased_tree_id = merge_trees(
&destination_parent_tree, &destination_parent_tree,
&source_parent_tree, &source_parent_tree,
@ -2003,7 +2000,7 @@ fn cmd_new(ui: &mut Ui, command: &CommandHelper, args: &NewArgs) -> Result<(), C
if new_parents_commits.len() > 1 { if new_parents_commits.len() > 1 {
new_parents_commits.retain(|c| c != &root_commit); new_parents_commits.retain(|c| c != &root_commit);
} }
let merged_tree = merge_commit_trees(tx.base_repo().as_repo_ref(), &new_parents_commits); let merged_tree = merge_commit_trees(tx.base_repo(), &new_parents_commits);
let new_parents_commit_id = new_parents_commits.iter().map(|c| c.id().clone()).collect(); let new_parents_commit_id = new_parents_commits.iter().map(|c| c.id().clone()).collect();
new_commit = tx new_commit = tx
.mut_repo() .mut_repo()
@ -2024,7 +2021,7 @@ fn cmd_new(ui: &mut Ui, command: &CommandHelper, args: &NewArgs) -> Result<(), C
)?; )?;
} }
} else { } else {
let merged_tree = merge_commit_trees(tx.base_repo().as_repo_ref(), &target_commits); let merged_tree = merge_commit_trees(tx.base_repo(), &target_commits);
new_commit = tx new_commit = tx
.mut_repo() .mut_repo()
.new_commit( .new_commit(
@ -2118,7 +2115,7 @@ fn cmd_move(ui: &mut Ui, command: &CommandHelper, args: &MoveArgs) -> Result<(),
source.id().hex(), source.id().hex(),
destination.id().hex() destination.id().hex()
)); ));
let parent_tree = merge_commit_trees(tx.base_repo().as_repo_ref(), &source.parents()); let parent_tree = merge_commit_trees(tx.base_repo(), &source.parents());
let source_tree = source.tree(); let source_tree = source.tree();
let instructions = format!( let instructions = format!(
"\ "\
@ -2280,7 +2277,7 @@ fn cmd_unsquash(
workspace_command.check_rewritable(parent)?; workspace_command.check_rewritable(parent)?;
let mut tx = let mut tx =
workspace_command.start_transaction(&format!("unsquash commit {}", commit.id().hex())); workspace_command.start_transaction(&format!("unsquash commit {}", commit.id().hex()));
let parent_base_tree = merge_commit_trees(tx.base_repo().as_repo_ref(), &parent.parents()); let parent_base_tree = merge_commit_trees(tx.base_repo(), &parent.parents());
let new_parent_tree_id; let new_parent_tree_id;
if args.interactive { if args.interactive {
let instructions = format!( let instructions = format!(
@ -2576,7 +2573,7 @@ Adjust the right side until it shows the contents you want. If you
don't make any changes, then the operation will be aborted.", don't make any changes, then the operation will be aborted.",
tx.format_commit_summary(&target_commit), tx.format_commit_summary(&target_commit),
); );
let base_tree = merge_commit_trees(tx.base_repo().as_repo_ref(), base_commits.as_slice()); let base_tree = merge_commit_trees(tx.base_repo(), base_commits.as_slice());
let tree_id = tx.edit_diff(ui, &base_tree, &target_commit.tree(), &instructions)?; let tree_id = tx.edit_diff(ui, &base_tree, &target_commit.tree(), &instructions)?;
if &tree_id == target_commit.tree_id() { if &tree_id == target_commit.tree_id() {
ui.write("Nothing changed.\n")?; ui.write("Nothing changed.\n")?;
@ -2651,7 +2648,7 @@ fn cmd_split(ui: &mut Ui, command: &CommandHelper, args: &SplitArgs) -> Result<(
let matcher = workspace_command.matcher_from_values(&args.paths)?; let matcher = workspace_command.matcher_from_values(&args.paths)?;
let mut tx = let mut tx =
workspace_command.start_transaction(&format!("split commit {}", commit.id().hex())); workspace_command.start_transaction(&format!("split commit {}", commit.id().hex()));
let base_tree = merge_commit_trees(tx.base_repo().as_repo_ref(), &commit.parents()); let base_tree = merge_commit_trees(tx.base_repo(), &commit.parents());
let interactive = args.paths.is_empty(); let interactive = args.paths.is_empty();
let instructions = format!( let instructions = format!(
"\ "\

View file

@ -137,7 +137,7 @@ pub fn show_patch(
formats: &[DiffFormat], formats: &[DiffFormat],
) -> Result<(), CommandError> { ) -> Result<(), CommandError> {
let parents = commit.parents(); let parents = commit.parents();
let from_tree = rewrite::merge_commit_trees(workspace_command.repo().as_repo_ref(), &parents); let from_tree = rewrite::merge_commit_trees(workspace_command.repo(), &parents);
let to_tree = commit.tree(); let to_tree = commit.tree();
show_diff( show_diff(
formatter, formatter,

View file

@ -21,7 +21,7 @@ use itertools::Itertools as _;
use jujutsu_lib::backend::{Signature, Timestamp}; use jujutsu_lib::backend::{Signature, Timestamp};
use jujutsu_lib::commit::Commit; use jujutsu_lib::commit::Commit;
use jujutsu_lib::op_store::WorkspaceId; use jujutsu_lib::op_store::WorkspaceId;
use jujutsu_lib::repo::RepoRef; use jujutsu_lib::repo::Repo;
use jujutsu_lib::rewrite; use jujutsu_lib::rewrite;
use pest::iterators::{Pair, Pairs}; use pest::iterators::{Pair, Pairs};
use pest::Parser; use pest::Parser;
@ -1030,7 +1030,7 @@ fn build_global_function<'a, C: 'a>(
} }
fn build_commit_keyword<'a>( fn build_commit_keyword<'a>(
repo: RepoRef<'a>, repo: &'a dyn Repo,
workspace_id: &WorkspaceId, workspace_id: &WorkspaceId,
name: &str, name: &str,
span: pest::Span, span: pest::Span,
@ -1112,7 +1112,7 @@ fn build_expression<'a, C: 'a>(
// TODO: We'll probably need a trait that abstracts the Property enum and // TODO: We'll probably need a trait that abstracts the Property enum and
// keyword/method parsing functions per the top-level context. // keyword/method parsing functions per the top-level context.
pub fn parse_commit_template<'a>( pub fn parse_commit_template<'a>(
repo: RepoRef<'a>, repo: &'a dyn Repo,
workspace_id: &WorkspaceId, workspace_id: &WorkspaceId,
template_text: &str, template_text: &str,
aliases_map: &TemplateAliasesMap, aliases_map: &TemplateAliasesMap,

View file

@ -19,7 +19,7 @@ use itertools::Itertools;
use jujutsu_lib::backend::{ChangeId, CommitId, ObjectId, Signature, Timestamp}; use jujutsu_lib::backend::{ChangeId, CommitId, ObjectId, Signature, Timestamp};
use jujutsu_lib::commit::Commit; use jujutsu_lib::commit::Commit;
use jujutsu_lib::hex_util::to_reverse_hex; use jujutsu_lib::hex_util::to_reverse_hex;
use jujutsu_lib::repo::RepoRef; use jujutsu_lib::repo::Repo;
use crate::formatter::{Formatter, PlainTextFormatter}; use crate::formatter::{Formatter, PlainTextFormatter};
use crate::time_util; use crate::time_util;
@ -329,7 +329,7 @@ impl<C, T: Template<C>> TemplateProperty<C> for PlainTextFormattedProperty<T> {
} }
pub struct WorkingCopiesProperty<'a> { pub struct WorkingCopiesProperty<'a> {
pub repo: RepoRef<'a>, pub repo: &'a dyn Repo,
} }
impl TemplateProperty<Commit> for WorkingCopiesProperty<'_> { impl TemplateProperty<Commit> for WorkingCopiesProperty<'_> {
@ -351,7 +351,7 @@ impl TemplateProperty<Commit> for WorkingCopiesProperty<'_> {
} }
pub struct BranchProperty<'a> { pub struct BranchProperty<'a> {
pub repo: RepoRef<'a>, pub repo: &'a dyn Repo,
} }
impl TemplateProperty<Commit> for BranchProperty<'_> { impl TemplateProperty<Commit> for BranchProperty<'_> {
@ -391,7 +391,7 @@ impl TemplateProperty<Commit> for BranchProperty<'_> {
} }
pub struct TagProperty<'a> { pub struct TagProperty<'a> {
pub repo: RepoRef<'a>, pub repo: &'a dyn Repo,
} }
impl TemplateProperty<Commit> for TagProperty<'_> { impl TemplateProperty<Commit> for TagProperty<'_> {
@ -413,7 +413,7 @@ impl TemplateProperty<Commit> for TagProperty<'_> {
} }
pub struct GitRefsProperty<'a> { pub struct GitRefsProperty<'a> {
pub repo: RepoRef<'a>, pub repo: &'a dyn Repo,
} }
impl TemplateProperty<Commit> for GitRefsProperty<'_> { impl TemplateProperty<Commit> for GitRefsProperty<'_> {
@ -437,11 +437,11 @@ impl TemplateProperty<Commit> for GitRefsProperty<'_> {
} }
pub struct GitHeadProperty<'a> { pub struct GitHeadProperty<'a> {
repo: RepoRef<'a>, repo: &'a dyn Repo,
} }
impl<'a> GitHeadProperty<'a> { impl<'a> GitHeadProperty<'a> {
pub fn new(repo: RepoRef<'a>) -> Self { pub fn new(repo: &'a dyn Repo) -> Self {
Self { repo } Self { repo }
} }
} }
@ -542,13 +542,13 @@ where
/// Type-erased `CommitId`/`ChangeId`. /// Type-erased `CommitId`/`ChangeId`.
#[derive(Clone)] #[derive(Clone)]
pub struct CommitOrChangeId<'a> { pub struct CommitOrChangeId<'a> {
repo: RepoRef<'a>, repo: &'a dyn Repo,
id_bytes: Vec<u8>, id_bytes: Vec<u8>,
is_commit_id: bool, is_commit_id: bool,
} }
impl<'a> CommitOrChangeId<'a> { impl<'a> CommitOrChangeId<'a> {
pub fn commit_id(repo: RepoRef<'a>, id: &CommitId) -> Self { pub fn commit_id(repo: &'a dyn Repo, id: &CommitId) -> Self {
CommitOrChangeId { CommitOrChangeId {
repo, repo,
id_bytes: id.to_bytes(), id_bytes: id.to_bytes(),
@ -556,7 +556,7 @@ impl<'a> CommitOrChangeId<'a> {
} }
} }
pub fn change_id(repo: RepoRef<'a>, id: &ChangeId) -> Self { pub fn change_id(repo: &'a dyn Repo, id: &ChangeId) -> Self {
CommitOrChangeId { CommitOrChangeId {
repo, repo,
id_bytes: id.to_bytes(), id_bytes: id.to_bytes(),