| pub use gix_diff::*; |
| |
| /// |
| #[allow(clippy::empty_docs)] |
| 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, |
| }; |
| |
| /// |
| #[allow(clippy::empty_docs)] |
| 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), |
| } |
| } |
| |
| /// |
| #[allow(clippy::empty_docs)] |
| 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), |
| } |
| } |
| |
| /// 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(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("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 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. |
| /// `mode` determines how the diffable files will look like, and also how fast, in average, these conversions are. |
| /// `attr_stack` is for accessing `.gitattributes` for knowing how to apply filters. Know that 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, |
| mode: gix_diff::blob::pipeline::Mode, |
| attr_stack: gix_worktree::Stack, |
| 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, |
| attr_stack, |
| ); |
| Ok(diff_cache) |
| } |
| } |
| #[cfg(feature = "blob-diff")] |
| pub use utils::{new_rewrites, resource_cache}; |