Skip to content

Commit

Permalink
copy-tracking: push towards CommitId based diff helper
Browse files Browse the repository at this point in the history
- create a helper that delegates to the original
- rework diff cli to use it if it can
  • Loading branch information
fowles committed Jul 18, 2024
1 parent e30d6ed commit 6d49831
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 19 deletions.
83 changes: 65 additions & 18 deletions cli/src/commands/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use itertools::Itertools;
use jj_lib::commit::Commit;
use jj_lib::merged_tree::MergedTree;
use jj_lib::rewrite::merge_commit_trees;
use tracing::instrument;

use crate::cli_util::{print_unmatched_explicit_paths, CommandHelper, RevisionArg};
use crate::cli_util::{
print_unmatched_explicit_paths, CommandHelper, RevisionArg, WorkspaceCommandHelper,
};
use crate::command_error::CommandError;
use crate::diff_util::DiffFormatArgs;
use crate::ui::Ui;
Expand Down Expand Up @@ -52,44 +58,85 @@ pub(crate) struct DiffArgs {
format: DiffFormatArgs,
}

fn resolve_revision(
workspace_command: &WorkspaceCommandHelper,
r: &Option<RevisionArg>,
) -> Result<Commit, CommandError> {
workspace_command.resolve_single_rev(r.as_ref().unwrap_or(&RevisionArg::AT))
}

fn handle_merge_diff(
ui: &mut Ui,
workspace_command: &WorkspaceCommandHelper,
args: &DiffArgs,
from_tree: &MergedTree,
to_tree: &MergedTree,
) -> Result<(), CommandError> {
let fileset_expression = workspace_command.parse_file_patterns(&args.paths)?;
let matcher = fileset_expression.to_matcher();
let diff_renderer = workspace_command.diff_renderer_for(&args.format)?;
ui.request_pager();
diff_renderer.show_diff(
ui,
ui.stdout_formatter().as_mut(),
from_tree,
to_tree,
matcher.as_ref(),
)?;
print_unmatched_explicit_paths(
ui,
workspace_command,
&fileset_expression,
[from_tree, to_tree],
)?;
Ok(())
}

#[instrument(skip_all)]
pub(crate) fn cmd_diff(
ui: &mut Ui,
command: &CommandHelper,
args: &DiffArgs,
) -> Result<(), CommandError> {
let workspace_command = command.workspace_helper(ui)?;
let from_tree;
let to_tree;
if args.from.is_some() || args.to.is_some() {
let from =
workspace_command.resolve_single_rev(args.from.as_ref().unwrap_or(&RevisionArg::AT))?;
from_tree = from.tree()?;
let to =
workspace_command.resolve_single_rev(args.to.as_ref().unwrap_or(&RevisionArg::AT))?;
to_tree = to.tree()?;

let to;
let from;

if args.to.is_some() || args.from.is_some() {
to = resolve_revision(&workspace_command, &args.to)?;
from = resolve_revision(&workspace_command, &args.from)?;
} else {
let commit = workspace_command
.resolve_single_rev(args.revision.as_ref().unwrap_or(&RevisionArg::AT))?;
from_tree = commit.parent_tree(workspace_command.repo().as_ref())?;
to_tree = commit.tree()?
to = resolve_revision(&workspace_command, &args.revision)?;
let mut parents: Vec<_> = to.parents().try_collect()?;
if parents.len() != 1 {
return handle_merge_diff(
ui,
&workspace_command,
args,
&merge_commit_trees(workspace_command.repo().as_ref(), &parents)?,
&to.tree()?,
);
}
from = parents.pop().unwrap();
}

let fileset_expression = workspace_command.parse_file_patterns(&args.paths)?;
let matcher = fileset_expression.to_matcher();
let diff_renderer = workspace_command.diff_renderer_for(&args.format)?;
ui.request_pager();
diff_renderer.show_diff(
diff_renderer.show_commit_diff(
ui,
ui.stdout_formatter().as_mut(),
&from_tree,
&to_tree,
from.id(),
to.id(),
matcher.as_ref(),
)?;
print_unmatched_explicit_paths(
ui,
&workspace_command,
&fileset_expression,
[&from_tree, &to_tree],
[&from.tree()?, &to.tree()?],
)?;
Ok(())
}
16 changes: 15 additions & 1 deletion cli/src/diff_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use std::{io, mem};

use futures::StreamExt;
use itertools::Itertools;
use jj_lib::backend::{BackendError, TreeValue};
use jj_lib::backend::{BackendError, CommitId, TreeValue};
use jj_lib::commit::Commit;
use jj_lib::conflicts::{materialized_diff_stream, MaterializedTreeValue};
use jj_lib::diff::{Diff, DiffHunk};
Expand Down Expand Up @@ -237,6 +237,20 @@ impl<'a> DiffRenderer<'a> {
}
}

/// Generates diff between `from_tree` and `to_tree`.
pub fn show_commit_diff(
&self,
ui: &Ui, // TODO: remove Ui dependency if possible
formatter: &mut dyn Formatter,
from: &CommitId,
to: &CommitId,
matcher: &dyn Matcher,
) -> Result<(), DiffRenderError> {
let from_tree = self.repo.store().get_commit(from)?.tree()?;
let to_tree = self.repo.store().get_commit(to)?.tree()?;
self.show_diff(ui, formatter, &from_tree, &to_tree, matcher)
}

/// Generates diff between `from_tree` and `to_tree`.
pub fn show_diff(
&self,
Expand Down

0 comments on commit 6d49831

Please sign in to comment.