1use crate::diff::targets::collect_files_for_target;
3use crate::diff::{diff_index_to_tree, diff_index_to_worktree, diff_trees, DiffEntry, DiffOptions};
4use crate::diff::{DiffTarget, FileDiff};
5use crate::error::Result;
6use crate::index::Index;
7use crate::objects::ObjectId;
8use crate::repo::Repository;
9
10#[derive(Debug, Copy, Clone)]
12pub struct Diff<'repo> {
13 repo: &'repo Repository,
14}
15
16impl<'repo> Diff<'repo> {
17 #[inline]
19 #[must_use]
20 pub fn new(repo: &'repo Repository) -> Self {
21 Self { repo }
22 }
23
24 #[inline]
26 #[must_use]
27 pub fn repository(&self) -> &'repo Repository {
28 self.repo
29 }
30
31 #[inline]
41 pub fn tree_to_tree(
42 &self,
43 old_tree: Option<&ObjectId>,
44 new_tree: Option<&ObjectId>,
45 ) -> Result<Vec<DiffEntry>> {
46 diff_trees(self.repo.odb(), old_tree, new_tree, "")
47 }
48
49 #[inline]
55 pub fn index_to_tree(
56 &self,
57 index: &Index,
58 tree_oid: Option<&ObjectId>,
59 ignore_submodules: bool,
60 ) -> Result<Vec<DiffEntry>> {
61 diff_index_to_tree(self.repo.odb(), index, tree_oid, ignore_submodules)
62 }
63
64 #[inline]
70 pub fn worktree_to_index(
71 &self,
72 index: &mut Index,
73 ignore_submodule_untracked: bool,
74 simplify_gitlinks: bool,
75 ) -> Result<Vec<DiffEntry>> {
76 let work_tree = self
77 .repo
78 .work_tree()
79 .ok_or(crate::error::Error::RequiresWorkTree)?;
80 diff_index_to_worktree(
81 self.repo.odb(),
82 index,
83 work_tree,
84 ignore_submodule_untracked,
85 simplify_gitlinks,
86 )
87 }
88
89 pub fn files(
95 &self,
96 target: &DiffTarget,
97 pathspecs: &[String],
98 opts: &DiffOptions,
99 ) -> Result<Vec<FileDiff>> {
100 collect_files_for_target(self.repo, target, pathspecs, opts.clone())
101 }
102}