diff options
Diffstat (limited to 'apps/servers/octopus/supergit/src/commit.rs')
-rw-r--r-- | apps/servers/octopus/supergit/src/commit.rs | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/apps/servers/octopus/supergit/src/commit.rs b/apps/servers/octopus/supergit/src/commit.rs index bc7383d1ed6d..99c4dbba6fce 100644 --- a/apps/servers/octopus/supergit/src/commit.rs +++ b/apps/servers/octopus/supergit/src/commit.rs @@ -1,4 +1,4 @@ -use crate::{FileTree, HashId}; +use crate::{Diff, FileTree, HashId}; use git2::Repository; use std::sync::Arc; @@ -71,6 +71,44 @@ impl Commit { FileTree::new(&self.repo, self.id.clone()) } + /// Get the list of paths in the repository touched by this commit + /// + /// Using this function directly is often not what you want. + /// Instead, use the `get_history(...)` function on `FileTree`, + /// which uses this function. + pub fn get_paths(&self) -> Vec<String> { + self.get_diff() + .map(|d| Diff::from(d)) + .map_or(vec![], |d| d.get_paths()) + } + + /// Utility function to get a merged diff from all parents + fn get_diff(&self) -> Option<git2::Diff> { + // Get all diffs with parents + let stree = self.find().tree().unwrap(); + let mut vec = self + .parents() + .into_iter() + .filter_map(|p| { + self.repo + .diff_tree_to_tree(Some(&stree), Some(p.find().tree().as_ref().unwrap()), None) + .ok() + }) + .collect::<Vec<_>>(); + + // If there are no parents + if vec.len() == 0 { + vec = vec![self.repo.diff_tree_to_tree(Some(&stree), None, None).ok()?]; + } + + // Take the first and merge onto + let first = vec.remove(0); + Some(vec.iter().fold(first, |mut acc, diff| { + acc.merge(diff).unwrap(); + acc + })) + } + fn find(&self) -> git2::Commit { self.repo.find_commit(self.id.to_oid()).unwrap() } |