Skip to main content

aicommit_rs/
diff.rs

1use git2::{DiffFormat, DiffLineType, DiffOptions, Repository};
2
3pub fn get_diff() -> Result<String, git2::Error> {
4    let repo = Repository::open_from_env()?;
5
6    let head = repo.head()?;
7    let head_oid = head
8        .target()
9        .ok_or_else(|| git2::Error::from_str("Head has no target"))?;
10    let commit = repo.find_commit(head_oid)?;
11    let tree = commit.tree()?;
12    let mut diff_options = DiffOptions::new();
13    diff_options.ignore_whitespace(true);
14    diff_options.ignore_whitespace_change(true);
15    diff_options.ignore_whitespace_eol(true);
16
17    let diff = repo.diff_tree_to_index(Some(&tree), None, Some(&mut diff_options))?;
18    let mut buf = Vec::new();
19
20    diff.print(DiffFormat::Patch, |_, _, line| {
21        let origin = line.origin_value();
22        match origin {
23            DiffLineType::Addition => buf.extend_from_slice(b"+"),
24            DiffLineType::Deletion => buf.extend_from_slice(b"-"),
25            DiffLineType::HunkHeader => return true,
26            _ => {}
27        }
28
29        buf.extend(line.content());
30        true
31    })?;
32
33    let contents = String::from_utf8_lossy(&buf);
34
35    Ok(contents.to_string())
36}