diff --git a/cli/src/commands/commit.rs b/cli/src/commands/commit.rs index a33e58624e8..4ad91c6d7c1 100644 --- a/cli/src/commands/commit.rs +++ b/cli/src/commands/commit.rs @@ -14,7 +14,6 @@ use jj_lib::object_id::ObjectId; use jj_lib::repo::Repo; -use jj_lib::rewrite::merge_commit_trees; use tracing::instrument; use crate::cli_util::CommandHelper; @@ -61,7 +60,7 @@ pub(crate) fn cmd_commit( let diff_selector = workspace_command.diff_selector(ui, args.tool.as_deref(), args.interactive)?; let mut tx = workspace_command.start_transaction(); - let base_tree = merge_commit_trees(tx.repo(), &commit.parents())?; + let base_tree = commit.parent_tree(tx.repo())?; let instructions = format!( "\ You are splitting the working-copy commit: {} diff --git a/cli/src/commands/diff.rs b/cli/src/commands/diff.rs index 6a44f67b61d..e17434473a2 100644 --- a/cli/src/commands/diff.rs +++ b/cli/src/commands/diff.rs @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -use jj_lib::rewrite::merge_commit_trees; use tracing::instrument; use crate::cli_util::{print_unmatched_explicit_paths, CommandHelper, RevisionArg}; @@ -72,8 +71,7 @@ pub(crate) fn cmd_diff( } else { let commit = workspace_command .resolve_single_rev(args.revision.as_ref().unwrap_or(&RevisionArg::AT))?; - let parents = commit.parents(); - from_tree = merge_commit_trees(workspace_command.repo().as_ref(), &parents)?; + from_tree = commit.parent_tree(workspace_command.repo().as_ref())?; to_tree = commit.tree()? } let fileset_expression = workspace_command.parse_file_patterns(&args.paths)?; diff --git a/cli/src/commands/restore.rs b/cli/src/commands/restore.rs index abee9a679ba..2c9e7ba106d 100644 --- a/cli/src/commands/restore.rs +++ b/cli/src/commands/restore.rs @@ -15,7 +15,7 @@ use std::io::Write; use jj_lib::object_id::ObjectId; -use jj_lib::rewrite::{merge_commit_trees, restore_tree}; +use jj_lib::rewrite::restore_tree; use tracing::instrument; use crate::cli_util::{CommandHelper, RevisionArg}; @@ -94,7 +94,7 @@ pub(crate) fn cmd_restore( } else { to_commit = workspace_command .resolve_single_rev(args.changes_in.as_ref().unwrap_or(&RevisionArg::AT))?; - from_tree = merge_commit_trees(workspace_command.repo().as_ref(), &to_commit.parents())?; + from_tree = to_commit.parent_tree(workspace_command.repo().as_ref())?; } workspace_command.check_rewritable([to_commit.id()])?; diff --git a/cli/src/commands/split.rs b/cli/src/commands/split.rs index 38514f04ec0..9661a50b457 100644 --- a/cli/src/commands/split.rs +++ b/cli/src/commands/split.rs @@ -15,7 +15,6 @@ use std::io::Write; use jj_lib::object_id::ObjectId; use jj_lib::repo::Repo; -use jj_lib::rewrite::merge_commit_trees; use tracing::instrument; use crate::cli_util::{CommandHelper, RevisionArg}; @@ -76,7 +75,7 @@ pub(crate) fn cmd_split( )?; let mut tx = workspace_command.start_transaction(); let end_tree = commit.tree()?; - let base_tree = merge_commit_trees(tx.repo(), &commit.parents())?; + let base_tree = commit.parent_tree(tx.repo())?; let instructions = format!( "\ You are splitting a commit into two: {} diff --git a/cli/src/commands/squash.rs b/cli/src/commands/squash.rs index 94656aae936..a76c2adbff5 100644 --- a/cli/src/commands/squash.rs +++ b/cli/src/commands/squash.rs @@ -19,7 +19,6 @@ use jj_lib::merged_tree::MergedTree; use jj_lib::object_id::ObjectId; use jj_lib::repo::Repo; use jj_lib::revset; -use jj_lib::rewrite::merge_commit_trees; use jj_lib::settings::UserSettings; use tracing::instrument; @@ -191,7 +190,7 @@ pub fn move_diff( } let mut source_commits = vec![]; for source in sources { - let parent_tree = merge_commit_trees(tx.repo(), &source.parents())?; + let parent_tree = source.parent_tree(tx.repo())?; let source_tree = source.tree()?; let instructions = format!( "\ diff --git a/cli/src/commands/status.rs b/cli/src/commands/status.rs index 7a4b094f964..940c63b26e7 100644 --- a/cli/src/commands/status.rs +++ b/cli/src/commands/status.rs @@ -15,7 +15,6 @@ use itertools::Itertools; use jj_lib::repo::Repo; use jj_lib::revset::{RevsetExpression, RevsetFilterPredicate}; -use jj_lib::rewrite::merge_commit_trees; use tracing::instrument; use crate::cli_util::{print_conflicted_paths, CommandHelper}; @@ -59,7 +58,7 @@ pub(crate) fn cmd_status( let formatter = formatter.as_mut(); if let Some(wc_commit) = &maybe_wc_commit { - let parent_tree = merge_commit_trees(repo.as_ref(), &wc_commit.parents())?; + let parent_tree = wc_commit.parent_tree(repo.as_ref())?; let tree = wc_commit.tree()?; if tree.id() == parent_tree.id() { writeln!(formatter, "The working copy is clean")?; diff --git a/cli/src/commands/unsquash.rs b/cli/src/commands/unsquash.rs index 389512318f9..da2c22178b1 100644 --- a/cli/src/commands/unsquash.rs +++ b/cli/src/commands/unsquash.rs @@ -14,7 +14,6 @@ use jj_lib::matchers::EverythingMatcher; use jj_lib::object_id::ObjectId; -use jj_lib::rewrite::merge_commit_trees; use tracing::instrument; use crate::cli_util::{CommandHelper, RevisionArg}; @@ -69,7 +68,7 @@ pub(crate) fn cmd_unsquash( None }; let mut tx = workspace_command.start_transaction(); - let parent_base_tree = merge_commit_trees(tx.repo(), &parent.parents())?; + let parent_base_tree = parent.parent_tree(tx.repo())?; let new_parent_tree_id; if let Some(diff_editor) = &interactive_editor { let instructions = format!( diff --git a/cli/src/commit_templater.rs b/cli/src/commit_templater.rs index 4ab0c7d1ebc..a341df4214d 100644 --- a/cli/src/commit_templater.rs +++ b/cli/src/commit_templater.rs @@ -22,13 +22,13 @@ use itertools::Itertools as _; use jj_lib::backend::{ChangeId, CommitId}; use jj_lib::commit::Commit; use jj_lib::extensions_map::ExtensionsMap; +use jj_lib::git; use jj_lib::hex_util::to_reverse_hex; use jj_lib::id_prefix::IdPrefixContext; use jj_lib::object_id::ObjectId as _; use jj_lib::op_store::{RefTarget, WorkspaceId}; use jj_lib::repo::Repo; use jj_lib::revset::{self, Revset, RevsetExpression, RevsetParseContext}; -use jj_lib::{git, rewrite}; use once_cell::unsync::OnceCell; use crate::template_builder::{ @@ -649,7 +649,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm if let [parent] = &commit.parents()[..] { return Ok(parent.tree_id() == commit.tree_id()); } - let parent_tree = rewrite::merge_commit_trees(repo, &commit.parents())?; + let parent_tree = commit.parent_tree(repo)?; Ok(*commit.tree_id() == parent_tree.id()) }); Ok(L::wrap_boolean(out_property)) diff --git a/lib/src/commit.rs b/lib/src/commit.rs index 0282c6d48a3..d1a8d202fa0 100644 --- a/lib/src/commit.rs +++ b/lib/src/commit.rs @@ -21,6 +21,8 @@ use std::sync::Arc; use crate::backend::{self, BackendResult, ChangeId, CommitId, MergedTreeId, Signature}; use crate::merged_tree::MergedTree; +use crate::repo::Repo; +use crate::rewrite::merge_commit_trees; use crate::signing::{SignResult, Verification}; use crate::store::Store; @@ -108,6 +110,12 @@ impl Commit { &self.data.root_tree } + /// Return the parent tree, merging the parent trees if there are multiple + /// parents. + pub fn parent_tree(&self, repo: &dyn Repo) -> BackendResult { + merge_commit_trees(repo, &self.parents()) + } + pub fn has_conflict(&self) -> BackendResult { if let MergedTreeId::Merge(tree_ids) = self.tree_id() { Ok(!tree_ids.is_resolved()) diff --git a/lib/src/rewrite.rs b/lib/src/rewrite.rs index 9e4b1c5ec4d..cd6190753a0 100644 --- a/lib/src/rewrite.rs +++ b/lib/src/rewrite.rs @@ -306,8 +306,8 @@ pub fn rebase_to_dest_parent( if source.parent_ids() == destination.parent_ids() { Ok(source.tree()?) } else { - let destination_parent_tree = merge_commit_trees(repo, &destination.parents())?; - let source_parent_tree = merge_commit_trees(repo, &source.parents())?; + let destination_parent_tree = destination.parent_tree(repo)?; + let source_parent_tree = source.parent_tree(repo)?; let source_tree = source.tree()?; let rebased_tree = destination_parent_tree.merge(&source_parent_tree, &source_tree)?; Ok(rebased_tree) @@ -320,7 +320,7 @@ pub fn back_out_commit( old_commit: &Commit, new_parents: &[Commit], ) -> BackendResult { - let old_base_tree = merge_commit_trees(mut_repo, &old_commit.parents())?; + let old_base_tree = old_commit.parent_tree(mut_repo)?; let new_base_tree = merge_commit_trees(mut_repo, new_parents)?; let old_tree = old_commit.tree()?; let new_tree = new_base_tree.merge(&old_tree, &old_base_tree)?;