ok/jj
1
0
Fork 0
forked from mirrors/jj

copies: add a separate diff stream item type with copy info

The goal is to have the new item type know if it represent a copy, a
rename, a deleted rename source, or a regular copy-unrelated item.
This commit is contained in:
Martin von Zweigbergk 2024-08-17 14:18:24 -07:00 committed by Martin von Zweigbergk
parent 70598498b0
commit 721aa1238c
5 changed files with 41 additions and 23 deletions

View file

@ -18,17 +18,18 @@ use std::collections::HashMap;
use std::io;
use std::rc::Rc;
use futures::stream::BoxStream;
use itertools::Itertools as _;
use jj_lib::backend::{BackendResult, ChangeId, CommitId};
use jj_lib::commit::Commit;
use jj_lib::copies::CopyRecords;
use jj_lib::copies::{CopiesTreeDiffEntry, CopyRecords};
use jj_lib::extensions_map::ExtensionsMap;
use jj_lib::fileset::{self, FilesetExpression};
use jj_lib::git;
use jj_lib::hex_util::to_reverse_hex;
use jj_lib::id_prefix::IdPrefixContext;
use jj_lib::matchers::Matcher;
use jj_lib::merged_tree::{MergedTree, TreeDiffStream};
use jj_lib::merged_tree::MergedTree;
use jj_lib::object_id::ObjectId as _;
use jj_lib::op_store::{RefTarget, RemoteRef, WorkspaceId};
use jj_lib::repo::Repo;
@ -1296,14 +1297,14 @@ impl TreeDiff {
})
}
fn diff_stream(&self) -> TreeDiffStream<'_> {
fn diff_stream(&self) -> BoxStream<'_, CopiesTreeDiffEntry> {
self.from_tree
.diff_stream_with_copies(&self.to_tree, &*self.matcher, &self.copy_records)
}
fn into_formatted<F, E>(self, show: F) -> TreeDiffFormatted<F>
where
F: Fn(&mut dyn Formatter, &Store, TreeDiffStream) -> Result<(), E>,
F: Fn(&mut dyn Formatter, &Store, BoxStream<CopiesTreeDiffEntry>) -> Result<(), E>,
E: Into<TemplatePropertyError>,
{
TreeDiffFormatted { diff: self, show }
@ -1318,7 +1319,7 @@ struct TreeDiffFormatted<F> {
impl<F, E> Template for TreeDiffFormatted<F>
where
F: Fn(&mut dyn Formatter, &Store, TreeDiffStream) -> Result<(), E>,
F: Fn(&mut dyn Formatter, &Store, BoxStream<CopiesTreeDiffEntry>) -> Result<(), E>,
E: Into<TemplatePropertyError>,
{
fn format(&self, formatter: &mut TemplateFormatter) -> io::Result<()> {

View file

@ -18,6 +18,7 @@ use std::ops::Range;
use std::path::{Path, PathBuf};
use std::{io, mem};
use futures::stream::BoxStream;
use futures::StreamExt;
use itertools::Itertools;
use jj_lib::backend::{BackendError, TreeValue};
@ -25,12 +26,12 @@ use jj_lib::commit::Commit;
use jj_lib::conflicts::{
materialized_diff_stream, MaterializedTreeDiffEntry, MaterializedTreeValue,
};
use jj_lib::copies::CopyRecords;
use jj_lib::copies::{CopiesTreeDiffEntry, CopyRecords};
use jj_lib::diff::{Diff, DiffHunk};
use jj_lib::files::{DiffLine, DiffLineHunkSide, DiffLineIterator, DiffLineNumber};
use jj_lib::matchers::Matcher;
use jj_lib::merge::MergedTreeValue;
use jj_lib::merged_tree::{MergedTree, TreeDiffEntry, TreeDiffStream};
use jj_lib::merged_tree::MergedTree;
use jj_lib::object_id::ObjectId;
use jj_lib::repo::Repo;
use jj_lib::repo_path::{RepoPath, RepoPathUiConverter};
@ -652,7 +653,7 @@ fn basic_diff_file_type(value: &MaterializedTreeValue) -> &'static str {
pub fn show_color_words_diff(
formatter: &mut dyn Formatter,
store: &Store,
tree_diff: TreeDiffStream,
tree_diff: BoxStream<CopiesTreeDiffEntry>,
path_converter: &RepoPathUiConverter,
num_context_lines: usize,
) -> Result<(), DiffRenderError> {
@ -808,7 +809,7 @@ pub fn show_file_by_file_diff(
ui: &Ui,
formatter: &mut dyn Formatter,
store: &Store,
tree_diff: TreeDiffStream,
tree_diff: BoxStream<CopiesTreeDiffEntry>,
path_converter: &RepoPathUiConverter,
matcher: &dyn Matcher,
copy_records: &CopyRecords,
@ -1279,7 +1280,7 @@ pub fn show_diff_summary(
let copied_sources = collect_copied_sources(copy_records, matcher);
async {
while let Some(TreeDiffEntry {
while let Some(CopiesTreeDiffEntry {
source: before_path,
target: after_path,
value: diff,
@ -1351,7 +1352,7 @@ fn get_diff_stat(
pub fn show_diff_stat(
formatter: &mut dyn Formatter,
store: &Store,
tree_diff: TreeDiffStream,
tree_diff: BoxStream<CopiesTreeDiffEntry>,
path_converter: &RepoPathUiConverter,
display_width: usize,
) -> Result<(), DiffRenderError> {
@ -1452,7 +1453,7 @@ pub fn show_types(
let copied_sources = collect_copied_sources(copy_records, matcher);
async {
while let Some(TreeDiffEntry {
while let Some(CopiesTreeDiffEntry {
source,
target,
value: diff,
@ -1490,11 +1491,11 @@ fn diff_summary_char(value: &MergedTreeValue) -> char {
pub fn show_names(
formatter: &mut dyn Formatter,
mut tree_diff: TreeDiffStream,
mut tree_diff: BoxStream<CopiesTreeDiffEntry>,
path_converter: &RepoPathUiConverter,
) -> io::Result<()> {
async {
while let Some(TreeDiffEntry {
while let Some(CopiesTreeDiffEntry {
target: repo_path, ..
}) = tree_diff.next().await
{

View file

@ -17,16 +17,17 @@
use std::io::{Read, Write};
use std::iter::zip;
use futures::stream::BoxStream;
use futures::{try_join, Stream, StreamExt, TryStreamExt};
use itertools::Itertools;
use regex::bytes::{Regex, RegexBuilder};
use crate::backend::{BackendError, BackendResult, CommitId, FileId, SymlinkId, TreeId, TreeValue};
use crate::copies::CopiesTreeDiffEntry;
use crate::diff::{Diff, DiffHunk};
use crate::files;
use crate::files::{ContentHunk, MergeResult};
use crate::merge::{Merge, MergeBuilder, MergedTreeValue};
use crate::merged_tree::{TreeDiffEntry, TreeDiffStream};
use crate::repo_path::{RepoPath, RepoPathBuf};
use crate::store::Store;
@ -333,11 +334,11 @@ pub struct MaterializedTreeDiffEntry {
pub fn materialized_diff_stream<'a>(
store: &'a Store,
tree_diff: TreeDiffStream<'a>,
tree_diff: BoxStream<'a, CopiesTreeDiffEntry>,
) -> impl Stream<Item = MaterializedTreeDiffEntry> + 'a {
tree_diff
.map(
|TreeDiffEntry {
|CopiesTreeDiffEntry {
source,
target,
value,

View file

@ -23,7 +23,8 @@ use futures::stream::BoxStream;
use futures::Stream;
use crate::backend::{BackendResult, CopyRecord};
use crate::merged_tree::{MergedTree, TreeDiffEntry, TreeDiffStream};
use crate::merge::MergedTreeValue;
use crate::merged_tree::{MergedTree, TreeDiffStream};
use crate::repo_path::{RepoPath, RepoPathBuf};
/// A collection of CopyRecords.
@ -91,8 +92,18 @@ impl<'a> CopiesTreeDiffStream<'a> {
}
}
/// A `TreeDiffEntry` with copy information.
pub struct CopiesTreeDiffEntry {
/// The source path.
pub source: RepoPathBuf,
/// The target path.
pub target: RepoPathBuf,
/// The resolved tree values if available.
pub value: BackendResult<(MergedTreeValue, MergedTreeValue)>,
}
impl Stream for CopiesTreeDiffStream<'_> {
type Item = TreeDiffEntry;
type Item = CopiesTreeDiffEntry;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
self.inner.as_mut().poll_next(cx).map(|option| {
@ -100,10 +111,14 @@ impl Stream for CopiesTreeDiffStream<'_> {
let Some(CopyRecord { source, .. }) =
self.copy_records.for_target(&diff_entry.target)
else {
return diff_entry;
return CopiesTreeDiffEntry {
source: diff_entry.source,
target: diff_entry.target,
value: diff_entry.value,
};
};
TreeDiffEntry {
CopiesTreeDiffEntry {
source: source.clone(),
target: diff_entry.target,
value: diff_entry.value.and_then(|(_, target_value)| {

View file

@ -31,7 +31,7 @@ use itertools::{EitherOrBoth, Itertools};
use crate::backend;
use crate::backend::{BackendResult, MergedTreeId, TreeId, TreeValue};
use crate::copies::{CopiesTreeDiffStream, CopyRecords};
use crate::copies::{CopiesTreeDiffEntry, CopiesTreeDiffStream, CopyRecords};
use crate::matchers::{EverythingMatcher, Matcher};
use crate::merge::{Merge, MergeBuilder, MergedTreeVal, MergedTreeValue};
use crate::repo_path::{RepoPath, RepoPathBuf, RepoPathComponent};
@ -289,7 +289,7 @@ impl MergedTree {
other: &MergedTree,
matcher: &'a dyn Matcher,
copy_records: &'a CopyRecords,
) -> TreeDiffStream<'a> {
) -> BoxStream<'a, CopiesTreeDiffEntry> {
let stream = self.diff_stream(other, matcher);
Box::pin(CopiesTreeDiffStream::new(
stream,