blob: 2f26e1b114c6a7dcf8ae75ee663e4d7ef9af027a [file] [log] [blame] [edit]
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};