summaryrefslogtreecommitdiffstats
path: root/vendor/gix/src/diff.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
commit9918693037dce8aa4bb6f08741b6812923486c18 (patch)
tree21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /vendor/gix/src/diff.rs
parentReleasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff)
downloadrustc-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.rs127
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};