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<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};
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<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};