mirror of
https://github.com/martinvonz/jj.git
synced 2024-11-28 17:41:14 +00:00
rewrite: propagate errors from merge_trees()
This commit is contained in:
parent
134efabcef
commit
b297c0c0d8
6 changed files with 45 additions and 45 deletions
|
@ -890,7 +890,7 @@ fn has_diff_from_parent(
|
|||
return false;
|
||||
}
|
||||
}
|
||||
let from_tree = rewrite::merge_commit_trees_without_repo(store, &index, &parents);
|
||||
let from_tree = rewrite::merge_commit_trees_without_repo(store, &index, &parents).unwrap();
|
||||
let to_tree = commit.tree();
|
||||
from_tree.diff(&to_tree, matcher).next().is_some()
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ use crate::simple_op_store::SimpleOpStore;
|
|||
use crate::store::Store;
|
||||
use crate::submodule_store::SubmoduleStore;
|
||||
use crate::transaction::Transaction;
|
||||
use crate::tree::TreeMergeError;
|
||||
use crate::view::{RefName, View};
|
||||
use crate::{backend, dag_walk, op_store};
|
||||
|
||||
|
@ -291,7 +292,7 @@ impl ReadonlyRepo {
|
|||
pub fn reload_at_head(
|
||||
&self,
|
||||
user_settings: &UserSettings,
|
||||
) -> Result<Arc<ReadonlyRepo>, OpHeadResolutionError<BackendError>> {
|
||||
) -> Result<Arc<ReadonlyRepo>, OpHeadResolutionError<TreeMergeError>> {
|
||||
self.loader().load_at_head(user_settings)
|
||||
}
|
||||
|
||||
|
@ -642,7 +643,7 @@ impl RepoLoader {
|
|||
pub fn load_at_head(
|
||||
&self,
|
||||
user_settings: &UserSettings,
|
||||
) -> Result<Arc<ReadonlyRepo>, OpHeadResolutionError<BackendError>> {
|
||||
) -> Result<Arc<ReadonlyRepo>, OpHeadResolutionError<TreeMergeError>> {
|
||||
let op = op_heads_store::resolve_op_heads(
|
||||
self.op_heads_store.as_ref(),
|
||||
&self.op_store,
|
||||
|
@ -683,7 +684,7 @@ impl RepoLoader {
|
|||
&self,
|
||||
op_heads: Vec<Operation>,
|
||||
user_settings: &UserSettings,
|
||||
) -> Result<Operation, BackendError> {
|
||||
) -> Result<Operation, TreeMergeError> {
|
||||
let base_repo = self.load_at(&op_heads[0]);
|
||||
let mut tx = base_repo.start_transaction(user_settings, "resolve concurrent operations");
|
||||
for other_op_head in op_heads.into_iter().skip(1) {
|
||||
|
@ -834,7 +835,7 @@ impl MutableRepo {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn rebase_descendants(&mut self, settings: &UserSettings) -> Result<usize, BackendError> {
|
||||
pub fn rebase_descendants(&mut self, settings: &UserSettings) -> Result<usize, TreeMergeError> {
|
||||
if !self.has_rewrites() {
|
||||
// Optimization
|
||||
return Ok(0);
|
||||
|
|
|
@ -17,7 +17,7 @@ use std::sync::Arc;
|
|||
|
||||
use itertools::{process_results, Itertools};
|
||||
|
||||
use crate::backend::{BackendError, BackendResult, CommitId, ObjectId};
|
||||
use crate::backend::{BackendError, CommitId, ObjectId};
|
||||
use crate::commit::Commit;
|
||||
use crate::dag_walk;
|
||||
use crate::index::Index;
|
||||
|
@ -27,10 +27,10 @@ use crate::repo_path::RepoPath;
|
|||
use crate::revset::{RevsetExpression, RevsetIteratorExt};
|
||||
use crate::settings::UserSettings;
|
||||
use crate::store::Store;
|
||||
use crate::tree::{merge_trees, Tree};
|
||||
use crate::tree::{merge_trees, Tree, TreeMergeError};
|
||||
use crate::view::RefName;
|
||||
|
||||
pub fn merge_commit_trees(repo: &dyn Repo, commits: &[Commit]) -> Tree {
|
||||
pub fn merge_commit_trees(repo: &dyn Repo, commits: &[Commit]) -> Result<Tree, TreeMergeError> {
|
||||
merge_commit_trees_without_repo(repo.store(), repo.index(), commits)
|
||||
}
|
||||
|
||||
|
@ -38,11 +38,9 @@ pub fn merge_commit_trees_without_repo(
|
|||
store: &Arc<Store>,
|
||||
index: &dyn Index,
|
||||
commits: &[Commit],
|
||||
) -> Tree {
|
||||
) -> Result<Tree, TreeMergeError> {
|
||||
if commits.is_empty() {
|
||||
store
|
||||
.get_tree(&RepoPath::root(), store.empty_tree_id())
|
||||
.unwrap()
|
||||
Ok(store.get_tree(&RepoPath::root(), store.empty_tree_id())?)
|
||||
} else {
|
||||
let mut new_tree = commits[0].tree();
|
||||
let commit_ids = commits
|
||||
|
@ -51,15 +49,15 @@ pub fn merge_commit_trees_without_repo(
|
|||
.collect_vec();
|
||||
for (i, other_commit) in commits.iter().enumerate().skip(1) {
|
||||
let ancestor_ids = index.common_ancestors(&commit_ids[0..i], &[commit_ids[i].clone()]);
|
||||
let ancestors = ancestor_ids
|
||||
let ancestors: Vec<_> = ancestor_ids
|
||||
.iter()
|
||||
.map(|id| store.get_commit(id).unwrap())
|
||||
.collect_vec();
|
||||
let ancestor_tree = merge_commit_trees_without_repo(store, index, &ancestors);
|
||||
let new_tree_id = merge_trees(&new_tree, &ancestor_tree, &other_commit.tree()).unwrap();
|
||||
new_tree = store.get_tree(&RepoPath::root(), &new_tree_id).unwrap();
|
||||
.map(|id| store.get_commit(id))
|
||||
.try_collect()?;
|
||||
let ancestor_tree = merge_commit_trees_without_repo(store, index, &ancestors)?;
|
||||
let new_tree_id = merge_trees(&new_tree, &ancestor_tree, &other_commit.tree())?;
|
||||
new_tree = store.get_tree(&RepoPath::root(), &new_tree_id)?;
|
||||
}
|
||||
new_tree
|
||||
Ok(new_tree)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,7 +66,7 @@ pub fn rebase_commit(
|
|||
mut_repo: &mut MutableRepo,
|
||||
old_commit: &Commit,
|
||||
new_parents: &[Commit],
|
||||
) -> BackendResult<Commit> {
|
||||
) -> Result<Commit, TreeMergeError> {
|
||||
let old_parents = old_commit.parents();
|
||||
let old_parent_trees = old_parents
|
||||
.iter()
|
||||
|
@ -82,20 +80,20 @@ pub fn rebase_commit(
|
|||
// Optimization
|
||||
old_commit.tree_id().clone()
|
||||
} else {
|
||||
let old_base_tree = merge_commit_trees(mut_repo, &old_parents);
|
||||
let new_base_tree = merge_commit_trees(mut_repo, new_parents);
|
||||
let old_base_tree = merge_commit_trees(mut_repo, &old_parents)?;
|
||||
let new_base_tree = merge_commit_trees(mut_repo, new_parents)?;
|
||||
// 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())?
|
||||
};
|
||||
let new_parent_ids = new_parents
|
||||
.iter()
|
||||
.map(|commit| commit.id().clone())
|
||||
.collect();
|
||||
mut_repo
|
||||
Ok(mut_repo
|
||||
.rewrite_commit(settings, old_commit)
|
||||
.set_parents(new_parent_ids)
|
||||
.set_tree(new_tree_id)
|
||||
.write()
|
||||
.write()?)
|
||||
}
|
||||
|
||||
pub fn back_out_commit(
|
||||
|
@ -103,9 +101,9 @@ pub fn back_out_commit(
|
|||
mut_repo: &mut MutableRepo,
|
||||
old_commit: &Commit,
|
||||
new_parents: &[Commit],
|
||||
) -> BackendResult<Commit> {
|
||||
let old_base_tree = merge_commit_trees(mut_repo, &old_commit.parents());
|
||||
let new_base_tree = merge_commit_trees(mut_repo, new_parents);
|
||||
) -> Result<Commit, TreeMergeError> {
|
||||
let old_base_tree = merge_commit_trees(mut_repo, &old_commit.parents())?;
|
||||
let new_base_tree = merge_commit_trees(mut_repo, new_parents)?;
|
||||
// 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_parent_ids = new_parents
|
||||
|
@ -113,10 +111,10 @@ pub fn back_out_commit(
|
|||
.map(|commit| commit.id().clone())
|
||||
.collect();
|
||||
// TODO: i18n the description based on repo language
|
||||
mut_repo
|
||||
Ok(mut_repo
|
||||
.new_commit(settings, new_parent_ids, new_tree_id)
|
||||
.set_description(format!("backout of commit {}", &old_commit.id().hex()))
|
||||
.write()
|
||||
.write()?)
|
||||
}
|
||||
|
||||
/// Rebases descendants of a commit onto a new commit (or several).
|
||||
|
@ -377,7 +375,7 @@ impl<'settings, 'repo> DescendantRebaser<'settings, 'repo> {
|
|||
|
||||
// TODO: Perhaps change the interface since it's not just about rebasing
|
||||
// commits.
|
||||
pub fn rebase_next(&mut self) -> Result<Option<RebasedDescendant>, BackendError> {
|
||||
pub fn rebase_next(&mut self) -> Result<Option<RebasedDescendant>, TreeMergeError> {
|
||||
while let Some(old_commit) = self.to_visit.pop() {
|
||||
let old_commit_id = old_commit.id().clone();
|
||||
if let Some(new_parent_ids) = self.new_parents.get(&old_commit_id).cloned() {
|
||||
|
@ -450,7 +448,7 @@ impl<'settings, 'repo> DescendantRebaser<'settings, 'repo> {
|
|||
Ok(None)
|
||||
}
|
||||
|
||||
pub fn rebase_all(&mut self) -> Result<(), BackendError> {
|
||||
pub fn rebase_all(&mut self) -> Result<(), TreeMergeError> {
|
||||
while self.rebase_next()?.is_some() {}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1403,7 +1403,7 @@ fn cmd_diff(ui: &mut Ui, command: &CommandHelper, args: &DiffArgs) -> Result<(),
|
|||
let commit =
|
||||
workspace_command.resolve_single_rev(args.revision.as_deref().unwrap_or("@"))?;
|
||||
let parents = commit.parents();
|
||||
from_tree = merge_commit_trees(workspace_command.repo().as_ref(), &parents);
|
||||
from_tree = merge_commit_trees(workspace_command.repo().as_ref(), &parents)?;
|
||||
to_tree = commit.tree()
|
||||
}
|
||||
let matcher = workspace_command.matcher_from_values(&args.paths)?;
|
||||
|
@ -1512,7 +1512,7 @@ fn cmd_status(
|
|||
}
|
||||
|
||||
if let Some(wc_commit) = &maybe_wc_commit {
|
||||
let parent_tree = merge_commit_trees(repo.as_ref(), &wc_commit.parents());
|
||||
let parent_tree = merge_commit_trees(repo.as_ref(), &wc_commit.parents())?;
|
||||
let tree = wc_commit.tree();
|
||||
if tree.id() == parent_tree.id() {
|
||||
formatter.write_str("The working copy is clean\n")?;
|
||||
|
@ -1829,9 +1829,9 @@ fn rebase_to_dest_parent(
|
|||
Ok(source.tree())
|
||||
} else {
|
||||
let destination_parent_tree =
|
||||
merge_commit_trees(workspace_command.repo().as_ref(), &destination.parents());
|
||||
merge_commit_trees(workspace_command.repo().as_ref(), &destination.parents())?;
|
||||
let source_parent_tree =
|
||||
merge_commit_trees(workspace_command.repo().as_ref(), &source.parents());
|
||||
merge_commit_trees(workspace_command.repo().as_ref(), &source.parents())?;
|
||||
let rebased_tree_id = merge_trees(
|
||||
&destination_parent_tree,
|
||||
&source_parent_tree,
|
||||
|
@ -2229,7 +2229,7 @@ fn cmd_new(ui: &mut Ui, command: &CommandHelper, args: &NewArgs) -> Result<(), C
|
|||
if new_parents_commits.len() > 1 {
|
||||
new_parents_commits.retain(|c| c != &root_commit);
|
||||
}
|
||||
let merged_tree = merge_commit_trees(tx.repo(), &new_parents_commits);
|
||||
let merged_tree = merge_commit_trees(tx.repo(), &new_parents_commits)?;
|
||||
let new_parents_commit_id = new_parents_commits.iter().map(|c| c.id().clone()).collect();
|
||||
new_commit = tx
|
||||
.mut_repo()
|
||||
|
@ -2250,7 +2250,7 @@ fn cmd_new(ui: &mut Ui, command: &CommandHelper, args: &NewArgs) -> Result<(), C
|
|||
)?;
|
||||
}
|
||||
} else {
|
||||
let merged_tree = merge_commit_trees(tx.repo(), &target_commits);
|
||||
let merged_tree = merge_commit_trees(tx.repo(), &target_commits)?;
|
||||
new_commit = tx
|
||||
.mut_repo()
|
||||
.new_commit(
|
||||
|
@ -2344,7 +2344,7 @@ fn cmd_move(ui: &mut Ui, command: &CommandHelper, args: &MoveArgs) -> Result<(),
|
|||
source.id().hex(),
|
||||
destination.id().hex()
|
||||
));
|
||||
let parent_tree = merge_commit_trees(tx.repo(), &source.parents());
|
||||
let parent_tree = merge_commit_trees(tx.repo(), &source.parents())?;
|
||||
let source_tree = source.tree();
|
||||
let instructions = format!(
|
||||
"\
|
||||
|
@ -2521,7 +2521,7 @@ fn cmd_unsquash(
|
|||
workspace_command.check_rewritable(parent)?;
|
||||
let mut tx =
|
||||
workspace_command.start_transaction(&format!("unsquash commit {}", commit.id().hex()));
|
||||
let parent_base_tree = merge_commit_trees(tx.repo(), &parent.parents());
|
||||
let parent_base_tree = merge_commit_trees(tx.repo(), &parent.parents())?;
|
||||
let new_parent_tree_id;
|
||||
if args.interactive {
|
||||
let instructions = format!(
|
||||
|
@ -2831,7 +2831,7 @@ fn cmd_restore(
|
|||
.tree();
|
||||
} else {
|
||||
to_commit = workspace_command.resolve_single_rev("@")?;
|
||||
from_tree = merge_commit_trees(workspace_command.repo().as_ref(), &to_commit.parents());
|
||||
from_tree = merge_commit_trees(workspace_command.repo().as_ref(), &to_commit.parents())?;
|
||||
}
|
||||
workspace_command.check_rewritable(&to_commit)?;
|
||||
|
||||
|
@ -2909,7 +2909,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.",
|
||||
tx.format_commit_summary(&target_commit),
|
||||
);
|
||||
let base_tree = merge_commit_trees(tx.repo(), base_commits.as_slice());
|
||||
let base_tree = merge_commit_trees(tx.repo(), base_commits.as_slice())?;
|
||||
let tree_id = tx.edit_diff(ui, &base_tree, &target_commit.tree(), &instructions)?;
|
||||
if &tree_id == target_commit.tree_id() {
|
||||
ui.write("Nothing changed.\n")?;
|
||||
|
@ -2984,7 +2984,7 @@ fn cmd_split(ui: &mut Ui, command: &CommandHelper, args: &SplitArgs) -> Result<(
|
|||
let matcher = workspace_command.matcher_from_values(&args.paths)?;
|
||||
let mut tx =
|
||||
workspace_command.start_transaction(&format!("split commit {}", commit.id().hex()));
|
||||
let base_tree = merge_commit_trees(tx.repo(), &commit.parents());
|
||||
let base_tree = merge_commit_trees(tx.repo(), &commit.parents())?;
|
||||
let interactive = args.paths.is_empty();
|
||||
let instructions = format!(
|
||||
"\
|
||||
|
|
|
@ -258,7 +258,8 @@ fn build_commit_keyword_opt<'repo>(
|
|||
language.wrap_boolean(wrap_fn(property, |commit| commit.tree().has_conflict()))
|
||||
}
|
||||
"empty" => language.wrap_boolean(wrap_fn(property, |commit| {
|
||||
commit.tree().id() == rewrite::merge_commit_trees(repo, &commit.parents()).id()
|
||||
let parent_tree = rewrite::merge_commit_trees(repo, &commit.parents()).unwrap();
|
||||
commit.tree().id() == parent_tree.id()
|
||||
})),
|
||||
_ => return None,
|
||||
};
|
||||
|
|
|
@ -154,7 +154,7 @@ pub fn show_patch(
|
|||
formats: &[DiffFormat],
|
||||
) -> Result<(), CommandError> {
|
||||
let parents = commit.parents();
|
||||
let from_tree = rewrite::merge_commit_trees(workspace_command.repo().as_ref(), &parents);
|
||||
let from_tree = rewrite::merge_commit_trees(workspace_command.repo().as_ref(), &parents)?;
|
||||
let to_tree = commit.tree();
|
||||
show_diff(
|
||||
formatter,
|
||||
|
|
Loading…
Reference in a new issue