use std::collections::BTreeSet;
use anyhow::{Context, Result};
use gix::bstr::{BString, ByteSlice};
pub(crate) fn changed_paths_committed(
repo: &gix::Repository,
base: gix::ObjectId,
head: gix::ObjectId,
) -> Result<BTreeSet<String>> {
let base_tree = repo
.find_commit(base)
.context("find base commit")?
.tree()
.context("read base commit tree")?;
let head_tree = repo
.find_commit(head)
.context("find head commit")?
.tree()
.context("read head commit tree")?;
let changes = repo
.diff_tree_to_tree(Some(&base_tree), Some(&head_tree), None)
.context("diff base..HEAD trees")?;
let mut paths = BTreeSet::new();
for change in &changes {
paths.insert(
change
.location()
.to_str()
.context("changed path is not valid UTF-8")?
.to_owned(),
);
paths.insert(
change
.source_location()
.to_str()
.context("changed source path is not valid UTF-8")?
.to_owned(),
);
}
Ok(paths)
}
pub(crate) fn changed_paths_worktree(repo: &gix::Repository) -> Result<BTreeSet<String>> {
let iter = repo
.status(gix::progress::Discard)
.context("open worktree status")?
.untracked_files(gix::status::UntrackedFiles::Files)
.tree_index_track_renames(gix::status::tree_index::TrackRenames::Disabled)
.into_iter(Vec::<BString>::new())
.context("create worktree status iterator")?;
let mut paths = BTreeSet::new();
for item in iter {
let item = item.context("read worktree status item")?;
paths.insert(
item.location()
.to_str()
.context("worktree-changed path is not valid UTF-8")?
.to_owned(),
);
}
Ok(paths)
}