just playing with tangled
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

copies: move `CopyRecords` to new `copies` module

Copy/rename handling is complicated. It seems worth having a module
for it. I'm going to add more content to it next.

authored by

Martin von Zweigbergk and committed by
Martin von Zweigbergk
fd9a236b 6101a66a

+77 -50
+1 -1
cli/src/commands/diff.rs
··· 13 13 // limitations under the License. 14 14 15 15 use itertools::Itertools; 16 - use jj_lib::backend::CopyRecords; 16 + use jj_lib::copies::CopyRecords; 17 17 use jj_lib::repo::Repo; 18 18 use jj_lib::rewrite::merge_commit_trees; 19 19 use tracing::instrument;
+2 -1
cli/src/commit_templater.rs
··· 19 19 use std::rc::Rc; 20 20 21 21 use itertools::Itertools as _; 22 - use jj_lib::backend::{BackendResult, ChangeId, CommitId, CopyRecords}; 22 + use jj_lib::backend::{BackendResult, ChangeId, CommitId}; 23 23 use jj_lib::commit::Commit; 24 + use jj_lib::copies::CopyRecords; 24 25 use jj_lib::extensions_map::ExtensionsMap; 25 26 use jj_lib::fileset::{self, FilesetExpression}; 26 27 use jj_lib::git;
+2 -1
cli/src/diff_util.rs
··· 20 20 21 21 use futures::StreamExt; 22 22 use itertools::Itertools; 23 - use jj_lib::backend::{BackendError, CopyRecords, TreeValue}; 23 + use jj_lib::backend::{BackendError, TreeValue}; 24 24 use jj_lib::commit::Commit; 25 25 use jj_lib::conflicts::{ 26 26 materialized_diff_stream, MaterializedTreeDiffEntry, MaterializedTreeValue, 27 27 }; 28 + use jj_lib::copies::CopyRecords; 28 29 use jj_lib::diff::{Diff, DiffHunk}; 29 30 use jj_lib::files::{DiffLine, DiffLineHunkSide, DiffLineIterator, DiffLineNumber}; 30 31 use jj_lib::matchers::Matcher;
+1 -45
lib/src/backend.rs
··· 15 15 #![allow(missing_docs)] 16 16 17 17 use std::any::Any; 18 - use std::collections::{BTreeMap, HashMap}; 18 + use std::collections::BTreeMap; 19 19 use std::fmt::Debug; 20 20 use std::io::Read; 21 21 use std::time::SystemTime; 22 22 23 23 use async_trait::async_trait; 24 - use futures::executor::block_on_stream; 25 24 use futures::stream::BoxStream; 26 25 use thiserror::Error; 27 26 ··· 179 178 /// It is required that the commit id is an ancestor of the commit with 180 179 /// which this copy source is associated. 181 180 pub source_commit: CommitId, 182 - } 183 - 184 - /// A collection of CopyRecords. 185 - #[derive(Default, Debug)] 186 - pub struct CopyRecords { 187 - records: Vec<CopyRecord>, 188 - // Maps from `target` to the index of the target in `records`. Conflicts 189 - // are excluded by keeping an out of range value. 190 - targets: HashMap<RepoPathBuf, usize>, 191 - } 192 - 193 - impl CopyRecords { 194 - /// Adds information about a stream of CopyRecords to `self`. A target with 195 - /// multiple conflicts is discarded and treated as not having an origin. 196 - pub fn add_records( 197 - &mut self, 198 - stream: BoxStream<BackendResult<CopyRecord>>, 199 - ) -> BackendResult<()> { 200 - for record in block_on_stream(stream) { 201 - let r = record?; 202 - let value = self 203 - .targets 204 - .entry(r.target.clone()) 205 - .or_insert(self.records.len()); 206 - 207 - if *value != self.records.len() { 208 - // TODO: handle conflicts instead of ignoring both sides. 209 - *value = usize::MAX; 210 - } 211 - self.records.push(r); 212 - } 213 - Ok(()) 214 - } 215 - 216 - /// Gets any copy record associated with a target path. 217 - pub fn for_target(&self, target: &RepoPath) -> Option<&CopyRecord> { 218 - self.targets.get(target).and_then(|&i| self.records.get(i)) 219 - } 220 - 221 - /// Gets all copy records. 222 - pub fn iter(&self) -> impl Iterator<Item = &CopyRecord> + '_ { 223 - self.records.iter() 224 - } 225 181 } 226 182 227 183 /// Error that may occur during backend initialization.
+66
lib/src/copies.rs
··· 1 + // Copyright 2024 The Jujutsu Authors 2 + // 3 + // Licensed under the Apache License, Version 2.0 (the "License"); 4 + // you may not use this file except in compliance with the License. 5 + // You may obtain a copy of the License at 6 + // 7 + // https://www.apache.org/licenses/LICENSE-2.0 8 + // 9 + // Unless required by applicable law or agreed to in writing, software 10 + // distributed under the License is distributed on an "AS IS" BASIS, 11 + // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 + // See the License for the specific language governing permissions and 13 + // limitations under the License. 14 + 15 + //! Code for working with copies and renames. 16 + 17 + use std::collections::HashMap; 18 + 19 + use futures::executor::block_on_stream; 20 + use futures::stream::BoxStream; 21 + 22 + use crate::backend::{BackendResult, CopyRecord}; 23 + use crate::repo_path::{RepoPath, RepoPathBuf}; 24 + 25 + /// A collection of CopyRecords. 26 + #[derive(Default, Debug)] 27 + pub struct CopyRecords { 28 + records: Vec<CopyRecord>, 29 + // Maps from `target` to the index of the target in `records`. Conflicts 30 + // are excluded by keeping an out of range value. 31 + targets: HashMap<RepoPathBuf, usize>, 32 + } 33 + 34 + impl CopyRecords { 35 + /// Adds information about a stream of CopyRecords to `self`. A target with 36 + /// multiple conflicts is discarded and treated as not having an origin. 37 + pub fn add_records( 38 + &mut self, 39 + stream: BoxStream<BackendResult<CopyRecord>>, 40 + ) -> BackendResult<()> { 41 + for record in block_on_stream(stream) { 42 + let r = record?; 43 + let value = self 44 + .targets 45 + .entry(r.target.clone()) 46 + .or_insert(self.records.len()); 47 + 48 + if *value != self.records.len() { 49 + // TODO: handle conflicts instead of ignoring both sides. 50 + *value = usize::MAX; 51 + } 52 + self.records.push(r); 53 + } 54 + Ok(()) 55 + } 56 + 57 + /// Gets any copy record associated with a target path. 58 + pub fn for_target(&self, target: &RepoPath) -> Option<&CopyRecord> { 59 + self.targets.get(target).and_then(|&i| self.records.get(i)) 60 + } 61 + 62 + /// Gets all copy records. 63 + pub fn iter(&self) -> impl Iterator<Item = &CopyRecord> + '_ { 64 + self.records.iter() 65 + } 66 + }
+1
lib/src/lib.rs
··· 32 32 pub mod commit; 33 33 pub mod commit_builder; 34 34 pub mod conflicts; 35 + pub mod copies; 35 36 pub mod dag_walk; 36 37 pub mod default_index; 37 38 pub mod default_submodule_store;
+2 -1
lib/src/merged_tree.rs
··· 30 30 use itertools::{EitherOrBoth, Itertools}; 31 31 32 32 use crate::backend; 33 - use crate::backend::{BackendResult, CopyRecord, CopyRecords, MergedTreeId, TreeId, TreeValue}; 33 + use crate::backend::{BackendResult, CopyRecord, MergedTreeId, TreeId, TreeValue}; 34 + use crate::copies::CopyRecords; 34 35 use crate::matchers::{EverythingMatcher, Matcher}; 35 36 use crate::merge::{Merge, MergeBuilder, MergedTreeVal, MergedTreeValue}; 36 37 use crate::repo_path::{RepoPath, RepoPathBuf, RepoPathComponent};
+2 -1
lib/tests/test_merged_tree.rs
··· 14 14 15 15 use futures::StreamExt; 16 16 use itertools::Itertools; 17 - use jj_lib::backend::{CommitId, CopyRecord, CopyRecords, FileId, MergedTreeId, TreeValue}; 17 + use jj_lib::backend::{CommitId, CopyRecord, FileId, MergedTreeId, TreeValue}; 18 + use jj_lib::copies::CopyRecords; 18 19 use jj_lib::files::MergeResult; 19 20 use jj_lib::matchers::{EverythingMatcher, FilesMatcher, Matcher, PrefixMatcher}; 20 21 use jj_lib::merge::{Merge, MergeBuilder, MergedTreeValue};