134 lines
4.4 KiB
Rust
134 lines
4.4 KiB
Rust
//! Tree query operations.
|
|
|
|
use std::path::Path;
|
|
|
|
use crate::commit::types::CommitOid;
|
|
use crate::tree::types::{TreeEntry, TreeInfo};
|
|
use crate::{GitDomain, GitError, GitResult};
|
|
|
|
impl GitDomain {
|
|
pub fn tree_get(&self, oid: &CommitOid) -> GitResult<TreeInfo> {
|
|
let oid = oid
|
|
.to_oid()
|
|
.map_err(|_| GitError::InvalidOid(oid.to_string()))?;
|
|
let tree = self
|
|
.repo()
|
|
.find_tree(oid)
|
|
.map_err(|_| GitError::ObjectNotFound(oid.to_string()))?;
|
|
Ok(TreeInfo::from_git2(&tree))
|
|
}
|
|
|
|
pub fn tree_exists(&self, oid: &CommitOid) -> bool {
|
|
oid.to_oid()
|
|
.ok()
|
|
.and_then(|oid| self.repo.find_tree(oid).ok())
|
|
.is_some()
|
|
}
|
|
|
|
pub fn tree_entry(&self, oid: &CommitOid, index: usize) -> GitResult<TreeEntry> {
|
|
let oid = oid
|
|
.to_oid()
|
|
.map_err(|_| GitError::InvalidOid(oid.to_string()))?;
|
|
let tree = self
|
|
.repo()
|
|
.find_tree(oid)
|
|
.map_err(|_| GitError::ObjectNotFound(oid.to_string()))?;
|
|
let entry = tree
|
|
.get(index)
|
|
.ok_or_else(|| GitError::Internal("tree entry not found".to_string()))?;
|
|
Ok(TreeEntry::from_git2(entry, self.repo()))
|
|
}
|
|
|
|
pub fn tree_list(&self, oid: &CommitOid) -> GitResult<Vec<TreeEntry>> {
|
|
let oid = oid
|
|
.to_oid()
|
|
.map_err(|_| GitError::InvalidOid(oid.to_string()))?;
|
|
let tree = self
|
|
.repo()
|
|
.find_tree(oid)
|
|
.map_err(|_| GitError::ObjectNotFound(oid.to_string()))?;
|
|
let repo = self.repo();
|
|
let entries: Vec<TreeEntry> = tree
|
|
.iter()
|
|
.map(|entry| TreeEntry::from_git2(entry, repo))
|
|
.collect();
|
|
Ok(entries)
|
|
}
|
|
|
|
pub fn tree_entry_count(&self, oid: &CommitOid) -> GitResult<usize> {
|
|
let info = self.tree_get(oid)?;
|
|
Ok(info.entry_count)
|
|
}
|
|
|
|
pub fn tree_entry_by_path(&self, tree_oid: &CommitOid, path: &str) -> GitResult<TreeEntry> {
|
|
let oid = tree_oid
|
|
.to_oid()
|
|
.map_err(|_| GitError::InvalidOid(tree_oid.to_string()))?;
|
|
let tree = self
|
|
.repo()
|
|
.find_tree(oid)
|
|
.map_err(|_| GitError::ObjectNotFound(tree_oid.to_string()))?;
|
|
let entry = tree
|
|
.get_path(Path::new(path))
|
|
.map_err(|e| GitError::Internal(format!("path '{}': {}", path, e)))?;
|
|
Ok(TreeEntry::from_git2(entry, self.repo()))
|
|
}
|
|
|
|
pub fn tree_entry_by_path_from_commit(
|
|
&self,
|
|
commit_oid: &CommitOid,
|
|
path: &str,
|
|
) -> GitResult<TreeEntry> {
|
|
let oid = commit_oid
|
|
.to_oid()
|
|
.map_err(|_| GitError::InvalidOid(commit_oid.to_string()))?;
|
|
let commit = self
|
|
.repo()
|
|
.find_commit(oid)
|
|
.map_err(|_| GitError::ObjectNotFound(commit_oid.to_string()))?;
|
|
let tree = self
|
|
.repo()
|
|
.find_tree(commit.tree_id())
|
|
.map_err(|e| GitError::Internal(e.to_string()))?;
|
|
let entry = tree
|
|
.get_path(Path::new(path))
|
|
.map_err(|e| GitError::Internal(format!("path '{}': {}", path, e)))?;
|
|
Ok(TreeEntry::from_git2(entry, self.repo()))
|
|
}
|
|
|
|
pub fn tree_is_empty(&self, oid: &CommitOid) -> GitResult<bool> {
|
|
let info = self.tree_get(oid)?;
|
|
Ok(info.is_empty)
|
|
}
|
|
|
|
pub fn tree_diffstats(
|
|
&self,
|
|
old_tree: &CommitOid,
|
|
new_tree: &CommitOid,
|
|
) -> GitResult<crate::diff::types::DiffStats> {
|
|
use crate::diff::types::DiffStats;
|
|
let old_oid = old_tree
|
|
.to_oid()
|
|
.map_err(|_| GitError::InvalidOid(old_tree.to_string()))?;
|
|
let new_oid = new_tree
|
|
.to_oid()
|
|
.map_err(|_| GitError::InvalidOid(new_tree.to_string()))?;
|
|
let old_tree = self
|
|
.repo()
|
|
.find_tree(old_oid)
|
|
.map_err(|e| GitError::Internal(e.to_string()))?;
|
|
let new_tree = self
|
|
.repo()
|
|
.find_tree(new_oid)
|
|
.map_err(|e| GitError::Internal(e.to_string()))?;
|
|
let diff = self
|
|
.repo()
|
|
.diff_tree_to_tree(Some(&old_tree), Some(&new_tree), None)
|
|
.map_err(|e| GitError::Internal(e.to_string()))?;
|
|
let stats = diff
|
|
.stats()
|
|
.map_err(|e| GitError::Internal(e.to_string()))?;
|
|
Ok(DiffStats::from_git2(&stats))
|
|
}
|
|
}
|