1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
//! Repository-scoped tree and index diffs via [`Diff`].
use crate::diff::targets::collect_files_for_target;
use crate::diff::{diff_index_to_tree, diff_index_to_worktree, diff_trees, DiffEntry, DiffOptions};
use crate::diff::{DiffTarget, FileDiff};
use crate::error::Result;
use crate::index::Index;
use crate::objects::ObjectId;
use crate::repo::Repository;
/// Compare trees, the index, and the working tree for one repository.
#[derive(Debug, Copy, Clone)]
pub struct Diff<'repo> {
repo: &'repo Repository,
}
impl<'repo> Diff<'repo> {
/// Bind diff helpers to `repo`.
#[inline]
#[must_use]
pub fn new(repo: &'repo Repository) -> Self {
Self { repo }
}
/// Underlying repository.
#[inline]
#[must_use]
pub fn repository(&self) -> &'repo Repository {
self.repo
}
/// Diff two tree oids (either side may be `None` for an empty tree).
///
/// # Errors
///
/// Propagates ODB read and tree walk errors.
///
/// # Examples
///
/// See the library guide on [diffing](https://grit-scm.com/docs/library/diff/).
#[inline]
pub fn tree_to_tree(
&self,
old_tree: Option<&ObjectId>,
new_tree: Option<&ObjectId>,
) -> Result<Vec<DiffEntry>> {
diff_trees(self.repo.odb(), old_tree, new_tree, "")
}
/// Diff the index against a tree (typically `HEAD`'s tree).
///
/// # Errors
///
/// Propagates ODB and index diff errors.
#[inline]
pub fn index_to_tree(
&self,
index: &Index,
tree_oid: Option<&ObjectId>,
ignore_submodules: bool,
) -> Result<Vec<DiffEntry>> {
diff_index_to_tree(self.repo.odb(), index, tree_oid, ignore_submodules)
}
/// Diff the working tree against the index.
///
/// # Errors
///
/// Returns an error when the repository has no work tree or diff I/O fails.
#[inline]
pub fn worktree_to_index(
&self,
index: &mut Index,
ignore_submodule_untracked: bool,
simplify_gitlinks: bool,
) -> Result<Vec<DiffEntry>> {
let work_tree = self
.repo
.work_tree()
.ok_or(crate::error::Error::RequiresWorkTree)?;
diff_index_to_worktree(
self.repo.odb(),
index,
work_tree,
ignore_submodule_untracked,
simplify_gitlinks,
)
}
/// Structured per-file diffs for `target`, honoring `pathspecs` and line-diff `opts`.
///
/// # Errors
///
/// Propagates index, ODB, and worktree diff failures.
pub fn files(
&self,
target: &DiffTarget,
pathspecs: &[String],
opts: &DiffOptions,
) -> Result<Vec<FileDiff>> {
collect_files_for_target(self.repo, target, pathspecs, opts.clone())
}
}