Skip to content

Commit 7fd9b0e

Browse files
committed
Provisions for tracking the location of a change. (#470)
1 parent a9056fd commit 7fd9b0e

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed

git-repository/src/object/tree/mod.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ impl<'repo> Tree<'repo> {
6565
#[allow(missing_docs)]
6666
///
6767
pub mod diff {
68-
use crate::bstr::BStr;
68+
use crate::bstr::{BStr, BString};
6969
use crate::ext::ObjectIdExt;
7070
use crate::{Id, Repository, Tree};
7171
use git_object::TreeRefIter;
@@ -83,6 +83,17 @@ pub mod diff {
8383

8484
/// Represents any possible change in order to turn one tree into another.
8585
#[derive(Debug, Clone, Copy)]
86+
pub struct Change<'a, 'repo, 'other_repo> {
87+
/// The location of the file or directory described by `event`, if tracking was enabled.
88+
///
89+
/// Otherwise this value is always an empty path.
90+
pub location: &'a BStr,
91+
/// The diff event itself to provide information about what would need to change.
92+
pub event: Event<'repo, 'other_repo>,
93+
}
94+
95+
/// An event emitted when finding differences between two trees.
96+
#[derive(Debug, Clone, Copy)]
8697
pub enum Event<'repo, 'other_repo> {
8798
/// An entry was added, like the addition of a file or directory.
8899
Addition {
@@ -135,7 +146,7 @@ pub mod diff {
135146
pub fn for_each_to_obtain_tree<'other_repo, E>(
136147
&mut self,
137148
other: &Tree<'other_repo>,
138-
for_each: impl FnMut(Event<'repo, 'other_repo>) -> Result<git_diff::tree::visit::Action, E>,
149+
for_each: impl FnMut(Change<'_, 'repo, 'other_repo>) -> Result<git_diff::tree::visit::Action, E>,
139150
) -> Result<(), Error>
140151
where
141152
E: std::error::Error + Sync + Send + 'static,
@@ -144,6 +155,7 @@ pub mod diff {
144155
let mut delegate = Delegate {
145156
repo: self.lhs.repo,
146157
other_repo: other.repo,
158+
location: BString::default(),
147159
visit: for_each,
148160
err: None,
149161
};
@@ -163,13 +175,15 @@ pub mod diff {
163175
struct Delegate<'repo, 'other_repo, VisitFn, E> {
164176
repo: &'repo Repository,
165177
other_repo: &'other_repo Repository,
178+
location: BString,
166179
visit: VisitFn,
167180
err: Option<E>,
168181
}
169182

170183
impl<'repo, 'other_repo, VisitFn, E> git_diff::tree::Visit for Delegate<'repo, 'other_repo, VisitFn, E>
171184
where
172-
VisitFn: FnMut(Event<'repo, 'other_repo>) -> Result<git_diff::tree::visit::Action, E>,
185+
VisitFn:
186+
for<'delegate> FnMut(Change<'delegate, 'repo, 'other_repo>) -> Result<git_diff::tree::visit::Action, E>,
173187
E: std::error::Error + Sync + Send + 'static,
174188
{
175189
fn pop_front_tracked_path_and_set_current(&mut self) {}
@@ -205,7 +219,10 @@ pub mod diff {
205219
id: oid.attach(self.other_repo),
206220
},
207221
};
208-
match (self.visit)(event) {
222+
match (self.visit)(Change {
223+
event,
224+
location: self.location.as_ref(),
225+
}) {
209226
Ok(action) => action,
210227
Err(err) => {
211228
self.err = Some(err);

git-repository/tests/object/tree.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ mod diff {
1212
let from = tree_named(&repo, "g");
1313
let to = tree_named(&repo, "h");
1414
from.changes()
15-
.for_each_to_obtain_tree(&to, |event| -> Result<_, Infallible> {
16-
match event {
15+
.for_each_to_obtain_tree(&to, |change| -> Result<_, Infallible> {
16+
assert_eq!(change.location, "", "without configuration the location field is empty");
17+
match change.event {
1718
Event::Modification {
1819
previous_entry_mode,
1920
previous_id,

0 commit comments

Comments
 (0)