pub use gix_diff::*; /// pub mod rename { /// Determine how to do rename tracking. #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum Tracking { /// Do not track renames at all, the fastest option. Disabled, /// Track renames. Renames, /// Track renames and copies. /// /// This is the most expensive option. 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, 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 { 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};