#![allow(unused)]
use ::std::collections::HashSet;
use ::std::path::Path;
use ::std::path::PathBuf;
use ::std::time::Instant;
use ::git2::Repository;
use ::log::debug;
use ::log::warn;
pub fn git_head_ref(dir: &Path) -> Result<String, String> {
let repo = Repository::open(dir).map_err(|err| {
format!(
"failed to read git repository at {}, err {}",
dir.to_string_lossy(),
err
)
})?;
let head = repo.head().unwrap().peel_to_commit().unwrap();
Ok(head.id().to_string())
}
pub fn git_master_base() {
}
pub fn git_affected_files_head(dir: &Path) -> Result<(HashSet<PathBuf>, HashSet<PathBuf>), String> {
let t0 = Instant::now();
let repo = Repository::open(dir).map_err(|err| {
format!(
"failed to read git repository at {}, err {}",
dir.to_string_lossy(),
err
)
})?;
let head_tree = repo
.head()
.unwrap()
.peel_to_commit()
.unwrap()
.tree()
.unwrap();
let head_parent_tree = repo
.head()
.unwrap()
.peel_to_commit()
.unwrap()
.parent(0)
.unwrap()
.tree()
.unwrap();
let diff = repo
.diff_tree_to_tree(Some(&head_tree), Some(&head_parent_tree), None)
.unwrap();
let mut changed_files = HashSet::new();
for delta in diff.deltas() {
if let Some(pth) = delta.new_file().path() {
changed_files.insert(pth.to_path_buf());
}
}
let mut deleted_files = HashSet::new();
for delta in diff.deltas() {
let q = delta.new_file(); if let Some(pth) = delta.old_file().path() {
if !changed_files.contains(pth) {
deleted_files.insert(pth.to_path_buf());
}
}
}
let duration = t0.elapsed().as_millis();
if duration > 200 {
warn!("git_affected_files_head slow, took {} ms", duration);
} else {
debug!("git_affected_files_head took {} ms", duration);
}
Ok((changed_files, deleted_files))
}
pub fn git_affected_files_uncommitted() {
}
pub fn git_affected_files_branch() {
}
#[cfg(test)]
mod tests {
use std::path::PathBuf;
use super::*;
#[test]
fn test_git_repo() {
git_affected_files_head(&PathBuf::from(".")).unwrap();
}
}