Skip to main content

repo/
repository_diff.rs

1// SPDX-License-Identifier: Apache-2.0
2//! Tree diffing utilities.
3
4use std::ops::ControlFlow;
5
6use objects::{
7    error::HeddleError,
8    object::{ContentHash, FileChange, FileChangeSet, diff_trees, diff_trees_visit},
9};
10
11use super::{Repository, Result};
12
13impl Repository {
14    /// Get the difference between two trees.
15    pub fn diff_trees(&self, from: &ContentHash, to: &ContentHash) -> Result<FileChangeSet> {
16        diff_trees(&self.store, from, to)
17            .map_err(|error| HeddleError::InvalidObject(format!("tree diff failed: {error}")))
18    }
19
20    /// Diff two trees with internal iteration, invoking `visitor` for each
21    /// change in traversal order.
22    ///
23    /// Unlike [`Repository::diff_trees`], this never materializes the full
24    /// change list: the visitor returns a [`ControlFlow`] so early-exit
25    /// consumers can stop on the first relevant change without allocating a
26    /// [`FileChangeSet`]. Returns the carried `B` on early exit, or
27    /// `ControlFlow::Continue(())` when the full diff is walked.
28    pub fn diff_trees_visit<V, B>(
29        &self,
30        from: &ContentHash,
31        to: &ContentHash,
32        visitor: V,
33    ) -> Result<ControlFlow<B>>
34    where
35        V: FnMut(FileChange) -> ControlFlow<B>,
36    {
37        diff_trees_visit(&self.store, from, to, visitor)
38            .map_err(|error| HeddleError::InvalidObject(format!("tree diff failed: {error}")))
39    }
40}