diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
commit | 9918693037dce8aa4bb6f08741b6812923486c18 (patch) | |
tree | 21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /vendor/gix/src/diff.rs | |
parent | Releasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff) | |
download | rustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip |
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix/src/diff.rs')
-rw-r--r-- | vendor/gix/src/diff.rs | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/vendor/gix/src/diff.rs b/vendor/gix/src/diff.rs index b10819293..af3c98704 100644 --- a/vendor/gix/src/diff.rs +++ b/vendor/gix/src/diff.rs @@ -15,3 +15,130 @@ pub mod rename { RenamesAndCopies, } } + +/// +#[cfg(feature = "blob-diff")] +mod utils { + use gix_diff::{rewrites::Copies, Rewrites}; + + use crate::{ + config::{cache::util::ApplyLeniency, tree::Diff}, + diff::rename::Tracking, + Repository, + }; + + /// + pub mod new_rewrites { + /// The error returned by [`new_rewrites()`](super::new_rewrites()). + #[derive(Debug, thiserror::Error)] + #[allow(missing_docs)] + pub enum Error { + #[error(transparent)] + ConfigDiffRenames(#[from] crate::config::key::GenericError), + #[error(transparent)] + ConfigDiffRenameLimit(#[from] crate::config::unsigned_integer::Error), + } + } + + /// + pub mod resource_cache { + /// The error returned by [`resource_cache()`](super::resource_cache()). + #[derive(Debug, thiserror::Error)] + #[allow(missing_docs)] + pub enum Error { + #[error(transparent)] + DiffAlgorithm(#[from] crate::config::diff::algorithm::Error), + #[error(transparent)] + WorktreeFilterOptions(#[from] crate::filter::pipeline::options::Error), + #[error(transparent)] + DiffDrivers(#[from] crate::config::diff::drivers::Error), + #[error(transparent)] + DiffPipelineOptions(#[from] crate::config::diff::pipeline_options::Error), + #[error(transparent)] + CommandContext(#[from] crate::config::command_context::Error), + #[error(transparent)] + AttributeStack(#[from] crate::config::attribute_stack::Error), + } + } + + /// Create an instance by reading all relevant information from the `config`uration, while being `lenient` or not. + /// Returns `Ok(None)` if nothing is configured. + /// + /// Note that missing values will be defaulted similar to what git does. + #[allow(clippy::result_large_err)] + pub fn new_rewrites( + config: &gix_config::File<'static>, + lenient: bool, + ) -> Result<Option<Rewrites>, new_rewrites::Error> { + let key = "diff.renames"; + let copies = match config + .boolean_by_key(key) + .map(|value| Diff::RENAMES.try_into_renames(value)) + .transpose() + .with_leniency(lenient)? + { + Some(renames) => match renames { + Tracking::Disabled => return Ok(None), + Tracking::Renames => None, + Tracking::RenamesAndCopies => Some(Copies::default()), + }, + None => return Ok(None), + }; + + let default = Rewrites::default(); + Ok(Rewrites { + copies, + limit: config + .integer_by_key("diff.renameLimit") + .map(|value| Diff::RENAME_LIMIT.try_into_usize(value)) + .transpose() + .with_leniency(lenient)? + .unwrap_or(default.limit), + ..default + } + .into()) + } + + /// Return a low-level utility to efficiently prepare a the blob-level diff operation between two resources, + /// and cache these diffable versions so that matrix-like MxN diffs are efficient. + /// + /// `repo` is used to obtain the needed configuration values, and `index` is used to potentially read `.gitattributes` + /// files from which may affect the diff operation. + /// `mode` determines how the diffable files will look like, and also how fast, in average, these conversions are. + /// `attribute_source` controls where `.gitattributes` will be read from, and it's typically adjusted based on the + /// `roots` - if there are no worktree roots, `.gitattributes` are also not usually read from worktrees. + /// `roots` provide information about where to get diffable data from, so source and destination can either be sourced from + /// a worktree, or from the object database, or both. + pub fn resource_cache( + repo: &Repository, + index: &gix_index::State, + mode: gix_diff::blob::pipeline::Mode, + attribute_source: gix_worktree::stack::state::attributes::Source, + roots: gix_diff::blob::pipeline::WorktreeRoots, + ) -> Result<gix_diff::blob::Platform, resource_cache::Error> { + let diff_algo = repo.config.diff_algorithm()?; + let diff_cache = gix_diff::blob::Platform::new( + gix_diff::blob::platform::Options { + algorithm: Some(diff_algo), + skip_internal_diff_if_external_is_configured: false, + }, + gix_diff::blob::Pipeline::new( + roots, + gix_filter::Pipeline::new(repo.command_context()?, crate::filter::Pipeline::options(repo)?), + repo.config.diff_drivers()?, + repo.config.diff_pipeline_options()?, + ), + mode, + repo.attributes_only( + // TODO(perf): this could benefit from not having to build an intermediate index, + // and traverse the a tree directly. + index, + attribute_source, + )? + .inner, + ); + Ok(diff_cache) + } +} +#[cfg(feature = "blob-diff")] +pub use utils::{new_rewrites, resource_cache}; |